android 4.2的android.os.NetworkOnMainThreadException

android.os.NetworkOnMainThreadException with android 4.2

本问题已经有最佳答案,请猛点这里访问。

这里我使用此代码加载Json。 它与Android 2.2工作正常,但当我使用Android 4.2它抛出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 +"
");
        }
        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;

}

}

我也在使用谷歌API。


在setContentView(R.layout.activity_main)之后将下面的代码写入MainActivity文件;

1
2
3
4
if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

并将import语句放到你的java文件中。

1
import android.os.StrictMode;


这是正确的方法:

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
76
77
78
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 +"
");
        }
        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
}  
}

要调用它(从main):

1
2
mJSONParser = new JSONParser();
mJSONParser.execute();


请确保您不在UI线程上进行任何网络访问,而是在异步任务中执行此操作

您的应用程序在Android 3.0及更高版本上崩溃的原因,但在Android 2.x上工作正常是因为HoneyComb对滥用UI线程更加严格。例如,当运行HoneyComb或更高版本的Android设备检测到UI线程上的网络访问时,将抛出NetworkOnMainThreadException。

看到这个


使用StrictMode这样的东西: -

1
2
3
4
5
   if (android.os.Build.VERSION.SDK_INT > 9) {
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

        StrictMode.setThreadPolicy(policy);
        }


当您尝试访问主线程上的网络时(主活动执行),会发生android.os.NetworkOnMainThreadException。要避免这种情况,您必须创建一个单独的线程或AsyncTaskRunnable实现来执行JSON数据加载。由于HoneyComb,您无法在主线程上进一步执行网络任务。
以下是使用AsyncTask执行网络任务的实现