zoukankan      html  css  js  c++  java
  • Android 4主线程访问网络

    最近做一个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、多线程中访问网络-既然系统默认不允许在主线程中访问,那么再开一个线程,这样在处理复杂流程的时候也不会影响界面的流畅,用户体验也好。

    以下是一段测试代码:

    1. public class MainActivity extends Activity {  
    2.   
    3.     private Button btnTest;  
    4.     private Button btnClear;  
    5.     private TextView txtResult;  
    6.     private Handler handler = null;  
    7.   
    8.     @Override  
    9.     protected void onCreate(Bundle savedInstanceState) {  
    10.         // StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()  
    11.         // .detectDiskReads()  
    12.         // .detectDiskWrites()  
    13.         // .detectNetwork() // or .detectAll() for all detectable problems  
    14.         // .penaltyLog()  
    15.         // .build());  
    16.         // StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()  
    17.         // .detectLeakedSqlLiteObjects()  
    18.         // .detectLeakedClosableObjects()  
    19.         // .penaltyLog()  
    20.         // .penaltyDeath()  
    21.         // .build());  
    22.   
    23.         super.onCreate(savedInstanceState);  
    24.         setContentView(R.layout.activity_main);  
    25.         btnTest = (Button) findViewById(R.id.btnTest);  
    26.         btnClear = (Button) findViewById(R.id.btnClear);  
    27.         txtResult = (TextView) findViewById(R.id.txtResult);  
    28.         //  
    29.         handler = new Handler() {  
    30.             public void handleMessage(Message msg) {  
    31.                 super.handleMessage(msg);  
    32.                 if (msg.what == 0) {  
    33.                     txtResult.append(" Begin test >> ");  
    34.                 } else if (msg.what == 1) {  
    35.                     txtResult.append(msg.obj.toString());  
    36.                 } else if (msg.what == 2) {  
    37.                     txtResult.append(" <<End test ");  
    38.                 }  
    39.             }  
    40.         };  
    41.         //  
    42.         txtResult.setText("");  
    43.         txtResult.setMovementMethod(ScrollingMovementMethod.getInstance());  
    44.   
    45.         btnTest.setOnClickListener(new View.OnClickListener() {  
    46.   
    47.             @Override  
    48.             public void onClick(View v) {  
    49.                 // doTest();  
    50.                 doTestOnAndroid4();  
    51.             }  
    52.         });  
    53.         btnClear.setOnClickListener(new View.OnClickListener() {  
    54.   
    55.             @Override  
    56.             public void onClick(View v) {  
    57.                 doClear();  
    58.   
    59.             }  
    60.         });  
    61.   
    62.     }  
    63.   
    64.     protected void doClear() {  
    65.         txtResult.setText("");  
    66.   
    67.     }  
    68.   
    69.     protected void doTest() {  
    70.   
    71.         String url = "http://www.baidu.com/";  
    72.         txtResult.append(" Begin test >> ");  
    73.         String text = "";  
    74.         try {  
    75.             text = Jsoup.connect(url).get().toString();  
    76.         } catch (Exception e) {  
    77.             e.printStackTrace();  
    78.             // text = e.getMessage();  
    79.         }  
    80.         txtResult.append(text);  
    81.         txtResult.append(" <<End test ");  
    82.     }  
    83.   
    84.     protected void doTestOnAndroid4() {  
    85.   
    86.         new Thread(new Runnable() {  
    87.             @Override  
    88.             public void run() {  
    89.                 Message m = new Message();  
    90.                 m.what = 0;  
    91.                 handler.sendMessage(m);  
    92.                 //  
    93.                 m = new Message();  
    94.                 m.what = 1;  
    95.                 String url = "http://www.baidu.com/";  
    96.                 try {  
    97.                     m.obj = Jsoup.connect(url).get().toString();  
    98.                 } catch (Exception e) {  
    99.                     e.printStackTrace();  
    100.                     // m.obj = e.getMessage();  
    101.                 }  
    102.                 handler.sendMessage(m);  
    103.                 //  
    104.                 m = new Message();  
    105.                 m.what = 2;  
    106.                 handler.sendMessage(m);  
    107.             }  
    108.         }).start();  
    109.   
    110.     }  
    111.   
    112. }  
  • 相关阅读:
    java基础篇3---变量值转换(不使用中间变量)
    java基础篇2---逆序输出
    Java基础篇1---数据类型转换
    java基础篇8-----字符大小写字母的转换
    java基础篇7----java.util中的Scanner类的使用
    java基础篇0----运算符
    java基础篇5---循环结构
    ECMAScript arguments 对象(摘自W3C)
    JS中的this的应用总结
    定时器 + 简单的动画效果
  • 原文地址:https://www.cnblogs.com/shipeng22022/p/4613987.html
Copyright © 2011-2022 走看看