2017-09-15 11 views
0

Webサービスからプルするレコードが多数あり、ローカルにキャッシュする必要があります。これを実行している間(1000レコード以上)、UIスレッドはブロックされ、ANR警告が表示されます。 IntentServiceを使ってUIをブロックしないと思った。何が間違っていますか?IntentServiceを介してSqliteデータベースにコンテンツを格納すると、UIスレッドがブロックされます

少数のコードスニペット:

public class ContentIntentService extends IntentService { 

@Override 
protected void onHandleIntent(Intent workIntent) { 
    code = workIntent.getStringExtra("CODE"); 
    getContent(code); 
} 

private void getContent(final String code) { 
    if (apiService == null) { 
     Retrofit client = ApiClient.getClient(); 
     if (client != null) 
      apiService = client.create(ApiInterface.class); 
    } 
    if (apiService == null) { 
     MobileValetHelper.onConnectionFailed(mAppContext); 
     return; 
    } 
    Call<SectionsResponse> call = apiService.getOutletContent(outletCode, outletCode, MobileValetHelper.getContentSessionToken(mAppContext)); 
    call.enqueue(new Callback<SectionsResponse>() { 
     @Override 
     public void onResponse(@NonNull Call<SectionsResponse> call, @NonNull Response<SectionsResponse> response) { 
      if (response != null 
        && response.body() != null 
        && response.body().status != null 
        && response.body().status.equalsIgnoreCase("Success") 
        && response.body().sessionToken != null 
        && response.body().data != null 
        ) { 
         DataCacheHelper dataCacheHelper = new DataCacheHelper(ContentIntentService.this); 
         dataCacheHelper.insertItems(ContentIntentService.this, items); 
        } 
      } else if (response != null 
        && response.errorBody() != null) { 
       Log.e(TAG, "getContent response.errorBody(): " + response.errorBody().string()); 
      } 
     } 

     @Override 
     public void onFailure(@NonNull Call<SectionsResponse> call, @NonNull Throwable t) { 
      Log.e(TAG, "getContent onFailure: " + t.toString()); 
     } 
    }); 
} 

}

パブリッククラスDataCacheHelper { プライベートContentIntentService mIntentService。

public DataCacheHelper(ContentIntentService service) { 
     mIntentService = service; 
    } 

    public void insertItems(final ArrayList<CategoryItem> items) { 

     if (mIntentService != null && items != null) { 
      try { 
       ContentValues[] valueList = new ContentValues[items.size()]; 
       int i = 0; 
       ContentValues values; 
       for (final CategoryItem item : items) { 
        values = ItemsTable.getContentValues(item); 
        valueList[i++] = values; 
       } 
       context.getContentResolver().bulkInsert(provider.CONTENT_URI, valueList); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
    } 
} 

}

+0

どのようにサービスを開始していますか? –

答えて

1

まず、IntentServiceからの非同期何かをすることはありません。 onHandleIntent()が返されると、IntentServiceは破棄されます。あなたのケースでは、ネットワークI/Oは、ディスクI/Oだけでなく、まだ進行中です。

第2に、難易度の原因であるメインアプリケーションスレッドでonResponse()が呼び出されます。

enqueue()の代わりに​​を使用し、onHandleIntent()に使用されているスレッドのIntentServiceに直接すべての作業を行います。

+0

ありがとう:)私を助けた。 –

関連する問題