【问题标题】:Android API error / httpget NetworkOnMainThreadException [duplicate]Android API错误/ httpget NetworkOnMainThreadException [重复]
【发布时间】:2014-08-17 06:14:15
【问题描述】:

这是我的错误信息:

08-17 07:58:14.286 32620-32620/xxx.dk.xxx E/AndroidRuntime:致命异常:主要 进程:xxx.dk.xxx,PID:32620 android.os.NetworkOnMainThreadException 在 android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1239) 在 java.net.InetAddress.lookupHostByName(InetAddress.java:388) 在 java.net.InetAddress.getAllByNameImpl(InetAddress.java:239) 在 java.net.InetAddress.getAllByName(InetAddress.java:214) 在 com.android.okhttp.internal.Dns$1.getAllByName(Dns.java:28) 在 com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:216) 在 com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:122) 在 com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:292) 在 com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255) 在 com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206) 在 com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345) 在 com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:89) 在 xxx.dk.xxx.DAL.JsonConnection.checkSecret(JsonConnection.java:42) 在 xxx.dk.xxx.BLL.CheckCarrierData.checkSecret(CheckCarrierData.java:14) 在 xxx.dk.xxx.GUI.Login.onClick(Login.java:49) 在 android.view.View.performClick(View.java:4480) 在 android.view.View$PerformClick.run(View.java:18686) 在 android.os.Handler.handleCallback(Handler.java:733) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:157) 在 android.app.ActivityThread.main(ActivityThread.java:5872) 在 java.lang.reflect.Method.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:515) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674) 在 dalvik.system.NativeStart.main(Native Method)

我正在尝试使用在 API10 上运行的 httpGet 方法,但是当我在具有 4.4.2 的单元上使用它时失败 -> 我需要 API10 及更高版本的支持。

代码:

public class JsonConnection
{
private String secretJsonStr = null;
private String nameOfCarrier = "";
public String checkSecret(String secret)
{
    HttpURLConnection urlConnection = null;
    BufferedReader reader = null;



    final String QueryParam = "secret";

    try
    {
        final String httpUrl = "***SOMEURL***?";

        Uri builtUri = Uri.parse(httpUrl).buildUpon().
appendQueryParameter(QueryParam, secret.toString()).build();

        URL url = new URL(builtUri.toString());

        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestMethod("GET");
        urlConnection.connect();
        // Read the input stream into a String
        InputStream inputStream = urlConnection.getInputStream();
        StringBuffer buffer = new StringBuffer();
        if (inputStream == null)
        {
            // Nothing to do.
            return null;
        }
        reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        while ((line = reader.readLine()) != null)
        {
            buffer.append(line + "\n");
        }
        if (buffer.length() == 0)
        {
            // Stream was empty. No point in parsing.
            return null;
        }
        secretJsonStr = buffer.toString();
    } catch (IOException e)
    {
        Log.e("Login", "Error", e);
        return null;
    } finally
    {
        if (urlConnection != null)
        {
            urlConnection.disconnect();
        }
        if (reader != null)
        {
            try
            {
                reader.close();
            } catch (final IOException e)
            {
                Log.e("Login", "Error closing stream", e);
            }
        }
    }
    try
    {
        JSONObject secretJson = new JSONObject(secretJsonStr);
        nameOfCarrier = getCarrierInfoFromJson(secretJson);

    }
    catch (JSONException e)
    {
        e.printStackTrace();
    }
    return nameOfCarrier;
}

private String getCarrierInfoFromJson(JSONObject secretJson)
        throws JSONException
{

    final String CARRIER_NAME = "Name";

    String nameOfCarrier2 = secretJson.getString(CARRIER_NAME);

    return nameOfCarrier2;


    }
}

由于某些保护,我无法向您显示 URL,但在 API 10 2.3.6 单元中运行时,一切都像魅力一样运行..

我虽然在所有 android 设备上完全向后兼容。

希望你有知识来帮助我,我肯定不知道怎么做。 :-(

最诚挚的问候 拉斯穆斯

【问题讨论】:

  • 忘了提到它在运行 urlConnection.connect() 时会跳转到决赛 - 它永远不会进入输入流。

标签: android http-get


【解决方案1】:

问题是http请求是在主线程(NetworkOnMainThreadException)上执行的,所以你需要把调用移到Thread。更多信息here

更新:实际上,this 可能重复。

【讨论】:

    【解决方案2】:

    正如错误所说,您无法在 MainThread 上执行 HTTP 连接,这会冻结屏幕。这是不合适的。

    您可以通过以下方式获得该权限:

    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    
    StrictMode.setThreadPolicy(policy);
    

    但是,这不是一个好习惯。您必须在后台线程上运行 http 连接并向用户显示加载消息。

    new Thread(new Runnable() {
                @Override
                public void run() {
                    // code goes here ...
                }
            }).start();
    

    【讨论】:

      【解决方案3】:

      正如其他答案所暗示的,您收到此错误是因为您在主线程上运行网络操作。我建议使用 AsyncTask。

      This link 向您展示了 AsyncTask 的结构。

      要调用 AsyncTask,请使用

      //getData() is name of class
      new getData().execute();
      

      更多参考Android Developer site

      【讨论】:

        猜你喜欢
        • 2014-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-29
        • 2012-08-09
        • 1970-01-01
        • 2011-07-06
        相关资源
        最近更新 更多