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

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

问题描述

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

查看提交

<代码> ** @deprecated 使用标准的<code>java.util.concurrent</code>或者* * Kotlin 并发实用程序反而.*/@已弃用公共抽象类 AsyncTask{

如果您在 Android 中维护带有异步任务的旧代码库,那么您将来可能需要对其进行更改.我的问题是应该使用 java.util.concurrent 正确替换下面显示的代码片段.它是一个 Activity 的静态内部类.我正在寻找可以与 minSdkVersion 16

一起使用的东西

私有静态类 LongRunningTask 扩展了 AsyncTask{private static final String TAG = MyActivity.LongRunningTask.class.getSimpleName();私有 WeakReference活动参考;LongRunningTask(MyActivity 上下文){activityReference = new WeakReference(上下文);}@覆盖受保护的 MyPojo doInBackground(String... params) {//一些长时间运行的任务}@覆盖protected void onPostExecute(MyPojo 数据) {MyActivity 活动 = activityReference.get();activity.progressBar.setVisibility(View.GONE);填充数据(活动,数据);}}

解决方案

private WeakReference活动参考;

很高兴它已被弃用,因为WeakReference 总是一个hack,而不是一个正确的解决方案.

现在人们将有机会清理他们的代码.

<小时><块引用>

AsyncTask

基于这段代码,实际上不需要Progress,而是有一个String输入+MyPojo输出.

这实际上很容易完成,无需使用任何 AsyncTask.

公共类TaskRunner {私人最终执行者执行者 = Executors.newSingleThreadExecutor();//根据你的要求改变private final Handler handler = new Handler(Looper.getMainLooper());公共接口回调{void onComplete(R 结果);}公共<R>void executeAsync(Callable<R> callable, Callback<R> callback) {executor.execute(() -> {最终 R 结果 = callable.call();handler.post(() -> {callback.onComplete(result);});});}}

如何传入String?像这样:

class LongRunningTask 实现 Callable{私人最终字符串输入;公共 LongRunningTask(字符串输入){this.input = 输入;}@覆盖公共 MyPojo 电话(){//一些长时间运行的任务返回 myPojo;}}

//在 ViewModel 中taskRunner.executeAsync(new LongRunningTask(input), (data) -> {//MyActivity 活动 = activityReference.get();//activity.progressBar.setVisibility(View.GONE);//填充数据(活动,数据);loadingLiveData.setValue(false);dataLiveData.setValue(data);});//在活动中@覆盖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) -> {如果(加载){progressBar.setVisibility(View.VISIBLE);} 别的 {progressBar.setVisibility(View.GONE);}});viewModel.dataLiveData.observe(this, (data) -> {填充数据(数据);});}

<小时>

这个例子使用了一个单线程池,这对数据库写入(或序列化网络请求)很有用,但如果你想要一些用于数据库读取或多个请求的东西,你可以考虑以下 Executor 配置:

private static final Executor THREAD_POOL_EXECUTOR =新 ThreadPoolExecutor(5, 128, 1,TimeUnit.SECONDS,新的 LinkedBlockingQueue());

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> {

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> 

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

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

And

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


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 AsyncTask API 在 Android 11 中弃用.有哪些替代方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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