第一次看到這異常,字面意思是說:在主線程中的網絡異常。然後我就去了解了下這個異常,先看看官方的說明:
public class
NetworkOnMainThreadException
extends RuntimeExceptionjava.lang.Object | ||||
? | java.lang.Throwable | |||
? | java.lang.Exception | |||
? | java.lang.RuntimeException | |||
? | android.os.NetworkOnMainThreadException |
Class Overview
The exception that is thrown when an application attempts to perform a networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to do networking on their main event loop threads, but it's heavily discouraged. See the document Designing for Responsiveness.
Also see StrictMode
.
所以事情就很清楚了。一個APP如果在主線程中請求網絡操作,將會拋出此異常。Android這個設計是爲了防止網絡請求時間過長而導致界面假死的情況發生。
解決方案有兩個,一個是使用StrictMode,二是使用線程來操作網絡請求。
第一種方法:簡單暴力,強制使用,代碼修改簡單(但是非常不推薦)
在MainActivity文件的setContentView(R.layout.activity_main)下面加上如下代碼
1
2
3
4
|
if
(android.os.Build.VERSION.SDK_INT > 9 )
{ StrictMode.ThreadPolicy
policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } |
第二種方法就是我使用的方法也是我要推薦的方法,將請求網絡資源的代碼使用Thread去操作。在Runnable中做HTTP請求,不用阻塞UI線程。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public
void
onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); this .setContentView(R.layout.main_view); new
Thread(runnable).start(); } Handler
handler = new
Handler(){ @Override public
void
handleMessage(Message msg) { super .handleMessage(msg); Bundle
data = msg.getData(); String
val = data.getString( "value" ); Log.i(TAG, "請求結果:"
+ val); } } Runnable
runnable = new
Runnable(){ @Override public
void
run() { //
TODO: http request. Message
msg = new
Message(); Bundle
data = new
Bundle(); data.putString( "value" , "請求結果" ); msg.setData(data); handler.sendMessage(msg); } } |
上面是比較通用的方法,我的代碼:
1
2
3
4
5
6
7
8
|
//
Android 4.0 之後不能在主線程中請求HTTP請求 new
Thread( new
Runnable(){ @Override public
void
run() { cachedImage
= asyncImageLoader.loadDrawable(imageUrl, position); imageView.setImageDrawable(cachedImage); } }).start(); |