In my application, there are multiple asynctasks. Please let me know why doInBackground of an asynctask sometimes does not getting called. Its onPreExecute method gets called. Is there any issue because of multiple asynctasks or something else?
/* ASync class for test table */
public class TestAsynch extends AsyncTask<String, Void, String>{
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String status = null;
String result1=API_Manager.getInstance().sendTestData(userName);
try {
if(result1 != null) {
// save in db
}
}
}
catch( Exception e) {
e.printStackTrace();
}
return status;
}
#Override
protected void onPostExecute(String status) {
}
}
If your project has multiple asynctasks you must check that there is a limit of asynctasks that can be executed. When you create a new AsyncTask it will be added on a Pool and will be execute only when is possible.
Check this answer:
Multitasking on android
And the docs: ThreadPoolExecutor
Here is an example on how properly handle multiple AsyncTasks AsyncTaskManager
OnPreExecute() gets called on the UI thread and doInBackground() is called on the background thread.
There is one dedicated background thread for the async task. This behaviour can be changed if you want to.
http://android-er.blogspot.in/2014/04/run-multi-asynctask-as-same-time.html
Now, say you have multiple instances of async task and I'm assuming you are calling execute() to run the async tasks. This will trigger all the preExecute immediately since UI thread is free but for the doInBackground it will triggered one by one. Hence it may take some time for the next async task to start.
doInBackground should run on a loop using a Boolean to check before execution. Before your Task is being executed, set a global boolean (may be true/false) depends on which you prefer and values add on thread should call runOnUiThread.
startExect = true;
new TestAsynch().execute();
then change this
public class TestAsynch extends AsyncTask<String, Void, String>{
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String status = null;
String result1=API_Manager.getInstance().sendTestData(userName);
try {
if(result1 != null) {
// save in db
}
}
}
catch( Exception e) {
e.printStackTrace();
}
return status;
}
#Override
protected void onPostExecute(String status) {
}
}
to this
public class TestAsynch extends AsyncTask<String, Void, String> {
String result1 = null;
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String status = null;
result1=API_Manager.getInstance().sendTestData(userName);
while (startExecute) {
Thread exe = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5);
}
catch( Exception e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
if(result1 != null) {
// save in db
}
}
});
}
}); exe.start();
}
return status;
}
#Override
protected void onPostExecute(String status) {
}
}
I know that the first you gonna this is... why the heck on the world you then use AsyncTask.
So here is my problem i am working on some Android app (API 7 for android 2.1 or higher) , and i am testing on emulator and everything was fine, so then i tested on HTC Sensation and it says NetworkOnMainThreadExeption!
I was downloading some pictures and then draw on the map.
So to solve this problem every (internet connection) in this case downloading the pictures i must put on AsyncTask to work.
So i need a method how to know when all pictures are done so i can start drawing..
I was trying so much and no result i have no idea. I got one solution with handler but if run on slower net i get nullpointer(because the pictures are not downloaded).
So please help me.
EDIT:
here is the idea:
Bitmap bubbleIcon ;
onCreate(){
...
// i am making call for Async
new ImgDown().execute(url);
//and then i calling functions and classes to draw with that picture bubbleIcon !
DrawOnMap(bubbleIcon);
}
//THIS IS ASYNC AND FOR EX. SUPPOSE I NEED TO DOWNLOAD THE PIC FIRST
class ImgDown extends AsyncTask<String, Void, Bitmap> {
private String url;
public ImgDown() {
}
#Override
protected Bitmap doInBackground(String... params) {
url = params[0];
try {
return getBitmapFromURL(url);
} catch (Exception err) {
}
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
bubbleIcon = result;
bubbleIcon = Bitmap
.createScaledBitmap(bubbleIcon, 70, 70, true);
}
public Bitmap getBitmapFromURL(String src) {
try {
Log.e("src", src);
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
// /tuka decode na slika vo pomalecuk kvalitet!
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3;
Bitmap myBitmap = BitmapFactory
.decodeStream(new FlushedInputStream(input));
Log.e("Bitmap", "returned");
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
Log.e("getBitmapFromURL", e.getMessage());
return null;
}
}
class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int byteValue = read();
if (byteValue < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
}
i hope now is more clear.
class OpenWorkTask extends AsyncTask {
#Override
protected Boolean doInBackground(String... params) {
// do something
return true;
}
#Override
protected void onPostExecute(Boolean result) {
// The results of the above method
// Processing the results here
myHandler.sendEmptyMessage(0);
}
}
Handler myHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
// calling to this function from other pleaces
// The notice call method of doing things
break;
default:
break;
}
}
};
You can write your own Delegate to delegate info about finishing the task, using OOP principles:
task_delegate.java
public interface TaskDelegate {
void TaskCompletionResult(String result);
}
main_activity.java
public class MainActivity extends Activity implements TaskDelegate {
//call this method when you need
private void startAsynctask() {
myAsyncTask = new MyAsyncTask(this);
myAsyncTask.execute();
}
//your code
#Override
public void TaskCompletionResult(String result) {
GetSomethingByResult(result);
}
}
my_asynctask.java
public class MyAsyncTask extends AsyncTask<Void, Integer, String> {
private TaskDelegate delegate;
protected MyAsyncTask(TaskDelegate delegate) {
this.delegate = delegate;
}
//your code
#Override
protected void onPostExecute(String result) {
delegate.TaskCompletionResult(result);
}
}
class openWorkTask extends AsyncTask<String, String, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
//do something
return true;
}
#Override
protected void onPostExecute(Boolean result) {
// The results of the above method
// Processing the results here
}
}
I would use a Progress Dialog if I were you. This way users can see that something is happening while the ASyncTask downloads the picture. On PostExecute, call a method from your main code that checks if the pictures are null. Remember you cannot update the UI in the doInBackground method so do any UI work in either onPreExecute or onPostExecute
private class DownloadPictures extends AsyncTask<String, Void, String>
{
ProgressDialog progressDialog;
#Override
protected String doInBackground(String... params)
{
//Download your pictures
return null;
}
#Override
protected void onPostExecute(String result)
{
progressDialog.cancel();
//Call your method that checks if the pictures were downloaded
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(
YourActivity.this);
progressDialog.setMessage("Downloading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected void onProgressUpdate(Void... values) {
// Do nothing
}
}
I was reading about AsyncTask, and I tried the simple program below. But it does not seem to work. How can I make it work?
public class AsyncTaskActivity extends Activity {
Button btn;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener((OnClickListener) this);
}
public void onClick(View view){
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for(int i=0;i<5;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
return null;
}
#Override
protected void onPostExecute(String result) {
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
}
I am just trying to change the label after 5 seconds in the background process.
This is my main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="10"
android:padding="10dip">
</ProgressBar>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Progress" >
</Button>
<TextView android:id="#+id/output"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Replace"/>
</LinearLayout>
My full answer is here, but here is an explanatory image to supplement the other answers on this page. For me, understanding where all the variables were going was the most confusing part in the beginning.
Ok, you are trying to access the GUI via another thread. This, in the main, is not good practice.
The AsyncTask executes everything in doInBackground() inside of another thread, which does not have access to the GUI where your views are.
preExecute() and postExecute() offer you access to the GUI before and after the heavy lifting occurs in this new thread, and you can even pass the result of the long operation to postExecute() to then show any results of processing.
See these lines where you are later updating your TextView:
TextView txt = findViewById(R.id.output);
txt.setText("Executed");
Put them in onPostExecute().
You will then see your TextView text updated after the doInBackground completes.
I noticed that your onClick listener does not check to see which View has been selected. I find the easiest way to do this is via switch statements. I have a complete class edited below with all suggestions to save confusion.
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings.System;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class AsyncTaskActivity extends Activity implements OnClickListener {
Button btn;
AsyncTask<?, ?, ?> runningTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = findViewById(R.id.button1);
// Because we implement OnClickListener, we only
// have to pass "this" (much easier)
btn.setOnClickListener(this);
}
#Override
public void onClick(View view) {
// Detect the view that was "clicked"
switch (view.getId()) {
case R.id.button1:
if (runningTask != null)
runningTask.cancel(true);
runningTask = new LongOperation();
runningTask.execute();
break;
}
}
#Override
protected void onDestroy() {
super.onDestroy();
// Cancel running task(s) to avoid memory leaks
if (runningTask != null)
runningTask.cancel(true);
}
private final class LongOperation extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// We were cancelled; stop sleeping!
}
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
// You might want to change "executed" for the returned string
// passed into onPostExecute(), but that is up to you
}
}
}
I'm sure it is executing properly, but you're trying to change the UI elements in the background thread and that won't do.
Revise your call and AsyncTask as follows:
Calling Class
Note: I personally suggest using onPostExecute() wherever you execute your AsyncTask thread and not in the class that extends AsyncTask itself. I think it makes the code easier to read especially if you need the AsyncTask in multiple places handling the results slightly different.
new LongThread() {
#Override public void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
}
}.execute("");
LongThread class (extends AsyncTask):
#Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Executed";
}
Concept and code here
I have created a simple example for using AsyncTask of Android. It starts with onPreExecute(), doInBackground(), publishProgress() and finally onProgressUpdate().
In this, doInBackground() works as a background thread, while other works in the UI Thread. You can't access an UI element in doInBackground(). The sequence is the same as I have mentioned.
However, if you need to update any widget from doInBackground, you can publishProgress from doInBackground which will call onProgressUpdate to update your UI widget.
class TestAsync extends AsyncTask<Void, Integer, String> {
String TAG = getClass().getSimpleName();
protected void onPreExecute() {
super.onPreExecute();
Log.d(TAG + " PreExceute","On pre Exceute......");
}
protected String doInBackground(Void...arg0) {
Log.d(TAG + " DoINBackGround", "On doInBackground...");
for (int i=0; i<10; i++){
Integer in = new Integer(i);
publishProgress(i);
}
return "You are at PostExecute";
}
protected void onProgressUpdate(Integer...a) {
super.onProgressUpdate(a);
Log.d(TAG + " onProgressUpdate", "You are in progress update ... " + a[0]);
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d(TAG + " onPostExecute", "" + result);
}
}
Call it like this in your activity:
new TestAsync().execute();
Developer Reference Here
Move these two lines:
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
out of your AsyncTask's doInBackground method and put them in the onPostExecute method. Your AsyncTask should look something like this:
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
Thread.sleep(5000); // no need for a loop
} catch (InterruptedException e) {
Log.e("LongOperation", "Interrupted", e);
return "Interrupted";
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
}
}
How to memorize the parameters used in AsyncTask?
Don't
If you are new to AsyncTask then it is very common to get confused while writing an AsyncTask. The main culprits are the parameters used in the AsyncTask, i.e., AsyncTask<A, B, C>. Based on the A, B, C (arguments) signature of the methods differs which makes things even more confusing.
Keep it simple!
The key is don't memorize. If you can visualize what your task really needs to do then writing the AsyncTask with the correct signature at the first attempt would be a piece of cake. Just figure out what your Input, Progress, and Output are, and you will be good to go.
So what is an AsyncTask?
AsyncTask is a background task that runs in the background thread. It takes an Input, performs Progress and gives an Output.
I.e., AsyncTask<Input, Progress, Output>.
For example:
What is the relationship with methods?
Between AsyncTask and doInBackground()
doInBackground() and onPostExecute(),onProgressUpdate()` are also
related
How to write that in the code?
DownloadTask extends AsyncTask<String, Integer, String>{
// Always same signature
#Override
public void onPreExecute()
{}
#Override
public String doInbackGround(String... parameters)
{
// Download code
int downloadPerc = // Calculate that
publish(downloadPerc);
return "Download Success";
}
#Override
public void onPostExecute(String result)
{
super.onPostExecute(result);
}
#Override
public void onProgressUpdate(Integer... parameters)
{
// Show in spinner, and access UI elements
}
}
How will you run this Task?
new DownLoadTask().execute("Paradise.mp3");
Background / Theory
AsyncTask allows you to run a task on a background thread, while publishing results to the UI thread.
The user should always able to interact with the app so it is important
to avoid blocking the main (UI) thread with tasks such as
downloading content from the web.
This is why we use an AsyncTask.
It offers a straightforward interface by wrapping the UI thread message queue and handler that allow you to send and process runnable objects and messages from other threads.
Implementation
AsyncTask is a generic class. (It takes parameterized types in its constructor.)
It uses these three generic types:
Params - the type of the parameters sent to the task upon execution.
Progress - the type of the progress units published during the background computation.
Result - the type of the result of the background computation.
Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
These three parameters correspond to three primary functions you can override in AsyncTask:
doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
To execute AsyncTask
Call execute() with parameters to be sent to the background task.
What Happens
On main/UI thread, onPreExecute() is called.
To initialize something in this thread. (E.g. show a progress bar on the user interface.)
On a background thread, doInBackground(Params...) is called.
(Params were passed via execute.)
Where the long-running task should happen.
Must override at least doInBackground() to use AsyncTask.
Call publishProgress(Progress...) to update the user interface with a display of progress (e.g. UI animation or log text printed) while the background computation is still executing.
Causes onProgressUpdate() to be called.
On the background thread a result is returned from doInBackground().
(This triggers the next step.)
On main/UI thread, onPostExecute() is called with the returned result.
Examples
In both examples the "blocking task" is a download from the web.
Example A downloads an image and displays it in an ImageView, while
Example B downloads some files.
Example A
The doInBackground() method downloads the image and stores it in an object of type BitMap. The onPostExecute() method takes the bitmap and places it in the ImageView.
class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bitImage;
public DownloadImageTask(ImageView bitImage) {
this.bitImage = bitImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mBmp = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mBmp = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mBmp;
}
protected void onPostExecute(Bitmap result) {
bitImage.setImageBitmap(result);
}
}
Example B
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
Example B execution
new DownloadFilesTask().execute(url1, url2, url3);
When an asynchronous task is executed, the task goes through four steps:
onPreExecute()
doInBackground(Params...)
onProgressUpdate(Progress...)
onPostExecute(Result)
Below is a demo example:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled())
break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
And once you created, a task is executed very simply:
new DownloadFilesTask().execute(url1, url2, url3);
Shortest example for just doing something asynchronously:
class MyAsyncTask extends android.os.AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
// Do something asynchronously
return null;
}
}
To run it:
(new MyAsyncTask()).execute();
When you are in the worker thread, you can not directly manipulate UI elements on Android.
When you are using AsyncTask please understand the callback methods.
For example:
public class MyAyncTask extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
// Here you can show progress bar or something on the similar lines.
// Since you are in a UI thread here.
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// After completing execution of given task, control will return here.
// Hence if you want to populate UI elements with fetched data, do it here.
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
// You can track you progress update here
}
#Override
protected Void doInBackground(Void... params) {
// Here you are in the worker thread and you are not allowed to access UI thread from here.
// Here you can perform network operations or any heavy operations you want.
return null;
}
}
FYI:
To access the UI thread from a worker thread, you either use runOnUiThread() method or post method on your view.
For instance:
runOnUiThread(new Runnable() {
textView.setText("something.");
});
or
yourview.post(new Runnable() {
yourview.setText("something");
});
This will help you know the things better. Hence in you case, you need to set your textview in the onPostExecute() method.
I would recommend making your life easier by using this library for background works:
https://github.com/Arasthel/AsyncJobLibrary
It's this simple...
AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {
#Override
public void doOnBackground() {
startRecording();
}
});
Sample Async Task with POST request:
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("key1", "value1"));
params.add(new BasicNameValuePair("key1", "value2"));
new WEBSERVICEREQUESTOR(URL, params).execute();
class WEBSERVICEREQUESTOR extends AsyncTask<String, Integer, String>
{
String URL;
List<NameValuePair> parameters;
private ProgressDialog pDialog;
public WEBSERVICEREQUESTOR(String url, List<NameValuePair> params)
{
this.URL = url;
this.parameters = params;
}
#Override
protected void onPreExecute()
{
pDialog = new ProgressDialog(LoginActivity.this);
pDialog.setMessage("Processing Request...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
super.onPreExecute();
}
#Override
protected String doInBackground(String... params)
{
try
{
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
HttpPost httpPost = new HttpPost(URL);
if (parameters != null)
{
httpPost.setEntity(new UrlEncodedFormEntity(parameters));
}
httpResponse = httpClient.execute(httpPost);
httpEntity = httpResponse.getEntity();
return EntityUtils.toString(httpEntity);
} catch (Exception e)
{
}
return "";
}
#Override
protected void onPostExecute(String result)
{
pDialog.dismiss();
try
{
}
catch (Exception e)
{
}
super.onPostExecute(result);
}
}
Update: March 2020
According to Android developer official documentation, AsyncTask is now deprecated.
It's recommended to use kotlin corourines instead. Simply, it allows you to write asynchronous tasks in a sequential style.
Simply:
LongOperation MyTask = new LongOperation();
MyTask.execute();
You need to declare the button onclicklistener. Once clicked, it calls AsyncTask class DownloadJson.
The process will be shown below:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new DownloadJson().execute();
}
});
}
// DownloadJSON AsyncTask
private class DownloadJson extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
newlist = new ArrayList<HashMap<String, String>>();
json = jsonParser.makeHttpRequest(json, "POST");
try {
newarray = new JSONArray(json);
for (int i = 0; i < countdisplay; i++) {
HashMap<String, String> eachnew = new HashMap<String, String>();
newobject = newarray.getJSONObject(i);
eachnew.put("id", newobject.getString("ID"));
eachnew.put("name", newobject.getString("Name"));
newlist.add(eachnew);
}
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
newlisttemp.addAll(newlist);
NewAdapterpager newadapterpager = new NewAdapterpager(ProcesssActivitypager.this, newlisttemp);
newpager.setAdapter(newadapterpager);
}
}
private class AsyncTaskDemo extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Do code here
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
#Override
protected void onCancelled() {
super.onCancelled();
progressDialog.dismiss();
Toast toast = Toast.makeText(
getActivity(),
"An error is occurred due to some problem",
Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
}
While working with AsyncTask, it is necessary to create a class-successor and in it to register the implementation of methods necessary for us. In this lesson we will look at three methods:
doInBackground - will be executed in a new thread, and here we solve all our difficult tasks. Because a non-primary thread does not have access to the UI.
onPreExecute - executed before doInBackground and has access to the UI
onPostExecute - executed after doInBackground (does not work if AsyncTask was canceled - about this in the next lessons) and has access to the UI.
This is the MyAsyncTask class:
class MyAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
tvInfo.setText("Start");
}
#Override
protected Void doInBackground(Void... params) {
// Your background method
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
tvInfo.setText("Finish");
}
}
And this is how to call in your Activity or Fragment:
MyAsyncTask myAsyncTask = new MyAsyncTask();
myAsyncTask.execute();
AsyncTask:
public class MainActivity extends AppCompatActivity {
private String ApiUrl="your_api";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyTask myTask=new MyTask();
try {
String result=myTask.execute(ApiUrl).get();
Toast.makeText(getApplicationContext(),result,Toast.LENGTH_SHORT).show();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public class MyTask extends AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... strings) {
String result="";
HttpURLConnection httpURLConnection=null;
URL url;
try {
url=new URL(strings[0]);
httpURLConnection=(HttpURLConnection) url.openConnection();
InputStream inputStream=httpURLConnection.getInputStream();
InputStreamReader reader=new InputStreamReader(inputStream);
result=getData(reader);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public String getData(InputStreamReader reader) throws IOException{
String result="";
int data=reader.read();
while (data!=-1){
char now=(char) data;
result+=data;
data=reader.read();
}
return result;
}
}
}
Sample AsyncTask example with progress
import android.animation.ObjectAnimator;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {
Button btn;
ProgressBar progressBar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.button1);
btn.setOnClickListener(this);
progressBar = (ProgressBar)findViewById(R.id.pbar);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.button1:
new LongOperation().execute("");
break;
}
}
private class LongOperation extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... params) {
Log.d("AsyncTask", "doInBackground");
for (int i = 0; i < 5; i++) {
try {
Log.d("AsyncTask", "task "+(i + 1));
publishProgress(i + 1);
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Completed";
}
#Override
protected void onPostExecute(String result) {
Log.d("AsyncTask", "onPostExecute");
TextView txt = (TextView) findViewById(R.id.output);
txt.setText(result);
progressBar.setProgress(0);
}
#Override
protected void onPreExecute() {
Log.d("AsyncTask", "onPreExecute");
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("onPreExecute");
progressBar.setMax(500);
progressBar.setProgress(0);
}
#Override
protected void onProgressUpdate(Integer... values) {
Log.d("AsyncTask", "onProgressUpdate "+values[0]);
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("onProgressUpdate "+values[0]);
ObjectAnimator animation = ObjectAnimator.ofInt(progressBar, "progress", 100 * values[0]);
animation.setDuration(1000);
animation.setInterpolator(new LinearInterpolator());
animation.start();
}
}
}
if you open AsyncTask class you can see below code.
public abstract class AsyncTask<Params, Progress, Result> {
#WorkerThread
protected abstract Result doInBackground(Params... params);
#MainThread
protected void onPreExecute() {
}
#SuppressWarnings({"UnusedDeclaration"})
#MainThread
protected void onPostExecute(Result result) {
}
}
AsyncTask features
AsyncTask is abstract class
AsyncTask is have 3 generic params.
AsyncTask has abstract method of doInBackground, onPreExecute, onPostExecute
doInBackground is WorkerThread (you can't update UI)
onPreExecute is MainThread
onPostExecute is MainThread (you can update UI)
example
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
AsyncTask<Void, Void, Post> asyncTask = new AsyncTask<Void, Void, Post>() {
#Override
protected Post doInBackground(Void... params) {
try {
ApiClient defaultClient = Configuration.getDefaultApiClient();
String authorization = "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1ODIxMzM4MTB9.bA3Byc_SuB6jzqUGAY4Pyt4oBNg0VfDRctZ8-PcPlYg"; // String | JWT token for Authorization
ApiKeyAuth Bearer = (ApiKeyAuth) defaultClient.getAuthentication("Bearer");
Bearer.setApiKey(authorization);
PostApi apiInstance = new PostApi();
String id = "1"; // String | id
Integer commentPage = 1; // Integer | Page number for Comment
Integer commentPer = 10; // Integer | Per page number For Comment
Post result;
try {
result = apiInstance.apiV1PostsIdGet(id, authorization, commentPage, commentPer);
} catch (ApiException e) {
e.printStackTrace();
result = new Post();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return new Post();
}
}
#Override
protected void onPostExecute(Post post) {
super.onPostExecute(post);
if (post != null) {
mEmailView.setText(post.getBody());
System.out.print(post);
}
}
};
asyncTask.execute();
}
Change your code as given below:
#Override
protected void onPostExecute(String result) {
runOnUiThread(new Runnable() {
public void run() {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed");
}
});
}