3

我正在尝试编写一个简单的服务,每隔几秒钟就会做一些事情。但是当我尝试在主 Activity 中运行其他 AsyncTasks 时运行服务时,我注意到其他 AsyncTasks 卡在 onPreExecute 上。当我禁用该服务时,一切都按预期工作。服务的 AsynTask 阻塞其他 AsyncTask 是否有原因?

服务

public class SVC_SyncData extends Service {

    private final String TAG = "SVC_SyncData";

    private AT_SyncData m_SyncPoll = null;

    public static boolean isRunning = false;

    public SVC_SyncData() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate");
        m_SyncPoll = new AT_SyncData(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand");
        m_SyncPoll.execute();
        isRunning = true;
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy");
        m_SyncPoll.cancel(false);
        isRunning = false;
    }
}

AT_SyncData 的 doInBackground

@Override
protected Void doInBackground(Void... params) {
    Log.i(TAG, "doInBackground");

    try {
        while (!isCancelled()) {
            Log.i(TAG, "syncData");

            // Sleep until next cycle
            Thread.sleep(5000);
        }
    }
    catch (Exception ex) {
        ex.printStackTrace();
    }

    return null;
}
4

2 回答 2

6

AsyncTask文档指出:

执行顺序

首次引入时,AsyncTask 在单个后台线程上串行执行。从 DONUT 开始,这被更改为允许多个任务并行运行的线程池。从 HONEYCOMB 开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。

如果你真的想要并行执行,你可以使用 THREAD_POOL_EXECUTOR 调用 executeOnExecutor(java.util.concurrent.Executor, Object[])。

因此,较新版本的 android 会有你描述的这个问题。您需要使用 executeOnExecutor 来确保您在单独的线程上运行。

此外,如果您有要在单独的线程中运行的服务,我建议:

  1. 使用IntentService
  2. 有时,您希望对服务的生命周期进行比 IntentService 提供的更多的控制,在这种情况下,您可以在服务中创建一个线程并在其中运行您的后台代码。实际上,更具体地说,创建一个包含 Looper的HandlerThread ,以便您可以使用标准的 android 方法在主线程和后台线程之间进行通信(消息)。就个人而言,我通常为我的服务选择此选项。
于 2012-10-17T17:52:17.347 回答
0

如果它在服务中,只需使用 Thread 或 Callable。AsyncTask 用于 UI 线程。服务不是 UI 线程。

API 是这样说的:“AsyncTasks 应该理想地用于短时间的操作(最多几秒钟。)如果您需要保持线程长时间运行,强烈建议您使用 java 提供的各种 API Executor、ThreadPoolExecutor、FutureTask等.util.concurrent包"

异步任务

于 2012-10-17T17:55:14.083 回答