是否可以在Service类中使用AsyncTask?

时间:2010-05-01 16:19:48

标签: android multithreading android-asynctask ui-thread

一切都在标题中。

在官方文档中声明Note that services, like other application objects, run in the main thread of their hosting process和AsyncTask仅在UIThread中执行时才有效。

那么可以在Service类中使用AsyncTask吗?

我试图这样做,但我总是得到同样的错误

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()", "");
        }

    }
}

5 个答案:

答案 0 :(得分:12)

另外请务必查看IntentService。如果该类足以满足您的需求,它将处理使该模式正常工作所涉及的许多细节。

答案 1 :(得分:2)

我想我发现为什么它不适用于我的情况。

我在这里使用:

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,进程间通信,所以我猜我的服务和我的Activity在两个不同的进程中,AsyncTask必须在主UI线程中执行对于android doc,所以为什么我试图做的事情在我看来根本不可能。

如果我错了,请有人纠正我。

答案 2 :(得分:1)

也许问题不是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");
  }
}

答案 3 :(得分:1)

  

是否可以在Service类中使用AsyncTask?

是。请参阅Reto Meier(2010)专业Android 2应用程序开发,Wrox。 Meier有published supporting code(见/第9章地震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);
        ...
    }
}

顺便说一句,我找不到任何证据支持你的声明“ AsyncTask仅在UIThread 中执行时才有效”(尽管这会violate threading rules)。

答案 4 :(得分:0)

虽然可以use AsyncTask in a Service class,但这违反了线程规则,特别是必须在UI线程上实例化并调用AsyncTask。 (有关进一步的讨论,请参阅https://stackoverflow.com/a/25172977/3664487。)