android.os.NetworkOnMainThreadException 与 android 4.2 [重复]

Posted

技术标签:

【中文标题】android.os.NetworkOnMainThreadException 与 android 4.2 [重复]【英文标题】:android.os.NetworkOnMainThreadException with android 4.2 [duplicate] 【发布时间】:2013-05-02 14:51:42 【问题描述】:

这里我使用这个代码加载 Json。 android 2.2 可以正常工作,但是当我使用 android 4.2 时,它会抛出 android.os.NetworkOnMainThreadException 异常,请给我解决方案

 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;


我也在使用 google api。

【问题讨论】:

这里已经回答了问题:***.com/questions/5150637/… ***.com/a/12615724/1168654 【参考方案1】:

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

if (android.os.Build.VERSION.SDK_INT > 9) 
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

下面的 import 语句到你的 java 文件中。

import android.os.StrictMode;

【讨论】:

这不是关闭 StrictMode 的正确方法。正确的做法是在AsyncTask中调用网络操作而不是关闭 正如@SankarV 所说,应该使用 AsyncTask 而不是关闭严格模式来完成。 不建议这样做。 AsyncTask 是一种更好的方法。 推荐了这么多解决方案,但除了这个之外,没有一个能解决问题。【参考方案2】:

这是正确的方法:

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
   

调用它(从main):

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

【讨论】:

你测试过吗?不起作用那个网址是什么? return obj 在循环外不可访问【参考方案3】:

请确保您不在 UI Thread 上进行任何网络访问,而是在 Async Task 上进行

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

见this

【讨论】:

我会说因为 HoneyComb 而不是 HoneyComb 和 Ice Cream Sandwich。事实上,JB 也有同样的政策【参考方案4】:

使用 StrictMode 类似这样的东西:-

   if (android.os.Build.VERSION.SDK_INT > 9) 
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

        StrictMode.setThreadPolicy(policy); 
        

【讨论】:

这不是关闭 StrictMode 的正确方法。正确的做法是在 AsyncTask 中调用网络操作而不是关闭。他们提供的支票只是为了关闭吗? 我们也可以使用 asynkTask 但对我来说它可以工作 是的,它会起作用,但不是最好的方法。他们提供了检查以确保开发人员在单独的线程中调用网络操作,而不是简单地关闭。 哦! thanx asyncTask 不错【参考方案5】:

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

【讨论】:

以上是关于android.os.NetworkOnMainThreadException 与 android 4.2 [重复]的主要内容,如果未能解决你的问题,请参考以下文章