Android AsyncTask Parameters - android

I'm having trouble understanding the use of the parameters for Asynctask in android.
The Android Developers documentation explains it as follows:
AsyncTask must be subclassed to be used.
The subclass will override at least one method (doInBackground(Params...)),
and most often will override a second one (onPostExecute(Result).)
Here is an example of subclassing:
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");
}
}
Once created, a task is executed very simply:
new DownloadFilesTask().execute(url1, url2, url3);
For my extension of AsyncTask, I don't need to pass in any parameters, but I need to override the doInBackground(), onProgressUpdate(), and onPostExecute(). Why do I have to insert Void,Void,Void into AsyncTask<>?
What do the parameters do?

From the documentation it says using Void simply marks the type as unused. You don't have to have a type in AsyncTask.
The three types used by an asynchronous task are the following:
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> { ... }

Well Async task parameters are simple,
First param : Array of object or single object which needed for background process.
Second param : Object type you are going to pass into to the onProgressUpdate
Third Param : The return type of doInBackground
example :-
private class ImageDownloader extends AsyncTask<Void, Void, Void> {//todo}
ImageDownloader downloader = new ImageDownloader();
downloader.execute();

You insert void void void if you have no need for the parameters. For example when the async task is done and in onPostExecute you just want to update the view and it isn't reliant on the result doInBackground you can put Void as the 3rd parameter.
I think it is preferred practice to use parameters however instead of holding variables in either the async task or instance variables if the async task is a private inner class.

Related

How to update Activity's variable during AsyncTask?

I'm trying to update a variable from AsyncTask, but I'm not exactly sure how. This is what I tried:
Outside the AsyncTask is the activity class that has a variable..:
int myVariable = 0;
MyTask hi = new MyTask ();
hi.execute();
System.out.print(myVariable);
class MyTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... args0) {
myVariable = 3;
return null;
}
}
Still prints out 0 :(
When i print out the variable, it still says 0, and not 3. I'm using AsynTask for something more complicated, but this is the dumbed down version of what I'm trying to accomplish.
You should print your variable inside the doInBackground() or the onProgressUpdate() method. Since the doInBackground() method does not run on the UI-Thread it is highly likely that the print-statement gets executed before the variable is incremented.
Like this: (assuming that "myVariable" is of type Integer, and this AsyncTask is an inner class of your Activity)
class MyTask extends AsyncTask<Void, Integer, Void> {
protected Void doInBackground(Void... args0) {
for(int i = 0; i < 100; i++) {
myVariable++;
// like this:
Log.i("Variable", "" + myVariable);
// or like this:
publishProgress(myVariable);
}
return null;
}
protected Void onProgressUpdate(Integer... prog) {
Log.i("Variable", "" + prog[0]);
}
}
Plese be aware that the for-loop I am using is just an example, you could do anything there and then update your variable and publish it. Also be aware that I changed the "Progress" type to Integer:
AsyncTask<Void, Integer, Void>
The AsyncTask main three methods are onPreExecute, doInBackground, onPostExecute.
The method onPreExecute of AsyncTask is mainly used for showing a loading/processing dialog so that until the process is completed the user interaction with the UI is disabled.
The method doInBackground of AsyncTask is mainly used for doing the background calculations or calling a web service.
The method onPostExecute of AsyncTask is mainly used for showing the output of the doInBackground method and it can be used for performing actions on the UI.
#CynthiaDDurazo: So, in your case you should use onPostExecute method to put your code System.out.println(myVariable);

What is the difference of asyntask parameter in android?

Well as my question says, i refer to http://developer.android.com/reference/android/os/AsyncTask.html
It tells me
Asyntask <params, progress, result>
but i did not use progress. and is it state according to your arrangement? or it has a rule?
FOr example:
class loadingdata extends AsyncTask<?,?,?>
protected void onPreExecute() {}
protected String doInBackground(String... args) {}
protected void onPostExecute() {}
so should I insert the 3 parameter as
asyntask <void String void> ?
or it has a rule of
<preExecute, postExecute, doInBackground> or so fourth?
please help me with this, I am a beginner to this and i dont understand it.
An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
AsyncTask's generic types :
The three types used by an asynchronous task are the following:
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> { ... }
AsyncTask and implements 4 methods:
1. doInBackground: Code performing long running operation goes in this method. When onClick method isexecuted on click of button, it calls execute method which accepts parameters and automatically calls
doInBackground method with the parameters passed.
2. onPostExecute: This method is called after doInBackground method completes processing. Result from doInBackground is passed to this method.
3. onPreExecute: This method is called before doInBackground method is called.
4. onProgressUpdate: This method is invoked by calling publishProgress anytime from doInBackground call this method.
Overriding onPostExecute, onPreExecute and onProgressUpdate is optional.
Points to remember:
1. Instance of Async Task needs to be created in UI thread. As shown in onClick method a new instance of LongOperation is created there. Also execute method with parameters should be called from UI thread.
2. Methods onPostExecute, onPreExecute and onProgressUpdate should not be explicitly called.
3. Task can be executed only once.
Let us look at a sample class LongOperation, which extends the AsyncTask below: view source print?
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// perform long running operation operation
return null;
}
/* (non-Javadoc)
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
}
/* (non-Javadoc)
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
// Things to be done before execution of long running operation.
//For example showing ProgessDialog
}
/* (non-Javadoc)
* #see android.os.AsyncTask#onProgressUpdate(Progress[])
*/
#Override
protected void onProgressUpdate(Void... values) {
/* Things to be done while execution of long running operation
is in progress.
For example updating ProgessDialog */
}
}
If you don't need one or more of the AsyncTask parameters then use Void (note the capital V so it is Void and not void).
In the signature of AsyncTask<params, progress, result>, the first is the type of an array passed to doInBackground(), the second is the type of an array used when calling publishProgress() which calls onProgressUpdate() and the third is the data type returned by doInBackdround() and passed to onPostExecute().
For example...
private class MyAsyncTask extends AsyncTask<String, Integer, Boolean>
...would mean the method signatures would be...
doInBackground(String... params)
onProgressUpdate(Integer... progress)
onPostExecute(Boolean result)
Since AsyncTask has generic parameters, you must provide all of them. If you don't use any of them, then the type you provide doesn't really matter.
The Types are Generic so u can use any of the class or primitive type. When you want execute The statement in AsyncTasks use it by making a instance of it and then call execute() for that instance.
goto: http://mysecretishelloworld.blogspot.in/2013/04/asynctask-usage-guide.html
for more detail use of AsyncTask.
http://developer.android.com/reference/android/os/AsyncTask.html
AsyncTask's generic types
The three types used by an asynchronous task are the following:
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 { ... }
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");
}
}
URL parameter for doInBackground(URL... urls)
You call publishProgress((int)somevalue) in doinBackground() to update progress.
Integer parameter for onProgressUpdate(Integer... progress)
Long (result) parameter for onPostExecute(). The result is received from doInBackground().
Usage
new DownloadFilesTask().execute(url1, url2, url3);

