Android 4主線程訪問網絡

Android項目訪問webservice,同樣的程序在Android2.3上運行完全正常,而跑到Android4上面,bug出現了...

看了一下異常:android.os.NetworkOnMainThreadException

然後,上網搜索一下才發現,原來Android4默認情況下是不允許在主線程中訪問網絡的。


解決問題的思路有兩種:

1、解除主線程網絡訪問限制,參見http://developer.android.com/reference/android/os/StrictMode.html

在onCreate中加入以下代碼即可:

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskReads()
                 .detectDiskWrites()
                 .detectNetwork()   // or .detectAll() for all detectable problems
                 .penaltyLog()
                 .build());
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                 .detectLeakedSqlLiteObjects()
                 .detectLeakedClosableObjects()
                 .penaltyLog()
                 .penaltyDeath()
                 .build());

不過如果要求至少是API-9纔可以,否則會編譯器提示錯誤,所以在適配一些低版本系統時候不太給力。

2、多線程中訪問網絡-既然系統默認不允許在主線程中訪問,那麼再開一個線程好了,這樣在處理複雜流程的時候也不會影響界面的流暢,用戶體驗也好。

以下是一段測試代碼:

public class MainActivity extends Activity {  
  
    private Button btnTest;  
    private Button btnClear;  
    private TextView txtResult;  
    private Handler handler = null;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        // StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()  
        // .detectDiskReads()  
        // .detectDiskWrites()  
        // .detectNetwork() // or .detectAll() for all detectable problems  
        // .penaltyLog()  
        // .build());  
        // StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()  
        // .detectLeakedSqlLiteObjects()  
        // .detectLeakedClosableObjects()  
        // .penaltyLog()  
        // .penaltyDeath()  
        // .build());  
  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        btnTest = (Button) findViewById(R.id.btnTest);  
        btnClear = (Button) findViewById(R.id.btnClear);  
        txtResult = (TextView) findViewById(R.id.txtResult);  
        //  
        handler = new Handler() {  
            public void handleMessage(Message msg) {  
                super.handleMessage(msg);  
                if (msg.what == 0) {  
                    txtResult.append("\nBegin test >>\n");  
                } else if (msg.what == 1) {  
                    txtResult.append(msg.obj.toString());  
                } else if (msg.what == 2) {  
                    txtResult.append("\n<<End test\n");  
                }  
            }  
        };  
        //  
        txtResult.setText("");  
        txtResult.setMovementMethod(ScrollingMovementMethod.getInstance());  
  
        btnTest.setOnClickListener(new View.OnClickListener() {  
  
            @Override  
            public void onClick(View v) {  
                // doTest();  
                doTestOnAndroid4();  
            }  
        });  
        btnClear.setOnClickListener(new View.OnClickListener() {  
  
            @Override  
            public void onClick(View v) {  
                doClear();  
  
            }  
        });  
  
    }  
  
    protected void doClear() {  
        txtResult.setText("");  
  
    }  
  
    protected void doTest() {  
  
        String url = "http://www.baidu.com/";  
        txtResult.append("\nBegin test >>\n");  
        String text = "";  
        try {  
            text = Jsoup.connect(url).get().toString();  
        } catch (Exception e) {  
            e.printStackTrace();  
            // text = e.getMessage();  
        }  
        txtResult.append(text);  
        txtResult.append("\n<<End test\n");  
    }  
  
    protected void doTestOnAndroid4() {  
  
        new Thread(new Runnable() {  
            @Override  
            public void run() {  
                Message m = new Message();  
                m.what = 0;  
                handler.sendMessage(m);  
                //  
                m = new Message();  
                m.what = 1;  
                String url = "http://www.baidu.com/";  
                try {  
                    m.obj = Jsoup.connect(url).get().toString();  
                } catch (Exception e) {  
                    e.printStackTrace();  
                    // m.obj = e.getMessage();  
                }  
                handler.sendMessage(m);  
                //  
                m = new Message();  
                m.what = 2;  
                handler.sendMessage(m);  
            }  
        }).start();  
  
    }  
  
}  



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章