通过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();
}
}
}
}
答
首先,切勿从IntentService
异步的东西。一旦onHandleIntent()
返回,IntentService
将被销毁。在你的情况下,网络I/O可能仍在继续,更不用说磁盘I/O了。
其次,在主应用程序线程上调用onResponse()
,这是您难度的来源。
因此,请使用代替enqueue()
,并直接在onHandleIntent()
的线程上执行所有工作。
+0
谢谢:)帮助我。 –
你是如何开始服务的? –