AsyncTask API 在 Android 11 中已弃用。有哪些替代方案?

新手上路,请多包涵

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

    }

原文由 Zeeshan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.2k
2 个回答
> private WeakReference<MyActivity> activityReference;
>
> ```

很好摆脱它已被弃用, [因为 `WeakReference<Context>` 总是一个黑客,而不是一个适当的解决方案](https://proandroiddev.com/a-quick-story-about-async-callbacks-memory-leaks-weakreferences-and-misconceptions-78003b3d6b26)。

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

* * *

> ```
>  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 { 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 读取或多个请求的东西,你可以考虑以下 Executor 配置:

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

”`

原文由 EpicPandaForce 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以直接使用 Executors 来自 java.util.concurrent 包。

我还搜索了它,并在这个 Android Async API is Deprecated 帖子中找到了解决方案。

不幸的是,该帖子使用的是 Kotlin,但经过一些努力我将其转换为 Java。所以这是解决方案。

 ExecutorService executor = Executors.newSingleThreadExecutor();
Handler handler = new Handler(Looper.getMainLooper());

executor.execute(new Runnable() {
    @Override
    public void run() {

        //Background work here

        handler.post(new Runnable() {
            @Override
            public void run() {
                //UI Thread work here
            }
        });
    }
});

很简单吧?如果您在项目中使用 Java 8,则可以稍微简化它。

 ExecutorService executor = Executors.newSingleThreadExecutor();
Handler handler = new Handler(Looper.getMainLooper());

executor.execute(() -> {
    //Background work here
    handler.post(() -> {
        //UI Thread work here
    });
});

尽管如此,它在代码的简洁性方面仍然无法击败kotlin,但比以前的java版本要好。

希望这会帮助你。谢谢你

原文由 Kashfa Khan 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题