【问题标题】:android.os.NetworkOnMainThreadException with android 4.2 [duplicate]android.os.NetworkOnMainThreadException 与 android 4.2 [重复]
【发布时间】: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。

【问题讨论】:

标签: android


【解决方案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 执行网络任务的实现

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 2012-03-13
    • 2013-08-20
    相关资源
    最近更新 更多