AsyncTask 中的 Runnable 是否会阻塞 service/activity?它对我有用
Does a Runnable in AsyncTask block the service/activity? It does for me
我有一项服务执行大量耗时的计算。所以我在后台添加了一个 AsyncTask
到 运行 。我有对 requestLocationUpdates()
的调用,显然不能在没有 Looper
的 AsyncTask 中执行。大多数人建议不要使用 Looper
,因为我不知道为什么。所以最后我不得不在 AsyncTask.doInBackground()
中添加一个 Runnable
和 Handler
。 Runnable
似乎阻止了调用此服务的 activity。当我的应用程序最小化时,这不会发生。事实上,每当执行发生时,我的另一个 activity 应用程序也会暂时被阻止。
1.当我在 Handler 上调用 Runnable 时到底发生了什么?
2。如何在后台真正实现 运行?
private void forkAsyncForTracking(){
new AsyncTask<Void, Void, Void>(){
private Location loc = null;
@Override
protected Void doInBackground(Void... params) {
handler.post(new Runnable(){
@Override
public void run() {
loc = getLocation();//this blocks the activity
}
});
return null;
}
@Override
protected void onPostExecute(Void lol){
doIt(loc);
}
}.execute();
}
默认情况下,服务在 'main' 线程上运行。因此,如果您将处理程序声明为服务的私有处理程序,它会被视为在主线程上声明。因此,在 doInBackground 中声明的 runnable 将在主线程上执行。请记住,这取决于将可运行对象发布到执行位置的处理程序。您必须在工作线程内声明处理程序(在本例中为 doInBackground 方法),并使用 Looper.prepare() 定义循环程序(因为默认情况下工作线程没有循环程序,所以不会有处理程序可以使用的消息队列)。尝试一下,此后该方法不应导致任何阻塞。
protected Void doInBackground(Void... params) {
Handler handler = new Handler(); //Declared on worker thread.
Looper.prepare();
handler.post(new Runnable(){
@Override
public void run() {
loc = getLocation();//this blocks the activity
}
});
return null;
}
另一种方法是使用 IntentService,它默认在工作线程上运行,这样您就不需要任何异步任务了。对于 IntentService,检查一下:http://developer.android.com/reference/android/app/IntentService.html
我有一项服务执行大量耗时的计算。所以我在后台添加了一个 AsyncTask
到 运行 。我有对 requestLocationUpdates()
的调用,显然不能在没有 Looper
的 AsyncTask 中执行。大多数人建议不要使用 Looper
,因为我不知道为什么。所以最后我不得不在 AsyncTask.doInBackground()
中添加一个 Runnable
和 Handler
。 Runnable
似乎阻止了调用此服务的 activity。当我的应用程序最小化时,这不会发生。事实上,每当执行发生时,我的另一个 activity 应用程序也会暂时被阻止。
1.当我在 Handler 上调用 Runnable 时到底发生了什么?
2。如何在后台真正实现 运行?
private void forkAsyncForTracking(){
new AsyncTask<Void, Void, Void>(){
private Location loc = null;
@Override
protected Void doInBackground(Void... params) {
handler.post(new Runnable(){
@Override
public void run() {
loc = getLocation();//this blocks the activity
}
});
return null;
}
@Override
protected void onPostExecute(Void lol){
doIt(loc);
}
}.execute();
}
默认情况下,服务在 'main' 线程上运行。因此,如果您将处理程序声明为服务的私有处理程序,它会被视为在主线程上声明。因此,在 doInBackground 中声明的 runnable 将在主线程上执行。请记住,这取决于将可运行对象发布到执行位置的处理程序。您必须在工作线程内声明处理程序(在本例中为 doInBackground 方法),并使用 Looper.prepare() 定义循环程序(因为默认情况下工作线程没有循环程序,所以不会有处理程序可以使用的消息队列)。尝试一下,此后该方法不应导致任何阻塞。
protected Void doInBackground(Void... params) {
Handler handler = new Handler(); //Declared on worker thread.
Looper.prepare();
handler.post(new Runnable(){
@Override
public void run() {
loc = getLocation();//this blocks the activity
}
});
return null;
}
另一种方法是使用 IntentService,它默认在工作线程上运行,这样您就不需要任何异步任务了。对于 IntentService,检查一下:http://developer.android.com/reference/android/app/IntentService.html