通过IntentService在Sqlite数据库中存储内容会阻塞UI线程

问题描述:

我有很多记录,我从web服务中提取,我需要在本地缓存它们。在执行此操作时(超过1000条记录)UI线程被阻止,并且收到ANR警告。我认为使用IntentService不会阻止用户界面。我做错了什么?通过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

你是如何开始服务的? –

首先,切勿从IntentService异步的东西。一旦onHandleIntent()返回,IntentService将被销毁。在你的情况下,网络I/O可能仍在继续,更不用说磁盘I/O了。

其次,在主应用程序线程上调用onResponse(),这是您难度的来源。

因此,请使用​​代替enqueue(),并直接在onHandleIntent()的线程上执行所有工作。

+0

谢谢:)帮助我。 –