android.os.NetworkOnMainThreadException
来源:互联网 发布:新疆网络监控处置中心 编辑:程序博客网 时间:2024/05/22 03:15
有个使用HttpURLConnection下载的例子, 自己测试重新写一遍的过程中发现,
buff = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
这句始终出错,urlConnection.getInputStream() 抛出异常System.err android.os.NetworkOnMainThreadException
但是把原来的例子代码导入测试又是正常的, 代码是一样的自己重写的却访问网络urlConnection.getInputStream())就出错 .
结果查了下, 找到原因原来是4.0以上, 对网络的使用如果放在UI线程里就会抛出异常, 要么就修改ManiFest文件 把 android:targetSdkVersion="" 这句删除, 要么就使用单独线程, 或者是异步任务类,
总之4.0以后在主线程中访问网络会报主线程访问网络异常.
详见这篇文章
http://www.cnblogs.com/kissazi2/p/3153307.html
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去掉,问题就解决了,但不是治本的解决方案。(如下图所示)
方法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_BACKGROUND
给Process.setThreadPriority()
。.如果我们不通过这种方法将线程的优先级设为较低级别的话,那么这个线程就会拥有跟UI线程一样的优先级,我们的应用程序就可能被这个线程拖慢。
- android.os.NetworkOnMainThreadException问题
- android.os.NetworkOnMainThreadException问题
- android.os.NetworkOnMainThreadException
- android.os.NetworkOnMainThreadException
- android.os.NetworkOnMainThreadException
- android.os.NetworkOnMainThreadException异常
- 关于android.os.NetworkOnMainThreadException
- android.os.NetworkOnMainThreadException
- android.os.NetworkOnMainThreadException
- android.os.NetworkOnMainThreadException
- 异常:android.os.NetworkOnMainThreadException
- android.os.NetworkOnMainThreadException
- android.os.NetworkOnMainThreadException异常
- android.os.NetworkOnMainThreadException
- exception: android.os.NetworkOnMainThreadException
- 异常:android.os.NetworkOnMainThreadException
- android.os.NetworkOnMainThreadException
- 异常android.os.NetworkOnMainThreadException
- Spark 入门之二:Spark RDD详解
- 解析XML--用php,dom来获得xml文件里的标签内value
- 多人合作中启动活动中传值的简明代码风格
- SQL语句(续)
- 在CentOS 6.3 64bit上安装MySQL for python模块
- android.os.NetworkOnMainThreadException
- 什么叫做线程安全?看strtok函数接触的一个名词
- iOS讲解迷惑--XMPP进阶 添加好友, 与好友聊天 (包括登录注册)
- table 中应用text-overflow
- Spark 入门之三:Spark运行框架
- 模拟器可以直接把Mac 的桌面文件做为iOS调试时存储的位置
- 大数据技术的事件处理上应该如何选择Linux服务器?
- ClassNotFoundException深入分析
- Linux下多线程模拟生产者/消费者问题