The AsyncTask API is deprecated in Android 11. What are the alternatives?
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>());
Default constructor in android.os.AsyncTask is deprecated
according to google doc:
This class was deprecated in API level 30.
Use the standard java.util.concurrent or Kotlin concurrency utilities instead.
you can check concurrent tutorial on this link,
and how to migrate from AsyncTask to concurrent here
Android Asynctask deprecated. Need substitute examples
This is an example of how to send a request without AsyncTask using Thread
void send_request(final String url) {
try {
Thread thread = new Thread() {
public void run() {
Looper.prepare();
final JSONObject[] maindata = {new JSONObject()};
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
String data = "";
String error_data = "";
HttpURLConnection httpURLConnection = null;
try {
httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setRequestProperty("Content-Type", "application/json");
int status = httpURLConnection.getResponseCode();
Log.d("GET RX", " status=> " + status);
try {
InputStream in = httpURLConnection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(in);
int inputStreamData = inputStreamReader.read();
while (inputStreamData != -1) {
char current = (char) inputStreamData;
inputStreamData = inputStreamReader.read();
data += current;
}
Log.d("GET RX =>", " " + data);
sdbw sd = new sdbw(act);
maindata[0] = new JSONObject(data);
} catch (Exception exx) {
InputStream error = httpURLConnection.getErrorStream();
InputStreamReader inputStreamReader2 = new InputStreamReader(error);
int inputStreamData2 = inputStreamReader2.read();
while (inputStreamData2 != -1) {
char current = (char) inputStreamData2;
inputStreamData2 = inputStreamReader2.read();
error_data += current;
}
Log.e("TX", "error => " + error_data);
}
} catch (Exception e) {
Log.e("TX", " error => " + e.getMessage());
e.printStackTrace();
} finally {
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
handler.removeCallbacks(this);
Looper.myLooper().quit();
}
}, 2000);
Looper.loop();
}
};
thread.start();
} catch (Exception ex) {
Log.e("ERROR =>", "" + ex.getMessage());
ex.printStackTrace();
}
}
Android AsyncTask API deprecating in Android 11, using Executor as alternative
ExecutorService executor = Executors.newSingleThreadExecutor();
Handler handler = new Handler(Looper.getMainLooper());
//onPreExecute() before to get into executor, as below
progressBar_main_activity.setVisibility(View.VISIBLE);
executor.execute(new Runnable() {
@Override
public void run() {
//Background work here
runbackground();
handler.post(new Runnable() {
@Override
public void run() {
//UI Thread work here
update_UI();
}
});
}
});
Android: Alternatives to AsyncTask?
There are plenty AsyncTask alternatives :
https://android-arsenal.com/tag/9
and plus Needle - Multithreading library for Android
http://zsoltsafrany.github.io/needle/
Is AsyncTask deprecated now w/ AsyncTaskLoader?
AsyncTaskLoader is only useful to load data in an Activity or Fragment. AsyncTask is more versatile and can do any kind of background operation in any kind of component. There are alternatives like RxJava, HandlerThreads, simple threads, etc. but it's certainly not deprecated.
Related Topics
Android 6.0 Multiple Permissions
Concurrent Modification Exception: Adding to an Arraylist
Classpath Does Not Work Under Linux
What Is a Stack Trace, and How to Use It to Debug My Application Errors
How to Declare and Initialize an Array in Java
How to Fix a Nosuchmethoderror
How to Read a Large Text File Line by Line Using Java
Why Is 128==128 False But 127==127 Is True When Comparing Integer Wrappers in Java
Javafx 8 Compatibility Issues - Fxml Static Fields
How to Pass a Bitmap Object from One Activity to Another
Passing Data Through Intent Using Serializable
React on Global Hotkey in a Java Program on Windows/Linux/Mac
What Is the Reason Behind "Non-Static Method Cannot Be Referenced from a Static Context"
Cannot Make a Static Reference to the Non-Static Method