19

一切都在标题中。

在官方文档中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()", "");
        }

    }
}
4

5 回答 5

12

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

于 2010-05-01T23:07:10.010 回答
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,进程间通信,所以我猜我的 Service 和我的 Activity 处于两个不同的进程中,AsyncTask 必须根据 android 文档在主 UI 线程中执行,所以我为什么要尝试根据这些事实,在我看来是不可能的。

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

于 2010-05-05T19:18:42.180 回答
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");
  }
}
于 2010-05-01T23:54:41.250 回答
1

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

是的。请参阅 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);
        ...
    }
}

另外,我找不到任何证据来支持您的说法,即“ AsyncTask 仅在它在 UIThread 中执行时才有效”(尽管这会违反线程规则)。

于 2014-08-07T01:36:54.583 回答
0

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

于 2014-08-14T00:07:31.910 回答