How can you pass multiple primitive parameters to AsyncTask?

There are related questions, such as How can I pass in 2 parameters to a AsyncTask class? , but I ran into the difficulty of trying in vain to pass multiple primitives as parameters to an AsyncTask, so I want to share what I discovered. This subtlety is not captured in the existing questions and answers, so I want to help out anyone who runs into the same problem as I did and save them the pain.
The question is this: I have multiple primitive parameters (e.g. two longs) that I want to pass to an AsyncTask to be executed in the background--how can it be done? (My answer...after struggling with this for awhile...can be found below.)
Just wrap your primitives in a simple container and pass that as a parameter to AsyncTask, like this:
private static class MyTaskParams {
int foo;
long bar;
double arple;
MyTaskParams(int foo, long bar, double arple) {
this.foo = foo;
this.bar = bar;
this.arple = arple;
}
}
private class MyTask extends AsyncTask<MyTaskParams, Void, Void> {
#Override
protected void doInBackground(MyTaskParams... params) {
int foo = params[0].foo;
long bar = params[0].bar;
double arple = params[0].arple;
...
}
}
Call it like this:
MyTaskParams params = new MyTaskParams(foo, bar, arple);
MyTask myTask = new MyTask();
myTask.execute(params);
Another way: You just need add MyTask constructor in your MyTask class:
private class MyTask extends AsyncTask<String, Void, Void> {
int foo;
long bar;
double arple;
MyTask(int foo, long bar, double arple) {
// list all the parameters like in normal class define
this.foo = foo;
this.bar = bar;
this.arple = arple;
}
...... // Here is doInBackground etc. as you did before
}
Then call
new MyTask(int foo, long bar, double arple).execute();
A second way like David Wasser's Answer.
It is (strictly-speaking) NOT possible to pass multiple primitives to AsyncTask. For example, if you want to perform myTask.execute(long1, long2) and try to set up private class myTask extends AsyncTask<long, Void, Void> with the corresponding method:
#Override
protected LocationItemizedOverlay doInBackground(long... params) {...}
your IDE will likely complain about needing to override a supertype method. Note that you are using the so-called Varargs method signature for doInBackground, where (long... params) is like saying "I accept a variable number of longs, stored as an array called params. I don't completely understand what causes a compiler/IDE complaint to be raised, but I think it has to do with how the generic class Params is defined.
In any case, it is possible to achieve what you want with no problem, provided you correctly cast your primitives to their respective non-primitive wrappers (e.g. int => Integer, long => Long, etc.). Actually, you don't need to explicitly cast your primitives to non-primitives. Java seems to handle that for you. You just need to set up your ASyncTask as follows (for the example of longs):
private class MyTask extends AsyncTask<Long, Void, Void> {
#Override
protected void doInBackground(Long... params) {
// Do stuff with params, for example:
long myFirstParam = params[0]
}
...
}
You can then use this class as you originally intended, e.g.:
MyTask myTask = new MyTask();
myTask.execute(long1, long2);
Or for any number of primitives that you would like, PROVIDED THEY ARE OF THE SAME TYPE. If you need to pass multiple types of primitives, this can also be done, but you will need to modify the above to:
private class MyTask extends AsyncTask<Object, Void, Void> {
#Override
protected void doInBackground(Object... params) {
// Do stuff with params, for example:
long myLongParam = (Long) params[0];
int myIntParam = (Integer) params[1];
}
...
}
This is more flexible, but it requires explicitly casting the parameters to their respective types. If this flexibility is not needed (i.e. a single data type), I recommend sticking to the first option, as it's slightly more readable.
The built in execute method accepts an array of Params, but they all must be of the defined type.. so if you simply set the PARAM type to OBJECT, then you can pass in whatever you like as long as they are children of objects....
private class MyTask extends AsyncTask<Object, Void, Void> {
Then in your doInBackGround, you simply cast each param in order back to what you need it to be:
#Override
protected void doInBackground(Object... params) {
Context t = (Context)params[0];
String a = (String) params[1];
List<LatLng> list = (List<LatLng>)params[2];
.
.
.
And your execute is simply:
new MyTask().execute(context,somestring,list_of_points);
Not as good form as wrapping it in your own wrapper class, or a bundle, or hash or something, because you are order dependent on both sides, but it will work. Of course you could just make your array a param of HashMap(,) and you basically are custom implementing a bundle at that point, but it will work.
I like malajisi's method, but if you didn't, couldn't you use the Bundle class?
Bundle myBundle = new Bundle();
myBundle.putInt("foo", foo);
myBundle.putLong("bar", bar);
myBundle.putDouble("arple", arple);
Then just pass the bundle and unpack it inside MyTask. Is this a terrible idea? You avoid creating a custom class, and it's flexible if you decide you need to pass additional parameters later.
Update: It has been quite a few years since I wrote this answer, and I really dislike it now. I would recommend against using a Bundle. If you need to pass multiple parameters into an asynctask (or anything, really), use a custom class that holds all your parameters at once. Using a bundle is a fine solution to a problem you shouldn't have. There is no law against creating a custom class to hold exactly what you need, and nothing else.
Also, why aren't you using coroutines? Asynctasks are so 2014.
This is solved via subclassing.
Google has an example for solving this problem (subclassing) in the official Android AsyncTask Documentation:
http://developer.android.com/reference/android/os/AsyncTask.html
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");
}
}

