Можно ли использовать AsyncTask в классе Service?
Все в заголовке.
В официальных документах указано, что Note that services, like other application objects, run in the main thread of their hosting process
и AsyncTask работают только в том случае, если они выполняются в UIThread.
Так можно ли использовать AsyncTask в классе Service?
Я пытаюсь сделать это, но я всегда получаю ту же ошибку
05-01 18:09:25.487: ERROR/JavaBinder(270): java.lang.ExceptionInInitializerError
...
05-01 18:09:25.487: ERROR/JavaBinder(270): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Я делаю что-то неправильно или это просто невозможно?
Вот код моего класса обслуживания
package com.eip.core;
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
public class NetworkService extends Service {
private final INetwork.Stub mBinder = new INetwork.Stub() {
@Override
public int doConnect(String addr, int port) throws RemoteException {
new ConnectTask().execute("test42");
return 0;
}
};
@Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
private class ConnectTask extends AsyncTask<String, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.i("OnPreExecute()", "");
}
@Override
protected Void doInBackground(String... arg0) {
Log.i("doInBackground()", "");
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.i("OnPostExecute()", "");
}
}
}
Ответы
Ответ 1
Думаю, я нашел, почему он не работает в моем случае.
Здесь я использую это:
private final INetwork.Stub mBinder = new INetwork.Stub() {
@Override
public int doConnect(String addr, int port) throws RemoteException {
new ConnectTask().execute("test42");
return 0;
}
};
Я использую это для выполнения так называемого IPC, Inter Process Communication, поэтому я предполагаю, что моя Служба и моя активность работают в двух разных процессах, AsyncTask должен выполняться в основном потоке пользовательского интерфейса в соответствии с к андроидному доктору, так почему я пытался сделать, кажется мне просто невозможным в соответствии с этими фактами.
Если я ошибаюсь, кто-то может исправить меня.
Ответ 2
Также не забудьте проверить IntentService. Если этого класса достаточно для ваших нужд, он позаботится о большом количестве мелких деталей, связанных с правильной работой этого шаблона.
Ответ 3
Возможно, проблема не в AsyncTask, а в другом. Например, вы уверены, что ваш метод onBind работает правильно? Попробуйте следующее:
@Override
public IBinder onBind(Intent arg0) {
return null;
}
Вы также можете попробовать это
public class NetworkService extends Service{
@Override
public void onStart(Intent intent, int startId) {
new ConnectTask().execute("test42");
}
}
Ответ 4
Можно ли использовать AsyncTask в классе Service?
Да. См. Reto Meier (2010) Профессиональная разработка приложений для Android 2, Wrox. Meier опубликовал поддерживающий код (см./Глава 9 Землетрясение 4/src/com/paad/землетрясение/EarthquakeService.java):
public class EarthquakeService extends Service {
...
private EarthquakeLookupTask lastLookup = null;
...
private class EarthquakeLookupTask extends AsyncTask<Void, Quake, Void> {
...
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
...
refreshEarthquakes();
return Service.START_NOT_STICKY;
};
private void refreshEarthquakes() {
...
lastLookup = new EarthquakeLookupTask();
lastLookup.execute((Void[])null);
...
}
}
В стороне, я не могу найти никаких доказательств, подтверждающих ваше утверждение о том, что "AsyncTask работает только в том случае, если он выполняется в UIThread" (хотя это нарушает правила потоковой передачи).
Ответ 5
Хотя возможно использовать AsyncTask
в классе Service
, это нарушает правила потоковой передачи, в частности, AsyncTask
необходимо создать и вызвать поток пользовательского интерфейса. (См. /info/282641/android-design-pattern-for-background-operation-with-ui-and-non-ui-modes/1410349#1410349 для дальнейшего обсуждения.)