Android 11中弃用的Android AsyncTask API有哪些替代方案? [英] Android AsyncTask API deprecating in Android 11.What are the alternatives?

查看:3064
本文介绍了Android 11中弃用的Android AsyncTask API有哪些替代方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:此问题与

  1. 几天前就完成了AOSP弃用承诺.
  2. 另一个问题是关于通过AsyncTask使用AsyncTaskLoader.


Google在Android 11中弃用了Android AsyncTask API,并建议改用java.util.concurrent.您可以在此处


Google is deprecating Android AsyncTask API in Android 11 and suggesting to use java.util.concurrent instead. you can check out the commit here

 *
 * @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正确替换下面显示的代码片段是什么.它是Activity的静态内部类.我正在寻找适用于minSdkVersion 16

If you’re maintaining an older codebase with asynchronous tasks in Android, you’re likely going to have to change it in future. My question is that what should be proper replacement of the code snippet shown below using java.util.concurrent. It is a static inner class of an Activity. I am looking for something that will work with 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) ;
        }     


    }

推荐答案

private WeakReference<MyActivity> activityReference;

已弃用它,

Good riddance that it's deprecated, because the WeakReference<Context> was always a hack, and not a proper solution.

现在人们将有机会对其代码进行清理.

Now people will have the opportunity to sanitize their code.

AsyncTask<String, Void, MyPojo> 

基于此代码,实际上不需要Progress,并且有String输入+ MyPojo输出.

Based on this code, Progress is actually not needed, and there is a String input + MyPojo output.

这实际上很容易实现,无需使用AsyncTask.

This is actually quite easy to accomplish without any use of 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);
            });
        });
    }
}

如何传递字符串?像这样:

How to pass in the String? Like so:

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);
    }); 
}


此示例使用了一个单线程池,该池非常适合数据库写入(或序列化的网络请求),但是如果您想要数据库读取或多个请求的内容,则可以考虑以下Executor配置:


This example used a single-threaded pool which is good for DB writes (or serialized network requests), but if you want something for DB reads or multiple requests, you can consider the following Executor configuration:

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

这篇关于Android 11中弃用的Android AsyncTask API有哪些替代方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