У меня есть IntentService со своим собственным процессом, правильно так:ANR в IntentService со своим собственным процессом
AndroidManifest.xml
<service
android:name="com.app.services.UpdateDatabaseService"
android:process=":updateDatabaseService"
android:label="@string/service_name"
android:exported="false" >
</service>
Затем, когда IntentService работает, он создать две темы , Одна из задач, по которой поток является длинной задачей (более 1 минуты). И я получаю вопрос ANR.
10-24 18:51:27.923: E/ActivityManager(148): ANR in com.app:FooService
10-24 18:51:27.923: E/ActivityManager(148): Reason: Executing service com.app/.services.FooService
10-24 18:51:27.923: E/ActivityManager(148): Load: 1.08/0.48/0.21
10-24 18:51:27.923: E/ActivityManager(148): CPU usage from 13433ms to 1122ms ago:
10-24 18:51:27.923: E/ActivityManager(148): 92% 1375/com.emanga:updateMangaDatabase: 87% user + 5.7% kernel/faults: 5740 minor
10-24 18:51:27.923: E/ActivityManager(148): 0.4% 148/system_server: 0.2% user + 0.1% kernel/faults: 13 minor
10-24 18:51:27.923: E/ActivityManager(148): 0.2% 45/adbd: 0% user + 0.2% kernel
10-24 18:51:27.923: E/ActivityManager(148): 0.1% 758/logcat: 0% user + 0.1% kernel
10-24 18:51:27.923: E/ActivityManager(148): 0% 266/com.android.phone: 0% user + 0% kernel/faults: 2 minor
10-24 18:51:27.923: E/ActivityManager(148): 93% TOTAL: 87% user + 6.2% kernel + 0% irq
10-24 18:51:27.923: E/ActivityManager(148): CPU usage from 1804ms to 2442ms later:
10-24 18:51:27.923: E/ActivityManager(148): 70% 1375/com.emanga:updateMangaDatabase: 65% user + 4.9% kernel/faults: 123 minor
Ни в коем случае пользовательский интерфейс не блокируется. Итак, если служба находится в отдельном процессе (а не в потоке пользовательского интерфейса), почему я получаю эту ошибку?
EDIT 1:
Я изменил IntentService в услужении, но я получаю тот же вопрос еще. Я попробую объяснить, что я хочу получить. В архитектуре моего приложения есть действия, которые показывают данные, восстановленные из базы данных с помощью Loaders. Если в базе данных нет запрошенных данных, она будет запрашивать службу, которая будет восстанавливать данные из Интернета (служба управляет интернет-запросами, анализирует некоторые html, обновляет базу данных новыми данными, а в конце служба уведомляет об изменениях)
Эта услуга имеет свой собственный процесс, потому что, хотя улов услуг исключения, которые могли бы произойти, таким образом, приложение является Robuster от интернета или анализатора сбоев (приложение не будет врезаться)
цель грузчиков игрового заключается в получении данных из базы данных, и целью службы является получение данных из Интернета и обновление базы данных. Связь между Loaders и Services предназначена только для уведомления об изменениях или запросах.
Наконец, у этой службы есть очередь задач и исполнитель, выполняющий задачи.
public class UpdateDatabaseService extends Service {
private static final String ACTION = "com.app.services.UpdateDatabaseService";
public static final String ACTION_TASK_1 = ACTION + ".latestChapters";
public static final String ACTION_TASK_2 = ACTION + ".latestMangas";
private static final byte PARALLELTASKS = 2;
public LinkedBlockingQueue<Runnable> tasks = new LinkedBlockingQueue<Runnable>();
private ExecutorService executor = Executors.newFixedThreadPool(PARALLELTASKS);
private final IBinder mBinder = new MyBinder();
public class MyBinder extends Binder {
public UpdateDatabaseService getService() {
return UpdateDatabaseService.this;
}
}
@Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
@Override
public void onCreate(){
// By default always it does DefaultTask1
tasks.put(new DefaultTask1());
if(!isEmptyTable("tableFoo")){
tasks.put(new DefaultTask2());
}
executor();
}
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent != null && intent.getAction() != null) {
String action = intent.getAction();
if(action == ACTION_TASK_1){
tasks.put(new Task1());
} else
if(action == ACTION_TASK_2){
tasks.put(new Task2());
}
}
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
private void executor(){
while(true){
executor.execute(tasks.take());
}
}
Укажите, какой код вы можете использовать в своем сервисе, здесь нет ничего полезного. – schwiz