2015-08-05 15 views
9

Sto lavorando a un'applicazione Android, che recupera l'immagine da Internet e mostra nell'interfaccia utente. Sto usando RecyclerView per mostrare l'immagine. Sto pensando di scaricare l'immagine usando un thread separato. e aggiorna RecyclerView tramite il gestore. Non so che scendessimo questo concetto è corretto o meno, (lo so AsyncTask, ma per l'apprendimento scopo Sto cercando di implementare Handler.) Così ho codificato per la stessa, come di seguitoUtilizzare il gestore per inserire nella discussione dell'interfaccia utente

private void loadNewsThumbnailImage(ArrayList<DataItem> dataList) { 
    for (DataItem item : DataList) { //DataItem is the model class 
     loadThumbnailFromInternet(item); 
     } 
} 



private void loadThumbnailFromInternet(final DataItem dataItem) { 

     Thread imageDowloaderThread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       Bitmap bitmap = null; 
       try { 
        bitmap = getDataItemBitmap(dataItem.getmImageUrl()); 
        dataItem.setmThumbnail(bitmap); 
        new Handler().post(new Runnable() { // Tried new Handler(Looper.myLopper()) also 
         @Override 
         public void run() { 
          mAdapter.notifyDataSetChanged(); 
         } 
        }); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     imageDowloaderThread.start(); 

    } 

ho eseguito questo codice ma sto ricevendo errore, e l'applicazione è terminata, non so perché questo sta accadendo. per favore qualcuno mi aiuti a risolverlo. e spiega qual è il problema per il codice corrente.

(Si prega di non suggerire di utilizzare AsyncTask (ho provato e funziona benissimo))

UPDATE

Errore durante: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

+0

si prega di ricaricare la qn – droidev

risposta

15

l'applicazione è sempre risolto in quanto stai chiamando notifyDataSetChanged() da un thread non UI.

Sostituire:

new Handler().post(new Runnable() { // Tried new Handler(Looper.myLopper()) also 
         @Override 
         public void run() { 
          mAdapter.notifyDataSetChanged(); 
         } 
        }); 

Con questo:

new Handler(Looper.getMainLooper()).post(new Runnable() { // Tried new Handler(Looper.myLopper()) also 
        @Override 
        public void run() { 
         mAdapter.notifyDataSetChanged(); 
        } 
       }); 
+1

che suona bene, ma allora qual è la differenza tra Looper.getMainLooper() e Looper.myLooper()? – droidev

+2

Looper.getMainLooper() ottiene il looper principale dell'applicazione mentre Looper.myLooper() restituisce il Looper associato al thread corrente. refere: http://developer.android.com/reference/android/os/Looper.html –

1

Il filo si è definito non dispone di un Looper, e nessuna coda di messaggi, quindi non è possibile inviare il messaggio in questo thread. AsyncTask ha il suo Looper che puoi trovare nel suo codice sorgente. Questo è gestore definito in AsyncTask:

private static class InternalHandler extends Handler { 
    public InternalHandler() { 
     super(Looper.getMainLooper()); 
    } 

    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) 
    @Override 
    public void handleMessage(Message msg) { 
     AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj; 
     switch (msg.what) { 
      case MESSAGE_POST_RESULT: 
       // There is only one result 
       result.mTask.finish(result.mData[0]); 
       break; 
      case MESSAGE_POST_PROGRESS: 
       result.mTask.onProgressUpdate(result.mData); 
       break; 
     } 
    } 
}