Android NetworkOnMainThreadException似乎无法解决

时间:2016-04-16 21:27:05

标签: java android

使用此应用程序,该应用程序与网络服务器通信。

我正在使用okHttp发送http请求并获得响应。

由于某种原因,当请求需要很长时间时,我会收到NetworkOnMainThreadException。

我发现的所有解决方案都无法解决。

这是在接收数据耗时之前有效的代码。

HttpGetRunnable.java

public class HttpGetRunnable implements Runnable {

  private Request request;
  private Response response;

  public HttpGetRunnable(String route) {
    String url = "http://10.0.2.2:8080" + route;
    request = new Request.Builder()
            .url(url)
            .build();
  }

  @Override
  public void run() {
    try{
        OkHttpClient client = new OkHttpClient();
        response = client.newCall(request).execute();
    } catch (IOException e) {
        e.printStackTrace();
        System.err.println(e.getMessage());
    }
  }

  public Response getResponse() {
    return response;
  }
}

用法

try {
    HttpGetRunnable httpGet = new HttpGetRunnable("/timesheet/" + user.getId());
    Thread thread = new Thread(httpGet);

    thread.start();
    thread.join();

    Response response = httpGet.getResponse();
    String jsonString = response.body().string();   
    // ^ throw exception on this line when taking to long
} catch (Exception e) {
    e.printStackTrace(System.out);
}

错误

04-16 23:06:53.042 31145-31145/com.example.jim.app I/System.out: android.os.NetworkOnMainThreadException
.. (no caused at)

到目前为止我尝试了什么:

  1. 使用Callable(与Runnable相同,返回Response)
  2. 使用Callable返回响应正文字符串
  3. 在ExecutorService单池中执行runnable
  4. 在ExecutorService单个池中提交callable,然后在future.get
  5. 中提交
  6. 使用okHttp deferred @Override方法onFailed onResponse
  7. 我无法弄清楚.. 我在这里做错了什么?

    由于

    P.S

    使用此版本com.squareup.okhttp3:okhttp:3.2.0

1 个答案:

答案 0 :(得分:3)

  

我在这里做错了什么?

您正在通过SELECT Id,userId,rank FROM (SELECT Id,userID, @rank := IFNULL(@rank,0)+1 as rank FROM users ORDER BY food_total DESC) AS T WHERE T.userID = 'g02' 阻止主应用程序主题。摆脱它。

例如,here is a sample app使用OkHttp3来请求最新的Stack Overflow 问题。我有一个处理HTTP I / O的专用join()

LoadThread

但我只是在片段的/*** Copyright (c) 2013-2016 CommonsWare, LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. From _The Busy Coder's Guide to Android Development_ https://commonsware.com/Android */ package com.commonsware.android.okhttp; import android.util.Log; import com.google.gson.Gson; import java.io.BufferedReader; import java.io.Reader; import de.greenrobot.event.EventBus; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; class LoadThread extends Thread { static final String SO_URL= "https://api.stackexchange.com/2.1/questions?" + "order=desc&sort=creation&site=stackoverflow&tagged=android"; @Override public void run() { try { OkHttpClient client=new OkHttpClient(); Request request=new Request.Builder().url(SO_URL).build(); Response response=client.newCall(request).execute(); if (response.isSuccessful()) { Reader in=response.body().charStream(); BufferedReader reader=new BufferedReader(in); SOQuestions questions= new Gson().fromJson(reader, SOQuestions.class); reader.close(); EventBus.getDefault().post(new QuestionsLoadedEvent(questions)); } else { Log.e(getClass().getSimpleName(), response.toString()); } } catch (Exception e) { Log.e(getClass().getSimpleName(), "Exception parsing JSON", e); } } } 中启动该线程。我不会尝试通过onCreate()阻止主应用程序线程。相反,我使用greenrobot的EventBus来找出加载数据的时间,然后使用它。