2016-06-01 11 views
0

ユーザーの画像をダウンロードするときにエラーが発生する場合があります。NetworkOnMainThreadエラーが発生します。 次のような行でクラッシュします。 byte[] imgBytes = body.bytes(); onResponseの方法はRetroFitです。私の理解は、このメソッドがメインスレッドにないことです。それとも、UIスレッドと違うのですか?RetrofitでNetworkOnMainエラーが発生し、画像をダウンロードする

ここに私のコードです。

private void syncPersonPhoto(final DBHelper db, final ArrayList<Person> syncPersons, final int current) { 
     final Person person = syncPersons.get(current); 
     Call<ResponseBody> photoSyncCall = RestClient.get(context).getPersonPhoto(person.getPersonCode(), person.getPersonTypeCode()); 
     photoSyncCall.enqueue(new Callback<ResponseBody>() { 
      @Override 
      public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { 
       if (response.isSuccessful()) { 
        ResponseBody body = response.body(); 
        try { 
         byte[] imgBytes = body.bytes(); <--- ERROR HERE 
         body.close(); 
         String imgBase64 = Base64.encodeToString(imgBytes, Base64.NO_WRAP); 
         db.addPersonImage(person.getPersonCode(), person.getPersonType(), imgBase64); 
        } catch (IOException e) { 
         log.log(TAG, "Bytes array couldn't be populated: " + e); 
        } 
       } 
      } 

      @Override 
      public void onFailure(Call<ResponseBody> call, Throwable t) { 
      } 
     }); 
    } 

誰でも問題を見ることができますか?

ありがとうございました。

+0

問題がある場合は、新しいスレッドでその行を実行してみてください。 – Nabin

+0

これは、RetroFit :: onResponseメソッドがメインスレッド上にあることを示しています!私は見られるように 'enqueue'メソッドを使用しました。別のスレッドで実行した場合、Androidには2種類のスレッドしかないので同じです。 – eoinzy

+0

これらの2種類のスレッドは何と思いますか? – Nabin

答えて

1

ResponseBodyJavaDocは言う:

レスポンスボディの生のバイトのクライアントアプリケーション にオリジンサーバからワンショット・ストリーム。 各応答本文は、Webサーバーへのアクティブな接続によってサポートされる です。これにより、クライアントアプリケーションには義務と制限の両方が課せられます( )。

あなたの電話番号bytes()は、ウェブサーバーへのまだ開いている接続を使用しています。このコールは、onResponseコールバック内で実行され、したがってメインスレッド内で実行され、NetworkOnMainThreadExceptionが発生します。

0

リクエスト自体はバックグラウンドスレッドで実行されます。しかし、応答コールバックonResponseonFailureがメインスレッドにディスパッチされて実行されます。

あなたが行った作業はネットワークに関係していない可能性があります。そうしないとエラーが発生します。

+0

OKですが、' onResponse'の後に返されるデータは 'response'にダウンロードされたデータではありませんオブジェクト、私はちょうど "ゲッター"と呼んでいますか?または、body.bytes()を呼び出すとネットワークコールが呼び出されますか?私はそれが応答の後にネットワークコールを呼び出す場合、それが奇妙に感じます。 – eoinzy

+0

コードの仕組みがわかりません。しかし、私は 'onResponse'ブロックを空のままにしておくと、クラッシュすることはないと推測しています。私は私のアプリケーションで同じコードを持っていて、私は応答を処理するためにバックグラウンドスレッドを使用しないで、うまく動作します。 –

関連する問題