簡體   English   中英

Android NetworkOnMainThreadException似乎無法解決

[英]Android NetworkOnMainThreadException seems unsolvable

正在與網絡服務器通信的此應用程序上工作。

我正在使用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返回響應主體String
  3. 在ExecutorService單池中執行可運行
  4. 在ExecutorService單個池中提交可調用對象,然后在future.get中
  5. 使用okHttp延遲的@Override方法onFailed onResponse

我只是想不通..我在這里做錯了什么?

謝謝

聚苯乙烯

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

我在這里做錯了什么?

您正在通過join()阻塞主應用程序線程。 擺脫它。

例如, 這是一個示例應用程序 ,它使用OkHttp3請求最新的Stack Overflow 問題。 我有一個專用的LoadThread處理HTTP I / O:

/***
  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()中啟動該線程。 然后,我不會嘗試通過join()阻止主應用程序線程。 相反,我使用greenrobot的EventBus找出何時加載數據,然后使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM