解决4.0后android.os.NetworkOnMainThreadException错误

Android SDK 2.0中访问网络不会出现android.os.NetworkOnMainThreadException异常错误,但在 4.0之后运行则会报此错误(即在主线程访问网络时发生异常)。

原因就是Android在4.0之前的版本都支持在主线程中访问网络,但在4.0以后对这部分程序进行了优化,若在主线程里执行Http请求都会报错,

其原则就是:UI线程不能有任何的网络访问操作


解决办法有两个思路,分别是:?
1
2
3
4
if (android.os.Build.VERSION.SDK_INT > 9 ) {
     StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
     StrictMode.setThreadPolicy(policy);
}
从 Android 2.3 开始提供了一个新的类 StrictMode,该类可以用于捕捉发生在应用程序主线程中耗时的磁盘、网络访问或函数调用,可以帮助开发者改进程序,

使主线程处理 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
28
29
public void onCreate(Bundle savedInstanceState) {
     super .onCreate(savedInstanceState);
     this .setContentView(R.layout.share_mblog_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( "mylog" , "请求结果-->" + 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);
     }
}
举例:如下获取Json字符串的方法在UI主线程中,就会报错:android.os.NetworkOnMainThreadException?
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public class JSONParser {
 
     static InputStream is = null ;
 
static JSONObject jObj = null ;
static String json = "" ;
 
// constructor
public JSONParser() {
 
}
 
public JSONObject getJSONFromUrl(String url) {
 
     // Making HTTP request
     try {
         // defaultHttpClient
         DefaultHttpClient httpClient = new DefaultHttpClient();
         HttpGet httpPost = new HttpGet(url);
 
             HttpResponse getResponse = httpClient.execute(httpPost);
            final int statusCode = getResponse.getStatusLine().getStatusCode();
 
            if (statusCode != HttpStatus.SC_OK) {
               Log.w(getClass().getSimpleName(),
                   "Error " + statusCode + " for URL " + url);
               return null ;
            }
 
            HttpEntity getResponseEntity = getResponse.getEntity();
 
         //HttpResponse httpResponse = httpClient.execute(httpPost);
         //HttpEntity httpEntity = httpResponse.getEntity();
         is = getResponseEntity.getContent();           
 
     } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
     } catch (ClientProtocolException e) {
         e.printStackTrace();
     } catch (IOException e) {
         Log.d( "IO" , e.getMessage().toString());
         e.printStackTrace();
 
     }
 
     try {
         BufferedReader reader = new BufferedReader( new InputStreamReader(
                 is, "iso-8859-1" ), 8 );
         StringBuilder sb = new StringBuilder();
         String line = null ;
         while ((line = reader.readLine()) != null ) {
             sb.append(line + "\n" );
         }
         is.close();
         json = sb.toString();
     } catch (Exception e) {
         Log.e( "Buffer Error" , "Error converting result " + e.toString());
     }
 
     // try parse the string to a JSON object
     try {
         jObj = new JSONObject(json);
     } catch (JSONException e) {
         Log.e( "JSON Parser" , "Error parsing data " + e.toString());
     }
 
     // return JSON String
     return jObj;
 
   }
}
正确的做法:可以采用AsyncTack?
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class JSONParser extends AsyncTask <String, Void, String>{
 
     static InputStream is = null ;
 
static JSONObject jObj = null ;
static String json = "" ;
 
// constructor
public JSONParser() {
 
}
@Override
protected String doInBackground(String... params) {
 
     // Making HTTP request
     try {
         // defaultHttpClient
         DefaultHttpClient httpClient = new DefaultHttpClient();
         HttpGet httpPost = new HttpGet(url);
 
             HttpResponse getResponse = httpClient.execute(httpPost);
            final int statusCode = getResponse.getStatusLine().getStatusCode();
 
            if (statusCode != HttpStatus.SC_OK) {
               Log.w(getClass().getSimpleName(),
                   "Error " + statusCode + " for URL " + url);
               return null ;
            }
 
            HttpEntity getResponseEntity = getResponse.getEntity();
 
         //HttpResponse httpResponse = httpClient.execute(httpPost);
         //HttpEntity httpEntity = httpResponse.getEntity();
         is = getResponseEntity.getContent();           
 
     } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
     } catch (ClientProtocolException e) {
         e.printStackTrace();
     } catch (IOException e) {
         Log.d( "IO" , e.getMessage().toString());
         e.printStackTrace();
 
     }
 
     try {
         BufferedReader reader = new BufferedReader( new InputStreamReader(
                 is, "iso-8859-1" ), 8 );
         StringBuilder sb = new StringBuilder();
         String line = null ;
         while ((line = reader.readLine()) != null ) {
             sb.append(line + "\n" );
         }
         is.close();
         json = sb.toString();
     } catch (Exception e) {
         Log.e( "Buffer Error" , "Error converting result " + e.toString());
     }
 
     // try parse the string to a JSON object
     try {
         jObj = new JSONObject(json);
     } catch (JSONException e) {
         Log.e( "JSON Parser" , "Error parsing data " + e.toString());
     }
 
     // return JSON String
     return jObj;
 
}
protected void onPostExecute(String page)
{  
     //onPostExecute
}  
}
在主线程中只需执行如下调用:?
1
2
mJSONParser = new JSONParser();
mJSONParser.execute();

第一种:强制使用以下更改,即在MainActivity的setContentView(R.layout.activity_main)下添加如下代码:

第二种:使用Thread、Runnable、Handler。即在Runnable中做HTTP请求,不用阻塞UI线程。

第二种方法就是多线程访问,因此可以采用AsyncTask任务方式也是相通的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
android.os.NetworkOnMainThreadExceptionAndroid平台的一个异常,通常是由于在主线程执行了网络操作而引发的。 Android应用程序的UI线程(主线程)主要用于处理用户界面的更新,如响应用户的操作、刷新UI元素等。然而,在Android平台上,从Android 4.0(即API Level 11)开始,禁止在主线程执行耗时的网络操作,以避免阻塞用户界面的响应性能。 如果在主线程尝试进行网络操作,就会抛出NetworkOnMainThreadException异常。这是为了提醒开发者在执行网络操作时应使用其他线程,例如后台线程AsyncTask线程池。 为了解决这个问题,可以采取以下方式之一: 1. 使用AsyncTask:将网络操作放在AsyncTask的doInBackground()方法执行,该方法在后台线程运行,并在完成后通过onPostExecute()方法将结果返回给主线程。 ```java class MyTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { // 在后台线程执行网络操作 return null; } @Override protected void onPostExecute(Void result) { // 在主线程更新UI或处理结果 } } // 启动任务 new MyTask().execute(); ``` 2. 使用Handler:在主线程创建一个Handler,在其使用post()方法来将网络操作放在Runnable执行。从而使网络操作在后台线程运行。 ```java Handler handler = new Handler(); handler.post(new Runnable() { @Override public void run() { // 在后台线程执行网络操作 } }); ``` 无论选择哪种方式,都可以避免在主线程执行网络操作而导致NetworkOnMainThreadException异常。这样可以确保应用程序的响应性能,并提供更好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值