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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:12:43  来源:igfitidea点击:

Is it possible to use AsyncTask in a Service class?

androidmultithreadingandroid-asynctaskui-thread

提问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 processand 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 processAsyncTask 只有在 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 AsyncTaskin a Serviceclass, this violates threading rules, in particular, AsyncTaskmust be instantiated and invoked on the UI thread. (See https://stackoverflow.com/a/25172977/3664487for further discussion.)

虽然可以类中使用AsyncTaskService,但这违反了线程规则,尤其是AsyncTask必须在 UI 线程上实例化和调用。(有关进一步讨论,请参阅https://stackoverflow.com/a/25172977/3664487。)