最近做一个Android项目,利用Jsoup读取和解析网页数据,同样的程序在Android2.3上运行完全正常,而跑到Android4上面,bug出现了...
看了一下异常:android.os.NetworkOnMainThreadException
然后,上网搜索一下才发现,原来Android4默认情况下是不允许在主线程中访问网络的。
解决问题的思路有两种:
1、解除主线程网络访问限制,参见http://developer.android.com/reference/android/os/StrictMode.html
在onCreate中加入以下代码即可:
<span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">StrictMode</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">setThreadPolicy</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><code style="line-height: 14px;"><a target=_blank target="_blank" href="http://developer.android.com/reference/android/os/StrictMode.ThreadPolicy.Builder.html" style="color: rgb(37, 138, 175); text-decoration: none;"><span class="typ" style="color: rgb(102, 0, 102);">StrictMode</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="typ" style="color: rgb(102, 0, 102);">ThreadPolicy</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="typ" style="color: rgb(102, 0, 102);">Builder</span></a></code><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">detectDiskReads</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">detectDiskWrites</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">detectNetwork</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="com" style="color: rgb(136, 0, 0);">// or .detectAll() for all detectable problems</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">penaltyLog</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">build</span><span class="pun" style="color: rgb(102, 102, 0);">());</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="typ" style="color: rgb(102, 0, 102);">StrictMode</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">setVmPolicy</span><span class="pun" style="color: rgb(102, 102, 0);">(</span><span class="kwd" style="color: rgb(0, 0, 136);">new</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><code style="line-height: 14px;"><a target=_blank target="_blank" href="http://developer.android.com/reference/android/os/StrictMode.VmPolicy.Builder.html" style="color: rgb(37, 138, 175); text-decoration: none;"><span class="typ" style="color: rgb(102, 0, 102);">StrictMode</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="typ" style="color: rgb(102, 0, 102);">VmPolicy</span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="typ" style="color: rgb(102, 0, 102);">Builder</span></a></code><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">detectLeakedSqlLiteObjects</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">detectLeakedClosableObjects</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">penaltyLog</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">penaltyDeath</span><span class="pun" style="color: rgb(102, 102, 0);">()</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="pun" style="color: rgb(102, 102, 0);">.</span><span class="pln" style="color: rgb(0, 0, 0);">build</span><span class="pun" style="color: rgb(102, 102, 0);">());</span>
不过如果要求至少是API-9才可以,否则会编译器提示错误,所以在适配一些低版本系统时候不太给力。
2、多线程中访问网络-既然系统默认不允许在主线程中访问,那么再开一个线程,这样在处理复杂流程的时候也不会影响界面的流畅,用户体验也好。
以下是一段测试代码: