2017-09-15 12 views
0

J'ai beaucoup d'enregistrements que je tire du service web et je dois les mettre en cache localement. En faisant cela (plus de 1000 enregistrements), le thread de l'interface utilisateur est bloqué et je reçois un avertissement ANR. J'ai pensé qu'utiliser IntentService pour cela ne bloquera pas l'interface utilisateur. Qu'est-ce que je fais?Le stockage du contenu dans la base de données Sqlite via IntentService bloque le thread d'interface utilisateur

Quelques extraits de code:

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 public class { privé 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

comment démarrez-vous le service? –

Répondre

1

Tout d'abord, ne jamais faire quelque chose asynchrone d'un IntentService. Une fois le onHandleIntent() renvoyé, le IntentService sera détruit. Dans votre cas, il se peut que les E/S réseau continuent à fonctionner, sans parler des E/S disque.

Ensuite, onResponse() est appelée sur le thread d'application principal, qui est la source de votre problème.

, utilisez execute() au lieu de enqueue() et faire tous les travaux directement dans le IntentService sur le fil utilisé pour onHandleIntent().

+0

Merci :) m'a aidé. –