android.os.NetworkOnMainThreadException的解决方案

简介:

06-24 18:04:36.857: E/AndroidRuntime(22251): FATAL EXCEPTION: main 
06-24 18:04:36.857: E/AndroidRuntime(22251): android.os.NetworkOnMainThreadException 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1128) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:175) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at libcore.io.IoBridge.sendto(IoBridge.java:473) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at java.net.DatagramSocket.send(DatagramSocket.java:284) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at com.example.com.ihome.bang.util.UdpHelper.send(UdpHelper.java:93) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at com.example.com.ihome.bang.adapter.ListViewAdapter$2.onClick(ListViewAdapter.java:210) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at android.view.View.performClick(View.java:4171) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at android.view.View$PerformClick.run(View.java:17070) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at android.os.Handler.handleCallback(Handler.java:615) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at android.os.Handler.dispatchMessage(Handler.java:92) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at android.os.Looper.loop(Looper.java:137) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at android.app.ActivityThread.main(ActivityThread.java:4797) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at java.lang.reflect.Method.invokeNative(Native Method) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at java.lang.reflect.Method.invoke(Method.java:511) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:804) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:571) 
06-24 18:04:36.857: E/AndroidRuntime(22251):     at dalvik.system.NativeStart.main(Native Method) 

原来在Android2.2上面运行的好好的一个网络应用程序,主要是发送UDP信息跟服务器进行通信的程序,安装到4.0上面就爆出了这个问题。

查了一下官方文档。文档上说:NetworkOnMainThreadException是因为应用程序在主线程上尝试网络操作。另外,这个异常在Honeycomb SDK或更高版本的SDK上才会抛出。低版本的SDK允许应用程序在主线程或loop线程执行网络操作,但不鼓励这样做。

 

方法1:我们可以把android:targetSdkVersion=”Version Num”这句话从AndroidManifest.xml去掉,问题就解决了,但不是治本的解决方案。(如下图所示)

image

方法2:在进行网络通信的部分,单独执行异步任务。

现在让我们思考一下,让原有代码修改最小的一种方法。如果程序对实时性的要求不是很高的话,我们可以创建一个异步任务类,这个异步任务类里面含有一个网络消息队列(Queue)。这个类通过对外提供一个消息入队列的接口,在异步类内部进行消息的发送。当要发送消息的时候(也就是原来进行网络操作的地方,我们假设是发送消息),我们将网络消息加入Queue,在异步任务里面用一个while循环查询Queue,当Queue中有数据的时候就进行发送,没有的话,sleep一段时间。具体的代码如下所示。

复制代码
package com.example.com.ihome.bang.tool;

import java.util.LinkedList;
import java.util.Queue;

import com.example.com.ihome.bang.util.UdpHelper;

import android.os.AsyncTask;
import android.util.Log;

public class SendThread extends AsyncTask{
    private static Queue<String> queue = new LinkedList<String>();  
    public static Boolean SendOrder(String Order){
        queue.offer(Order);
        return true;
    }
    
    
    @Override
    protected Object doInBackground(Object... params) {
        String str;
        while (true) {
            //Log.d(SendThread.class.getName(), "进入doInBackground");
            if ((str = queue.poll()) != null) {

                //Log.d(SendThread.class.getName(), "doInBackground_发送"+str);
                UdpHelper.sendReally(str);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    
                    e.printStackTrace();
                    
                }
            }
            

        }
    }

}
复制代码

方法3:在进行网络通信的部分,用后台线程来执行操作

自己创建线程的话,比创建异步任务更麻烦一点。记住,当你要用线程来处理网络通信部分的时候,记得将线程设置为后台运行,也就是通过设置线程的属性为”background”。我们可以通过传递参数 THREAD_PRIORITY_BACKGROUNDProcess.setThreadPriority() 。.如果我们不通过这种方法将线程的优先级设为较低级别的话,那么这个线程就会拥有跟UI线程一样的优先级,我们的应用程序就可能被这个线程拖慢。

本文转自陈哈哈博客园博客,原文链接http://www.cnblogs.com/kissazi2/p/3153307.html如需转载请自行联系原作者

kissazi2
相关文章
|
5月前
|
XML Android开发 数据格式
android点击FrameLayout、LinearLayout等父布局没响应的原因以及解决方案
android点击FrameLayout、LinearLayout等父布局没响应的原因以及解决方案
151 2
|
5月前
|
安全 Shell Android开发
Android系统 init.rc sys/class系统节点写不进解决方案和原理分析
Android系统 init.rc sys/class系统节点写不进解决方案和原理分析
267 0
|
21天前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
58 7
|
24天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台解决方案
【9月更文挑战第27天】在移动应用开发的广阔天地中,安卓和iOS两大操作系统如同双子星座般耀眼。开发者们在这两大平台上追逐着创新的梦想,却也面临着选择的难题。如何在保持高效的同时,实现跨平台的开发?本文将带你探索跨平台开发的魅力所在,揭示其背后的技术原理,并通过实际案例展示其应用场景。无论你是安卓的忠实拥趸,还是iOS的狂热粉丝,这篇文章都将为你打开一扇通往跨平台开发新世界的大门。
|
5天前
|
Android开发
Android开发显示头部Bar的需求解决方案--Android应用实战
Android开发显示头部Bar的需求解决方案--Android应用实战
9 0
|
2月前
|
前端开发 开发工具 Android开发
探索安卓与iOS应用开发:跨平台解决方案的崛起
【8月更文挑战第27天】在移动设备日益普及的今天,安卓和iOS系统占据了市场的主导地位。开发者们面临着一个重要问题:是选择专注于单一平台,还是寻找一种能够同时覆盖两大系统的解决方案?本文将探讨跨平台开发工具的优势,分析它们如何改变了移动应用的开发格局,并分享一些实用的开发技巧。无论你是新手还是资深开发者,这篇文章都将为你提供有价值的见解和建议。
|
2月前
|
消息中间件 算法 安全
操作系统处理多进程的问题及解决方案
【8月更文挑战第23天】
133 1
|
2月前
|
Android开发
Android编译出现Warning: Mapping new ns to old ns的解决方案
Android编译出现Warning: Mapping new ns to old ns的解决方案
228 3
|
2月前
|
前端开发 JavaScript Android开发
探索Android和iOS开发中的跨平台解决方案
【8月更文挑战第1天】随着移动应用市场的不断扩张,开发者面临一个共同的挑战——如何高效地为多个平台创建和维护应用程序。本文将深入探讨跨平台开发工具,特别是Flutter和React Native,通过比较它们的优势和限制,并辅以实际代码示例,揭示这些工具如何帮助开发者在保持高性能的同时,实现代码的最大化重用。
|
2月前
|
前端开发 JavaScript Android开发
安卓与iOS开发中的跨平台解决方案
【8月更文挑战第24天】在移动应用开发领域,安卓和iOS两大平台占据了主导地位。然而,为这两个平台分别开发和维护应用会带来额外的时间和成本。本文将探讨跨平台开发的概念、优势以及流行的跨平台框架,如React Native和Flutter,并分析它们如何解决多平台开发的挑战。