1. 程式人生 > >android網路連線經常出現Timeout,NetworkOnMainThreadException問題,手動瀏覽器訪問web地址正常

android網路連線經常出現Timeout,NetworkOnMainThreadException問題,手動瀏覽器訪問web地址正常

我們在開發android程式的時候,無論你使用URLConnection還是HttpClient操作,經常遇到Timeout現象,這個時候如果你檢查了網路是正常的,手動瀏覽器訪問目標web地址也可以正常瀏覽的話,估摸著下面的情況對你有用

我遇到的情況就是,在一些2.X系統手機上訪問URL正常,但是在4.x系統手機上就報錯:

03-07 13:17:06.132: E/ConnectionManager(25522): android.os.NetworkOnMainThreadException

或者一些Timeout的異常

通過查閱相關資料,發現,自從Android 2.3之後,系統增加了一個類:StrictMode。這個類對網路的訪問方式進行了一定的改變。
Android的官方文件給出了這個類設定的目的:
StrictMode是一個系統提供的開發工具,用以檢測在開發過程中因為偶然的事故從而造成的系統潛在的問題,進而提示開發者對其進行修復。
StrictMode通常用於捕獲磁碟訪問或者網路訪問中與主程序之間互動產生的問題,因為在主程序中,UI操作和一些動作的執行是最經常用到的,它們之間會產生一定的衝突問題。將磁碟訪問和網路訪問從主執行緒中剝離可以使磁碟或者網路的訪問更加流暢,提升響應度和使用者體驗。
顯然,大多數初學者在進行網路開發時,會選擇將訪問網路的程式碼直接放到主程序中,由於和主程序的首要工作——UI互動——相矛盾,因此,必須設定一定的檢測機制,以保證系統執行的流暢,所有的異常都可以被檢測。
Android文件建議我們增加這兩條命令:

2 3 4 5 6 7 8 9 10 11 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork()   // or .detectAll() for all detectable problems .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() 
//探測SQLite資料庫操作 .penaltyLog() //列印logcat .penaltyDeath() .build());

即使這樣子的話,在4.x系統手機上還是會報錯,但是不會中斷程式執行;

QQ截圖20130307133238

其實我的程式是一個webview做的android app殼, js通過webview跟native互動,讓native做一些代理訪問操作,html5部分會去做儲存展示操作,也就說js做的一些儲存操作和native做的網路訪問有可能在併發執行,StrictMode只不過更好地檢測出來而已。