2017-10-08 61 views
0

我試圖加載圖像異步到Leanback中的CardPresenter像這樣。okhttp3拋出NetworkOnMainThreadException與滑行異步加載圖像

public interface CustomImageModel { 
    String requestCustomUrl(int width, int height); 
} 

public static class CustomImageModelGrabber implements CustomImageModel { 

    public CustomImageModelGrabber() { 

    } 

    @Override 
    public String requestCustomUrl(int width, int height) { 
     OkHttpClient client = new OkHttpClient; 
     Request request = new Request.Builder().url(image_url).build(); 
     return client.newCall(request).execute().body().string(); 
    } 
} 

public static class CustomImageUrlLoader extends BaseGlideUrlLoader<CustomImageModel> { 
    public CustomImageUrlLoader(Context context) { 
     super(context); 
    } 

    @Override 
    protected String getUrl(CustomImageModel model, int width, int height) { 
     return model.requestCustomUrl(); 
    } 
} 

在CardPresenter.java

@Override 
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) { 

    CustomImageModel customImageRequest = new CustomImageModelGrabber(); 

    Glide 
      .with(context) 
      .using(new CustomImageUrlLoader(context)) 
      .load(customImageRequest) 
      .into(imageView1); 
} 

不幸的是預期,這並不工作。 只有少數圖像正確載入卡演示,但其中大部分都沒有了,下面的錯誤被拋出:

android.os.NetworkOnMainThreadException 
android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303) 

這是完全隨機的,其工作,哪些沒有。

我也嘗試在MainActivity.java中設置嚴格模式。

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

雖然這種解決方案正確加載的所有圖像,並且不拋出任何NetworkOnMainThreadException錯誤,它帶有巨大的性能問題。滾動變得緩慢和laggy,我展示了以下消息:

I/Choreographer: Skipped 182 frames! The application may be doing too much work on its main thread. 

有沒有什麼解決辦法,使圖像負載異步同時仍保持平穩和良好的性能?

+1

我相信此行'client.newCall(請求).execute()身體()的字符串();'是的同步執行。網絡請求並導致您的問題。 – peitek

+0

你是對的...我使用這段代碼是因爲我認爲'BaseGlideUrlLoader'運行在後臺線程上。 –

回答

0

我的方法是完全錯誤的。我認爲BaseGlideUrlLoader在後臺線程上運行,但它不。

因此,代碼走的是以下幾點:

@Override 
public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) { 

    final ImageCardView cardView = (ImageCardView) viewHolder.view; 

    OkHttpClient client = new OkHttpClient; 
    Request request = new Request.Builder().url(image_url).build(); 


    client.newCall(request).enqueue(new Callback() { 
     @Override public void onFailure(Call call, IOException e) { 
     e.printStackTrace(); 
     } 

     @Override public void onResponse(Call call, Response response) throws IOException { 
     try (ResponseBody responseBody = response.body()) { 
      if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 


      String imageFromResponse = responseBody.string(); 
      // do whatever is needed to get the image (i.e JSON-handling) 

      Handler mainHandler = new Handler(Looper.getMainLooper()); 
      Runnable myRunnable = new Runnable() { 
       @Override 
       public void run() { 
        Glide.with(cardView.getContext()) 
          .load(imagefromResponse) 
          .error(mDefaultCardImage) 
          .into(cardView.getMainImageView()); 
       } 
      }; 
     } 
    }); 


}