问题描述
Google 正在弃用 Android 11 中的 Android AsyncTask API,并建议改用 java.util.concurrent
.您可以在此处
** @deprecated 使用标准的<code>java.util.concurrent</code>或者* 反而.*/@已弃用公共抽象类 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);填充数据(活动,数据);}}
很高兴它已被弃用,因为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) ;
}
}
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.
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 中弃用.有哪些替代方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!