How to pass variables in and out of AsyncTasks?

I haven't spent much time working with AsyncTasks in Android. I'm trying to understand how to pass variables to and from the class. The syntax:
class MyTask extends AsyncTask<String, Void, Bitmap>{
// Your Async code will be here
}
it's a little bit confusing with the < > syntax on the end of the class definition. Never seen that type of syntax before. It seems like I'm limited to only passing one value into the AsyncTask. Am I incorrect in assuming this? If I have more to pass, how do I do that?
Also, how do I return values from the AsyncTask?
It's a class and when you want to use it you call new MyTask().execute() but the actual method you use in the class is doInBackground(). So where do you actually return something?
Note: all of the information below is available on the Android Developers AsyncTask reference page. The Usage header has an example. Also take a look at the Painless Threading Android Developers Blog Entry.
Take a look at the source code for AsynTask.
The funny < > notation lets you customize your Async task. The brackets are used to help implement generics in Java.
There are 3 important parts of a task you can customize:
The type of the parameters passed in - any number you want
The type for what you use to update the progress bar / indicator
The type for what you return once done with the background task
And remember, that any of the above may be interfaces. This is how you can pass in multiple types on the same call!
You place the types of these 3 things in the angle brackets:
<Params, Progress, Result>
So if you are going to pass in URLs and use Integers to update progress and return a Boolean indicating success you would write:
public MyClass extends AsyncTask<URL, Integer, Boolean> {
In this case, if you are downloading Bitmaps for example, you would be handling what you do with the Bitmaps in the background. You could also just return a HashMap of Bitmaps if you wanted. Also remember the member variables you use are not restricted, so don't feel too tied down by params, progress, and result.
To launch an AsyncTask instantiate it, and then execute it either sequentially or in parallel. In the execution is where you pass in your variables. You can pass in more than one.
Note that you do not call doInBackground() directly. This is because doing so would break the magic of the AsyncTask, which is that doInBackground() is done in a background thread. Calling it directly as is, would make it run in the UI thread. So, instead you should use a form of execute(). The job of execute() is to kick off the doInBackground() in a background thread and not the UI thread.
Working with our example from above.
...
myBgTask = new MyClass();
myBgTask.execute(url1, url2, url3, url4);
...
onPostExecute will fire when all the tasks from execute are done.
myBgTask1 = new MyClass().execute(url1, url2);
myBgTask2 = new MyClass().execute(urlThis, urlThat);
Notice how you can pass multiple parameters to execute() which passes the multiple parameter on to doInBackground(). This is through the use of varargs (you know like String.format(...). Many examples only show the extraction of the first params by using params[0], but you should make sure you get all the params. If you are passing in URLs this would be (taken from the AsynTask example, there are multiple ways to do this):
// This method is not called directly.
// It is fired through the use of execute()
// It returns the third type in the brackets <...>
// and it is passed the first type in the brackets <...>
// and it can use the second type in the brackets <...> to track progress
protected Long doInBackground(URL... urls)
{
int count = urls.length;
long totalSize = 0;
// This will download stuff from each URL passed in
for (int i = 0; i < count; i++)
{
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
// This will return once when all the URLs for this AsyncTask instance
// have been downloaded
return totalSize;
}
If you are going to be doing multiple bg tasks, then you want to consider that the above myBgTask1 and myBgTask2 calls will be made in sequence. This is great if one call depends on the other, but if the calls are independent - for example you are downloading multiple images, and you don't care which ones arrive first - then you can make the myBgTask1 and myBgTask2 calls in parallel with the THREAD_POOL_EXECUTOR:
myBgTask1 = new MyClass().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url1, url2);
myBgTask2 = new MyClass().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, urlThis, urlThat);
Note:
Example
Here is an example AsyncTask that can take as many types as you want on the same execute() command. The restriction is that each type must implement the same interface:
public class BackgroundTask extends AsyncTask<BackgroundTodo, Void, Void>
{
public static interface BackgroundTodo
{
public void run();
}
#Override
protected Void doInBackground(BackgroundTodo... todos)
{
for (BackgroundTodo backgroundTodo : todos)
{
backgroundTodo.run();
// This logging is just for fun, to see that they really are different types
Log.d("BG_TASKS", "Bg task done on type: " + backgroundTodo.getClass().toString());
}
return null;
}
}
Now you can do:
new BackgroundTask().execute(this1, that1, other1);
Where each of those objects is a different type! (which implements the same interface)
I recognize that this is a late answer, but here's what I've been doing for the last while.
When I'm needing to pass in a bunch of data to an AsyncTask, I can either create my own class, pass that in and then access it's properties, like this:
public class MyAsyncTask extends AsyncTask<MyClass, Void, Boolean> {
#Override
protected Boolean doInBackground(MyClass... params) {
// Do blah blah with param1 and param2
MyClass myClass = params[0];
String param1 = myClass.getParam1();
String param2 = myClass.getParam2();
return null;
}
}
and then access it like this:
AsyncTask asyncTask = new MyAsyncTask().execute(new MyClass());
or I can add a constructor to my AsyncTask class, like this:
public class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {
private String param1;
private String param2;
public MyAsyncTask(String param1, String param2) {
this.param1 = param1;
this.param2 = param2;
}
#Override
protected Boolean doInBackground(Void... params) {
// Do blah blah with param1 and param2
return null;
}
}
and then access it like this:
AsyncTask asyncTask = new MyAsyncTask("String1", "String2").execute();
Hope this helps!
Since you can pass array of objects in the square bracket, that is the best way to pass data based on which you want to do processing in the background.
You could pass the reference of your activity or the view in the Constructor and use that to pass data back into your activity
class DownloadFilesTask extends AsyncTask<URL, Integer, List> {
private static final String TAG = null;
private MainActivity mActivity;
public DownloadFilesTask(MainActivity activity) {
mActivity = activity;
mActivity.setProgressBarIndeterminateVisibility(true);
}
protected List doInBackground(URL... url) {
List output = Downloader.downloadFile(url[0]);
return output;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
private void setProgressPercent(final Integer integer) {
mActivity.setProgress(100*integer);
}
protected void onPostExecute(List output) {
mActivity.mDetailsFragment.setDataList((ArrayList<Item>) output);
//you could do other processing here
}
}
Alternatively, you could just use a regular thread and usea handler to send data back to the ui thread by overriding the handlemessage function.
Passing a simple String:
public static void someMethod{
String [] variableString= {"hello"};
new MyTask().execute(variableString);
}
static class MyTask extends AsyncTask<String, Integer, String> {
// This is run in a background thread
#Override
protected String doInBackground(String... params) {
// get the string from params, which is an array
final String variableString = params[0];
Log.e("BACKGROUND", "authtoken: " + variableString);
return null;
}
}

Android: How can I pass parameters to AsyncTask's onPreExecute()?

I use an AsyncTask for loading operations that I implemented as an inner class.
In onPreExecute() I show a loading dialog which I then hide again in onPostExecute(). But for some of the loading operations I know in advance that they will finish very quickly so I don't want to display the loading dialog.
I wanted to indicate this by a boolean parameter that I could pass to onPreExecute() but apparently for some reason onPreExecute() doesn't take any parameters.
The obvious workaround would probably be to create a member field in my AsyncTask or in the outer class which I would have to set before every loading operation but that does not seem very elegant. Is there a better way to do this?
You can override the constructor. Something like:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
public MyAsyncTask(boolean showLoading) {
super();
// do stuff
}
// doInBackground() et al.
}
Then, when calling the task, do something like:
new MyAsyncTask(true).execute(maybe_other_params);
Edit: this is more useful than creating member variables because it simplifies the task invocation. Compare the code above with:
MyAsyncTask task = new MyAsyncTask();
task.showLoading = false;
task.execute();
1) For me that's the most simple way passing parameters to async task
is like this
// To call the async task do it like this
Boolean[] myTaskParams = { true, true, true };
myAsyncTask = new myAsyncTask ().execute(myTaskParams);
Declare and use the async task like here
private class myAsyncTask extends AsyncTask<Boolean, Void, Void> {
#Override
protected Void doInBackground(Boolean...pParams)
{
Boolean param1, param2, param3;
//
param1=pParams[0];
param2=pParams[1];
param3=pParams[2];
....
}
2) Passing methods to async-task
In order to avoid coding the async-Task infrastructure (thread, messagenhandler, ...) multiple times you might consider to pass the methods which should be executed in your async-task as a parameter. Following example outlines this approach.
In addition you might have the need to subclass the async-task to pass initialization parameters in the constructor.
/* Generic Async Task */
interface MyGenericMethod {
int execute(String param);
}
protected class testtask extends AsyncTask<MyGenericMethod, Void, Void>
{
public String mParam; // member variable to parameterize the function
#Override
protected Void doInBackground(MyGenericMethod... params) {
// do something here
params[0].execute("Myparameter");
return null;
}
}
// to start the asynctask do something like that
public void startAsyncTask()
{
//
AsyncTask<MyGenericMethod, Void, Void> mytest = new testtask().execute(new MyGenericMethod() {
public int execute(String param) {
//body
return 1;
}
});
}
why, how and which parameters are passed to Asynctask<>, see detail here. I think it is the best explanation.
Google's Android Documentation Says that :
An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
AsyncTask's generic types :
The three types used by an asynchronous task are the following:
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> { ... }
You Can further refer : http://developer.android.com/reference/android/os/AsyncTask.html
Or You Can clear whats the role of AsyncTask by refering Sankar-Ganesh's Blog
Well The structure of a typical AsyncTask class goes like :
private class MyTask extends AsyncTask<X, Y, Z>
protected void onPreExecute(){
}
This method is executed before starting the new Thread. There is no input/output values, so just initialize variables or whatever you think you need to do.
protected Z doInBackground(X...x){
}
The most important method in the AsyncTask class. You have to place here all the stuff you want to do in the background, in a different thread from the main one. Here we have as an input value an array of objects from the type “X” (Do you see in the header? We have “...extends AsyncTask” These are the TYPES of the input parameters) and returns an object from the type “Z”.
protected void onProgressUpdate(Y y){
}
This method is called using the method publishProgress(y) and it is usually used when you want to show any progress or information in the main screen, like a progress bar showing the progress of the operation you are doing in the background.
protected void onPostExecute(Z z){
}
This method is called after the operation in the background is done. As an input parameter you will receive the output parameter of the doInBackground method.
What about the X, Y and Z types?
As you can deduce from the above structure:
X – The type of the input variables value you want to set to the background process. This can be an array of objects.
Y – The type of the objects you are going to enter in the onProgressUpdate method.
Z – The type of the result from the operations you have done in the background process.
How do we call this task from an outside class? Just with the following two lines:
MyTask myTask = new MyTask();
myTask.execute(x);
Where x is the input parameter of the type X.
Once we have our task running, we can find out its status from “outside”. Using the “getStatus()” method.
myTask.getStatus();
and we can receive the following status:
RUNNING - Indicates that the task is running.
PENDING - Indicates that the task has not been executed yet.
FINISHED - Indicates that onPostExecute(Z) has finished.
Hints about using AsyncTask
Do not call the methods onPreExecute, doInBackground and onPostExecute manually. This is automatically done by the system.
You cannot call an AsyncTask inside another AsyncTask or Thread. The call of the method execute must be done in the UI Thread.
The method onPostExecute is executed in the UI Thread (here you can call another AsyncTask!).
The input parameters of the task can be an Object array, this way you can put whatever objects and types you want.
You can either pass the parameter in the task constructor or when you call execute:
AsyncTask<Object, Void, MyTaskResult>
The first parameter (Object) is passed in doInBackground.
The third parameter (MyTaskResult) is returned by doInBackground. You can change them to the types you want. The three dots mean that zero or more objects (or an array of them) may be passed as the argument(s).
public class MyActivity extends AppCompatActivity {
TextView textView1;
TextView textView2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
textView1 = (TextView) findViewById(R.id.textView1);
textView2 = (TextView) findViewById(R.id.textView2);
String input1 = "test";
boolean input2 = true;
int input3 = 100;
long input4 = 100000000;
new MyTask(input3, input4).execute(input1, input2);
}
private class MyTaskResult {
String text1;
String text2;
}
private class MyTask extends AsyncTask<Object, Void, MyTaskResult> {
private String val1;
private boolean val2;
private int val3;
private long val4;
public MyTask(int in3, long in4) {
this.val3 = in3;
this.val4 = in4;
// Do something ...
}
protected void onPreExecute() {
// Do something ...
}
#Override
protected MyTaskResult doInBackground(Object... params) {
MyTaskResult res = new MyTaskResult();
val1 = (String) params[0];
val2 = (boolean) params[1];
//Do some lengthy operation
res.text1 = RunProc1(val1);
res.text2 = RunProc2(val2);
return res;
}
#Override
protected void onPostExecute(MyTaskResult res) {
textView1.setText(res.text1);
textView2.setText(res.text2);
}
}
}

Categories

Resources