I have implemented the 2 asyn tasks, I am using android4.0. where one asyntask is executed continuously, second one is executed based on requirement(may be mulitpe times).
For example.
class AsynTask1 exetends AsyncTask<Void, Bitmap, Void>{
protected Void doInBackground(Void... params) {
while(true){
publishProgress(bmp);
}
}
}
class AsynTask2 extends AsyncTask<String, Void,Void>{
protected Void doInBackground(String... params){
System.out.println(params[0])
}
}
In activity class
class MainActivity extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new AsynTask1().execute();
int i=0;
while(i<100)
{
if(i%2==0)
new AsynTask2().execute("no is even"+i);
i++
}
}
}
In the above case the AsynTask2 is not executed .
If tried with executeOnExecutor(AsyncTask.THREAD_POOL_Executor,params), then both asyntask are executed and I am getting the print messages from the AsynTask2, but those are not in order(like 0 2 6 4 10 8 12 14 ....).
Is there any way to execute the AsynTask1 continuously and AsynTask2 in Sequential order so that the order(like 0 2 4 6 8 10 12 14....) is prevented.
Thanks & Regards
mini.
Use SERIAL_EXECUTOR for Asynctask2
new AsynTask2().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR ,"no is even"+i)
Edit:
Use for Asynctask1 , so that same executor is not used
new AsynTask1().executeOnExecutor(AsyncTask.THREAD_POOL_Executor,params);
You are not supposed to use AsyncTask for long-running threads (the way you are implementing AsyncTask1). See the documentation: http://developer.android.com/reference/android/os/AsyncTask.html . Just create a separate thread for what AsyncTask1 is doing.
Since you need serial execution for what you are doing in AsyncTask2 can be done by creating a ThreadPool of size 1.
// Creating ThreadPool
ExecutorService service = Executors.newFixedThreadPool(1);
// Submitting task
service.execute(task);
// Shutting down the thread pool when not required.
service.shutdown();
Try using call backs. Define the interfaces in your AsyncTask classes and implement them in the main class. Use the callBack on onPostExecute of AsyncTask2 to launch the next AsyncTask2. You'll guarantee the order.
class AsyncTask2 extends AsyncTask<String, Void,Boolean<{
//Your code. doInBackground must now return a boolean.
protected Void onPostExecute(final Boolean success){
myCallback listener = (myCallback) parentActivity;
listener.call();
}
public Interface myCallback{
void call();
}
}
And then on your main activity you implement myCallback.
[EDIT]
Here's a sample of what you could do.
Class MainActivity extends Activity implements myCallback{
//Your code
public void call(){
new AsyncTask2().execute("no is even" + i);
}
}
int i=0;
while(i<100)
{
new AsynTask1().execute();
if(i%2==0)
{
new AsynTask2().execute("no is even"+i);
}
i++
}
Related
I'm running httpsCommand (shown below, via clientTask() from MainActivity) and downloading about 1KB of data from a webserver. I plan to update a ListView in MainActivity (I think that's possible, but I recall it being a bit annoying last time I did it) with the downloaded data inside myListAllDoneListener(). I'd like to run this in a loop every 5 minutes to check for new data.
I've tried running new myCLientTask().execute()... inside a while loop (using Thread.sleep and try/catch) but it only seemed to run one loop and crashed after 15 seconds or so. Found a similar question but it's not quite answered. How can I background this data download?
// ** MainActivity.java **
public class MainActivity extends AppCompatActivity
{
...
#Override
protected void onCreate(Bundle savedInstanceState)
{
new clientTask(getApplicationContext(), myListAllDoneListener, ...);
...
private AsyncTaskCompleteListener myListAllDoneListener = new AsyncTaskCompleteListener()
{
#Override
public void onComplete(ArrayList<String> data, String msg, int statuscode)
{
// update listview with new data
...
//** clientTask.java **
public class clientTask extends Activity
{
ArrayList<String> mData;
...
public clientTask (Context ctx, AsyncTaskCompleteListener ... String cmd, ...)
{
...
new myClientTask().execute();
...
private class myClientTask extends AsyncTask<Object, Object, Object>
{
...
protected Object doInBackground (Object... params)
{
mData = httpsCommand (mCmd);
...
You can't use Thread.sleep in activity. It will block your UI. To run a periodic task
Look this stackoverflow answer using Handlers.
Also, there are some things wrong with your code. You shouldn't create object of an Activity class and use it for such things.
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);
I have 3 activities A,B,C. In all the 3 activities i'm using Async task. Is it possible to run all the Async task under a single Async task(Common code).
If possible
1. How to check which task called from which activity?
2. How to check whether the task got completed or not?
May be you want to have a Common async task for that can used to perform long running taks and you want a callback machanism to it use this,
You can implement the same by taking async task class a separate abstract and by implementing a callback interface.
Async Class with callback
Yes it is possible.
Add a Parameter that is used to indicate the calling Activity
Look at JavaDoc of AsyncTask method onPostExecute()
Create your AsyncTask class
public class MyTask extends AsyncTask<Void, Void, Void>
{
// Use a WeakReference instead of holding the Activity object
private WeakReference<Activity> mActivity;
public MyTask(Activity activity)
{
mActivity = new WeakReference<Activity>(activity);
}
#Override
protected Void doInBackground(Void... params)
{
// do common work
return null;
}
public Activity getActivity()
{
return mActivity.get();
}
public void setActivity(Activity activity)
{
mActivity = new WeakReference<Activity>(activity);
}
}
And in each Activity:
MyTask t = new MyTask(YourActivity.this)
{
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
// do some work when finished
}
};
I have to load XML data in my app, I'm doing that in a subclass of my activity class extending AsyncTask like this :
public class MyActivity extends Activity {
ArrayList<Offre> listOffres;
private class DownloadXML extends AsyncTask<Void, Void,Void>
{
protected Void doInBackground(Void... params)
{
listOffres = ContainerData.getFeeds();
return null;
}
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_liste_offres);
DownloadXML.execute(); // Problem here !
for(Offre offre : listOffres) { // etc }
}
}
I don't know how to use execute() here, I have the following error :
Cannot make a static reference to the non-static method execute(Integer...)
from the type AsyncTask
I guess some parameters but what ?
Thank you.
You need to create an instance of your DonwloadXML file and call execute() on that method:
DownloadXML task=new DownloadXML();
task.execute();
EDIT: you should probably also return the listOffers from your doInBackground() and process the array in the onPostExecute() method of your AsynTask. You can have a look at this simple AsyncTask tutorial.
you should call it like:
new DownloadXML().execute();
Actually you are calling the method of AsyncTask (which further extends the AsyncTask class) without making an OBJECT of that class.
you can call the execute method in two ways.
make an object/instance of the class like
DownloadXML task=new DownloadXML();
task.execute();
by using an flying object.
new DownloadXML().execute();
I prefer to use here 2nd method to do that.
Well if you want to execute some code by async task in java you can also do this:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
// add code which you want to run in background thread
runOnUiThread(new Runnable() {
#Override
public void run() {
// add code which you want to run in main(UI) thread
}
});
}
});
And in kotlin if you are using anko, there is much more simpler way to acheive this:
doAsync {
// add code which you want to run in background thread
uiThread {
// add code which you want to run in main(UI) thread
}
}
u can execute ur asynctask either
new DownloadXML().execute();
or
DownloadXML task=new DownloadXML();
task.execute();
and one more thing u are getting in array in asynctask than it is good to use postexeceute method for ur for loop iteration
as given below
protected void onPostExecute(String s) {
for(Offre offre : listOffres) { // do ur work here after feeling array }
}
You have to create object of DownloadXML class first.
DownloadXML downloadxml= new DownloadXML();
downloadxml.execute();
and return listOffres.
listOffres = ContainerData.getFeeds();
return listOffers;
I am developing an application in which i need to send the value of the asynctask's onPostExecute method's result in to the previous activity , ie the activity in which the aync task is being called.pls put some codes. Anyhelp is appreciated
Two ways:
Declare class extending AsyncTask as private class in parent Activity
Pass Handler or Activity itself as param of class extending AsyncTask
If I were you, I'd follow the first option.
Look at DOCS:
class MyActivitySubclass extends Activity {
function runOnPostExecute(){
// whatever
}
private class MyTask extends AsyncTask<Void, Void, Void> {
void doInBackground(Void... params){
// do your background stuff
}
void onPostExecute(Void... result){
runOnPostExecute();
}
}
}
Note 1
Code placed in body of function onPostExecute is already run on Activity thread, you should just mention that this keywords leads to MyTask.this and not MyActivitySubclass.this
Well if your AsyncTask is an inner class, you could simply call a method in your activity from onPostExecute():
public class MyActivity extends Activity {
public void someMethod(String someParam) {
// do something with string here
}
public class InnerTask extends AsyncTask<...> {
protected void onPostExecute(result) {
someMethod(Send parameters);
}
}
}
The onPostExecute method is fired on the main UI thread, so anything done there is already on the AsyncTasks caller.
http://developer.android.com/reference/android/os/AsyncTask.html
Fire an event in the OnPostExecute.
Its an add on to the answer by Marek Sebera, he pointed to use a handler. To keep the code simple and intuitive use an interface. This isn't alien concept, we use it all the time for callback functions (eg: OnClickListner etc..). The code would look some thing like this.
public class InnerTask extends AsyncTask<...>
{
interface ResultHandler
{
void gotResult(<> result);
}
private ResultHandler myResult;
//constructor
public InnerTask(....params...,ResultHandler callback)
{
...
this.myResult = callback;
}
protected void onPostExecute(<>result)
{
...
myResult.gotResult(result);
}
}
public class MyActivity extends Activity implements InnerTask.ResultHandler
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
//do something
//if you want the InnerTask to execute here
InnerTask i = new InnerTask(....params...,this); //send 'this' as parameter
i.execute();
}
#Override
public void gotResult(<> result)
{
//from onPostExecute
}
}
If we want to use the same AsynTask class at multiple sites we can use this type of implementation instead of using nested classes implementation.