2014-06-06 108 views
0

我試圖從Service開始另一個IntentService,但它在嘗試傳遞新的ResultReceiver時給我一個錯誤以新的Handler作爲參數。java.lang.RuntimeException:無法在未調用Looper.prepare()的線程中創建處理程序

不知道爲什麼它給了我這個錯誤。請幫忙!

797線在SocketIOService已發生的錯誤是:

downloadIntent.putExtra(DownloadService.KEY_RECEIVER, new DownloadReceiver(new Handler())); 

堆棧跟蹤錯誤

06-05 19:51:10.417: E/AndroidRuntime(7716): FATAL EXCEPTION: Thread-6358 
06-05 19:51:10.417: E/AndroidRuntime(7716): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
06-05 19:51:10.417: E/AndroidRuntime(7716):  at android.os.Handler.<init>(Handler.java:121) 
06-05 19:51:10.417: E/AndroidRuntime(7716):  at com.walintukai.lfdate.SocketIOService$9.run(SocketIOService.java:797) 
06-05 19:51:10.417: E/AndroidRuntime(7716):  at java.lang.Thread.run(Thread.java:856) 

開始IntentService

new Thread(new Runnable() { 
     public void run() { 
      try { 
       JSONArray array = json.getJSONArray(0); 

       if (array.length() > 0) { 
        ArrayList<String> coverPhotos = new ArrayList<String>(); 

        for (int i = 0; i < array.length(); i++) { 
         String id = array.getJSONObject(i).getString(KEY_ID); 
         String name = array.getJSONObject(i).getString(KEY_NAME); 
         String genre = array.getJSONObject(i).getString(KEY_GENRE); 

         String platform = ""; 
         JSONArray platformArray = array.getJSONObject(i).getJSONArray(KEY_PLATFORM); 
         for (int p = 0; p < platformArray.length(); p++) { 
          if (p == 0) { platform = platformArray.getString(p); } 
          else { platform = platform + ", " + platformArray.getString(p); } 
         } 

         String coverPhoto = ""; 
         JSONArray coverPhotoArray = array.getJSONObject(i).getJSONArray(KEY_COVER_PHOTO); 
         for (int c = 0; c < coverPhotoArray.length(); c++) { 
          if (c == 0) { coverPhoto = coverPhotoArray.getString(c); } 
          else { coverPhoto = coverPhoto + ", " + coverPhotoArray.getString(c); } 
         } 

         Game game = new Game(id, name, genre, platform, coverPhoto); 
         if (!db.doesGameExist(id)) { db.createGame(game); } 
         else { db.updateGame(game); } 

         coverPhotos.add(coverPhoto); 

        } 

        Intent downloadIntent = new Intent(SocketIOService.this, DownloadService.class); 
        downloadIntent.putStringArrayListExtra(DownloadService.KEY_COVER_PHOTOS, coverPhotos); 
        downloadIntent.putExtra(DownloadService.KEY_RECEIVER, new DownloadReceiver(new Handler())); 
        startService(downloadIntent); 
       } 
      } 
      catch (JSONException e) { e.printStackTrace(); } 
     } 
    }).start(); 
0123碼

ResultReceiver代碼

private class DownloadReceiver extends ResultReceiver { 

    public DownloadReceiver(Handler handler) { 
     super(handler); 
    } 

    @Override 
    protected void onReceiveResult(int resultCode, Bundle resultData) { 
     super.onReceiveResult(resultCode, resultData); 

     if (resultCode == DownloadService.RESULT_FINISHED) { 
      Log.i("GAME COVER DOWNLOADS", "COMPLETE"); 
      if (mOnServiceListener != null) { 
       mOnServiceListener.onGameListUpdated(); 
      } 
     } 
    } 
} 

IntentService代碼

public class DownloadService extends IntentService { 

public static final String KEY_COVER_PHOTOS = "coverPhotos"; 
public static final String KEY_RECEIVER = "receiver"; 
public static final int RESULT_FINISHED = 1000; 
private static final String URL_GAME_COVER = "https://test.com/images/game_cover/"; 

public DownloadService(String name) { 
    super(name); 
} 

@Override 
protected void onHandleIntent(Intent intent) { 
    ArrayList<String> coverPhotos = intent.getStringArrayListExtra(KEY_COVER_PHOTOS); 
    ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra(KEY_RECEIVER); 

    for (String coverPhoto : coverPhotos) { 
     // TODO: implement code to handle multiple photos 

     try { 
      URL url = new URL(URL_GAME_COVER + coverPhoto); 
      URLConnection connection = url.openConnection(); 
      connection.connect(); 

      // This will be useful so that you can show a typical 0-100% progress bar 
      int fileLength = connection.getContentLength(); 

      // Download the file 
      InputStream input = new BufferedInputStream(url.openStream()); 
      String filepath = this.getExternalFilesDir(Environment.DIRECTORY_PICTURES).toString() + "/" + coverPhoto; 
      OutputStream output = new FileOutputStream(filepath); 

      byte data[] = new byte[1024]; 
      long total = 0; 
      int count; 
      while ((count = input.read(data)) != -1) { 
       total += count; 
       output.write(data, 0, count); 
      } 

      output.flush(); 
      output.close(); 
      input.close(); 
     } 
     catch (IOException e) { e.printStackTrace(); } 

    } 

    receiver.send(RESULT_FINISHED, null); 

} 

}

回答

2

什麼類型是你的SocketIOService?是否真的是Service

如果你在一個共同的主線是不是ActivityService創建Handler,你應該叫Looper.prepare();第一,然後消息總線在開始線程和處理工作well.Or你會得到了異常,因爲一般線程沒有消息總線(消息只是一個無限循環)。

編輯:哦,你的處理程序不在你的服務中,而是在子線程中(在你的新線程(xxx).start中),所以這是一個沒有消息總線的普通線程。我認爲你應該在外面使用你的處理程序,然後使用它作爲Service的處理程序。

+0

SocketIOService擴展了'Service'。我在剛剛實例化一個新的ResultReceiver之前添加了'Looper.prepare();現在它不再崩潰了,但是當我嘗試'receiver.send(RESULT_FINISHED,null);'ResultReceiver'不會選擇它起來。你知道爲什麼嗎? –

+0

@TheNomad看到我的新編輯。 – tianwei

+0

優秀!我刪除了'Looper.prepare();'並將'Handler'實例化爲'Service'的成員。非常感謝您的幫助 :) –

相關問題