3

数秒ごとに何かを行う単純なサービスを作成しようとしています。しかし、メインのアクティビティで他の AsyncTasks を実行しようとしているときにサービスを実行すると、他の AsyncTasks が onPreExecute で動かなくなることに気付きました。サービスを無効にすると、すべてが期待どおりに機能しました。Service の 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 のドキュメントには次のように記載されています。

実行順序

最初に導入されたとき、AsyncTasks は単一のバックグラウンド スレッドでシリアルに実行されました。DONUT 以降、これはスレッドのプールに変更され、複数のタスクが並行して動作できるようになりました。HONEYCOMB 以降、並列実行によって発生する一般的なアプリケーション エラーを回避するために、タスクは単一のスレッドで実行されます。

本当に並列実行が必要な場合は、THREAD_POOL_EXECUTOR を使用して executeOnExecutor(java.util.concurrent.Executor, Object[]) を呼び出すことができます。

したがって、Androidの新しいバージョンには、あなたが説明したこの問題があります。別のスレッドで実行していることを確認するには、executeOnExecutor を使用する必要があります。

さらに、別のスレッドで実行したいサービスがある場合は、次のいずれかをお勧めします。

  1. IntentServiceを使用する
  2. 場合によっては、サービスのライフサイクルを IntentService が提供するものよりも詳細に制御したい場合があります。そのような場合は、サービスでスレッドを作成し、その中でバックグラウンド コードを実行するだけです。実際には、より具体的には、ルーパーを含む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 に答える