Android 11中弃用的Android AsyncTask API有哪些替代方案?


20

编辑:这个问题不是重复的

  1. 仅仅几天后,AOSP就完成了弃用承诺。
  2. 另一个问题是关于在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。它是Activity的静态内部类。我正在寻找可以使用的东西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

没有所谓的“静态内部类”。您的意思是静态嵌套类。
白俄罗斯

Answers:


22
private WeakReference<MyActivity> activityReference;

弃用它是一件好事,因为WeakReference<Context>始终是hack,而不是适当的解决方案

现在人们将有机会清理其代码。


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

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

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

我在遇到错误executor.post。无法解析方法
Kris B,

@KrisB显然是被调用execute()而不是post()
EpicPandaForce

您知道将a传递给它是否可以Context吗?我知道将a Context传入AsyncTask是问题之一。
克里斯B

您仍然需要在ViewModel,保留的片段,单例或其他任何方式中运行它,就像通常在Android中使用异步方法一样。
EpicPandaForce

1
newSingleThreadExecutor比较适合写,但是您绝对应该THREAD_POOL_EXECUTOR在文章末尾使用来进行数据库读取。
EpicPandaForce

3

Google建议使用Java的并发框架或Kotlin Coroutines。但是Rxjava最终具有比Java并发更多的灵活性和功能,因此颇受欢迎。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.