Android 是否可以在 Service 类中使用 AsyncTask?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2750664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to use AsyncTask in a Service class?
提问by Spredzy
Everything is in the title.
一切都在标题中。
On the official documentations it is stated that Note that services, like other application objects, run in the main thread of their hosting process
and AsyncTask only works if it is executed in the UIThread.
在官方文档中声明Note that services, like other application objects, run in the main thread of their hosting process
AsyncTask 只有在 UIThread 中执行时才有效。
So is it possible to use AsyncTask in a Service class?
那么是否可以在 Service 类中使用 AsyncTask 呢?
I am trying to do so but I'm always getting the same error
我正在尝试这样做,但我总是遇到相同的错误
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()
Am I doing something wrong or is this just impossible ?
我做错了什么还是这是不可能的?
Here is the code of my Service class
这是我的服务类的代码
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()", "");
}
}
}
采纳答案by Spredzy
I Think I found why it is not working in my case.
我想我找到了为什么它在我的情况下不起作用。
Here I am using this :
我在这里使用这个:
private final INetwork.Stub mBinder = new INetwork.Stub() {
@Override
public int doConnect(String addr, int port) throws RemoteException {
new ConnectTask().execute("test42");
return 0;
}
};
I am using this to do what so called IPC, Inter Process Communication, so I guess that my Service and my Activity are in two differents process, AsyncTask must be executed in the main UI thread according to the android doc, so why I was trying to do seems to me just impossible according to those facts.
我正在使用它来执行所谓的 IPC,进程间通信,所以我猜我的 Service 和我的 Activity 处于两个不同的进程中,根据 android doc,AsyncTask 必须在主 UI 线程中执行,所以我为什么要尝试根据这些事实,在我看来这是不可能的。
If I am wrong please someone can correct me.
如果我错了,请有人可以纠正我。
回答by hackbod
Also be sure to check out IntentService. If that class is sufficient for your needs, it will take care of a lot of little details involved in making that pattern work correctly.
也一定要检查 IntentService。如果该类足以满足您的需要,它将处理使该模式正常工作所涉及的许多小细节。
回答by user2768
Is it possible to use AsyncTask in a Service class?
是否可以在 Service 类中使用 AsyncTask?
Yes. See Reto Meier (2010) Professional Android 2 Application Development, Wrox. Meier has published supporting code(see /Chapter 9 Earthquake 4/src/com/paad/earthquake/EarthquakeService.java):
是的。请参阅 Reto Meier (2010) Professional Android 2 Application Development,Wrox。Meier 已发布支持代码(参见 /Chapter 9 Earthquake 4/src/com/paad/earthquake/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);
...
}
}
On an aside, I cannot find any evidence to support your claim that "AsyncTask only works if it is executed in the UIThread" (although this would violate threading rules).
顺便说一句,我找不到任何证据来支持您的说法,即“ AsyncTask 仅在 UIThread 中执行时才有效”(尽管这会违反线程规则)。
回答by Fedor
Maybe problem is not AsyncTask but something else. For example are you sure your onBind method works correctly? Please try this:
也许问题不是 AsyncTask 而是其他问题。例如,您确定您的 onBind 方法工作正常吗?请试试这个:
@Override
public IBinder onBind(Intent arg0) {
return null;
}
You could also try that
你也可以试试
public class NetworkService extends Service{
@Override
public void onStart(Intent intent, int startId) {
new ConnectTask().execute("test42");
}
}
回答by user2768
Although it is possible to use AsyncTask
in a Service
class, this violates threading rules, in particular, AsyncTask
must be instantiated and invoked on the UI thread. (See https://stackoverflow.com/a/25172977/3664487for further discussion.)
虽然可以在类中使用AsyncTask
Service
,但这违反了线程规则,尤其是AsyncTask
必须在 UI 线程上实例化和调用。(有关进一步讨论,请参阅https://stackoverflow.com/a/25172977/3664487。)