Android AsyncTask APIはAndroid 11で廃止予定です。代替案は何ですか?


21

編集:この質問は重複ではありません

  1. 廃止のほんの数日前のAOSPコミットが行われました。
  2. もう1つの質問は、AsyncTaskではなくAsyncTaskLoaderを使用することです。


GoogleはAndroid 11でのAndroid AsyncTask APIのサポートを終了し、java.util.concurrent代わりに使用することを提案しています。ここでコミットを確認できます

 *
 * @deprecated Use the standard <code>java.util.concurrent</code> or
 *   <a href="https://developer.android.com/topic/libraries/architecture/coroutines">
 *   Kotlin concurrency utilities</a> instead.
 */
@Deprecated
public abstract class AsyncTask<Params, Progress, Result> {

Androidで非同期タスクを含む古いコードベースを維持している場合は、将来的に変更する必要があるでしょう。私の質問は、以下に示すコードスニペットをを使用して適切に置き換えることjava.util.concurrentです。これは、アクティビティの静的内部クラスです。私はうまくいくものを探していますminSdkVersion 16

private static class LongRunningTask extends AsyncTask<String, Void, MyPojo> {
        private static final String TAG = MyActivity.LongRunningTask.class.getSimpleName();
        private WeakReference<MyActivity> activityReference;

        LongRunningTask(MyActivity context) {
            activityReference = new WeakReference<>(context);
        }

        @Override
        protected MyPojo doInBackground(String... params) {
            // Some long running task

        }

        @Override
        protected void onPostExecute(MyPojo data) {

            MyActivity activity = activityReference.get();
            activity.progressBar.setVisibility(View.GONE);
            populateData(activity, data) ;
        }     


    }

5
「廃止」とは、Googleが別の場所に移動することを推奨していることを意味します。クラスがすぐに削除されるという意味ではありません。特に、AsyncTask下位互換性を壊さずに削除することはできません。
CommonsWare


2
@ Style-7ではありません。
EpicPandaForce

「静的内部クラス」というものはありません。あなたは静的なネストされたクラスを意味します。
激怒

回答:


22
private WeakReference<MyActivity> activityReference;

常にハックであり、適切な解決策ではなかったため、WeakReference<Context>非推奨になっていることを確認します

今、人々は彼らのコードを消毒する機会を持つでしょう。


AsyncTask<String, Void, MyPojo> 

このコードに基づくProgressと、実際には必要ありません。String入力+ MyPojo出力があります。

これは、AsyncTaskを使用しなくても、実際には非常に簡単に実行できます。

public class TaskRunner {
    private final Executor executor = Executors.newSingleThreadExecutor(); // change according to your requirements
    private final Handler handler = new Handler(Looper.getMainLooper());

    public interface Callback<R> {
        void onComplete(R result);
    }

    public <R> void executeAsync(Callable<R> callable, Callback<R> callback) {
        executor.execute(() -> {
            final R result = callable.call();
            handler.post(() -> {
                callback.onComplete(result);
            });
        });
    }
}

文字列を渡す方法は?そのようです:

class LongRunningTask implements Callable<MyPojo> {
    private final String input;

    public LongRunningTask(String input) {
        this.input = input;
    }

    @Override
    public MyPojo call() {
        // Some long running task
        return myPojo;
    }
}

そして

// in ViewModel
taskRunner.executeAsync(new LongRunningTask(input), (data) -> {
    // MyActivity activity = activityReference.get();
    // activity.progressBar.setVisibility(View.GONE);
    // populateData(activity, data) ;

    loadingLiveData.setValue(false);
    dataLiveData.setValue(data);
});

// in Activity
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main_activity);

    viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
    viewModel.loadingLiveData.observe(this, (loading) -> {
        if(loading) {
            progressBar.setVisibility(View.VISIBLE);
        } else {
            progressBar.setVisibility(View.GONE);
        }
    });

    viewModel.dataLiveData.observe(this, (data) -> {
        populateData(data);
    }); 
}

この例では、DB書き込み(またはシリアル化されたネットワーク要求)に適したシングルスレッドプールを使用しましたが、DB読み取りまたは複数の要求に何かが必要な場合は、次のエグゼキューター構成を検討できます。

private static final Executor THREAD_POOL_EXECUTOR =
        new ThreadPoolExecutor(5, 128, 1,
                TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

でエラーが発生しexecutor.postます。メソッドを解決できません
クリスB

@KrisBは、execute()代わりに呼び出されているようですpost()
EpicPandaForce

Contextこれにを渡しても大丈夫かどうか知っていますか?私は渡すことを知っているContextにするAsyncTaskことの問題点の一つでした。
クリスB

Androidで非同期の場合と同じように、これをViewModel、保持フラグメント、シングルトンなどで実行する必要があります。
EpicPandaForce

1
newSingleThreadExecutor書き込みには優れていますがTHREAD_POOL_EXECUTOR、データベースの読み取りにはポストの最後にあるを必ず使用してください。
EpicPandaForce

3

Googleでは、Javaの並行処理フレームワークまたはKotlinコルーチンの使用を推奨しています。しかし、Rxjavaはjavaの同時実行性よりもはるかに高い柔軟性と機能を備えているため、かなりの人気を得ました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.