2017-10-08 7 views
0

Ich versuche, Bilder in einem CardPresenter in Leanback wie folgt asynchron zu laden.okhttp3 wirft NetworkOnMainThreadException beim Laden von Bildern asynchron mit Glide

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(); 
    } 
} 

In 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); 
} 

Leider ist dies nicht wie erwartet funktionieren. Nur wenige Bilder richtig in die Karten Moderator geladen, aber die meisten von ihnen sind nicht, und der folgende Fehler ausgelöst:

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

Es ist völlig zufällig, welche Arbeit und welche nicht.

Ich habe auch versucht, den strikten Modus in MainActivity.java einzustellen.

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

Während diese Lösung alle Bilder korrekt geladen und keine NetworkOnMainThreadException Fehler wirft, kommt es mit großen Performance-Probleme. Das Scrollen wird langsam und laggy, mir die folgende Meldung zeigt:

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

Gibt es eine Lösung, um die Bilder Last asynchron zu machen, während immer noch eine glatte und eine gute Leistung beibehalten?

+1

Ich glaube, diese Linie 'client.newCall (Anfrage) .execute() Gehäuse() string();' ist eine synchrone Ausführung a.. Netzwerkanforderung und verursacht Ihr Problem. – peitek

+0

Sie haben Recht ... Ich habe diesen Code verwendet, weil ich dachte, dass 'BaseGlideUrlLoader' in einem Hintergrund-Thread läuft. –

Antwort

0

Mein Ansatz war völlig falsch. Ich dachte, dass BaseGlideUrlLoader auf einem Hintergrund-Thread ausgeführt wird, aber das tut es nicht.

So ist der Code zu gehen, ist die folgende:

@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()); 
       } 
      }; 
     } 
    }); 


} 
Verwandte Themen