Question

In my acivity, i need to run two background service.

main background service:

class loadingTask extends AsyncTask<Void, Void,Void> {

      @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        pd = ProgressDialog.show(context, "", "Chargement en cours..", true, false);
        super.onPreExecute();
    }


    @Override
    protected void onPostExecute(Void result) {
         // TODO Auto-generated method stub
        super.onPostExecute(result);
        pd.dismiss();
    }

    ...

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub
        getxml = Util.CallWebService("");
        return null;
    }
}

Second background service.

class mloadingTask extends AsyncTask<String, Void, String> {

    protected String doInBackground(String... urls) {

        SAXHelper sh = null;
        try {
            sh = new SAXHelper(urls[0]);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        sh.parseContent("");
        return "";

    }

    protected void onPostExecute(String s) {
        pd.dismiss();

    }
}

In my onCreate() method I want to call the first background and when it finished loading the second background service starts. Part of my background service is as follows.

AsyncTask<Void, Void,Void> loadTask = new loadingTask().execute();

    if(loadTask.getStatus()==AsyncTask.Status.FINISHED){

         new mloadingTask().execute(getxml);

         System.out.println("getxml: "+getxml);
    }

However the second background service doesn't seem to start. i am not getting the a print also. I think I miss a step or android doesn't allow more than one background service in the same activity. A help please.

Was it helpful?

Solution

AsyncTask<Void, Void,Void> loadTask = new loadingTask().execute();

if(loadTask.getStatus()==AsyncTask.Status.FINISHED){

  new mloadingTask().execute(getxml);

  System.out.println("getxml: "+getxml);
}

there is a 99% chance that the if() block will never pass. You first execute the first asyncTask named loadTask and RIGHT after check if it finished. Small chance that it actually finishes by then.

The easy approach:

Use only one async task. You want to finish asyncTask 1 and then fire asyncTask 2, its exactly the same as having only one asyncTask doing both operations.

class loadingTask extends AsyncTask<Void, Void,Void> {

      @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        pd = ProgressDialog.show(context, "", "Chargement en cours..", true, false);
        super.onPreExecute();
    }


    @Override
    protected void onPostExecute(Void result) {
         // TODO Auto-generated method stub
        super.onPostExecute(result);
        pd.dismiss();
    }

    ...

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub
        getxml = Util.CallWebService("");

        SAXHelper sh = null;
        try {
            sh = new SAXHelper(urls[0]);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        sh.parseContent("");
        return null;
    }
}

The difficult approach:

How I solve this kind of thing is(our situation is different, but it should do)

Create an interface, with one method. for example:

public interface OnDataChangedListner {
    void dataChanged(Class listener);
}

Then somewhere (i use my repository classes) write a method to add and remove entires to a list of OnDataChangedListener interfaces

private ArrayList<OnDataChangedListner> mOnDataChangedListners;

public void addOnDataChangedListner(OnDataChangedListner onDataChangedListner){
    synchronized (mOnDataChangedListners){
        mOnDataChangedListners.add(onDataChangedListner);
    }
}

public void removeOnDataChangedListner(OnDataChangedListner onyDataChangedListner){
    if (mOnDataChangedListners != null){
        synchronized (mOnDataChangedListners){
            for (Iterator<OnDataChangedListner> it = mOnDataChangedListners.iterator(); it.hasNext();) {
                OnDataChangedListner listener = it.next();
                if (listener .equals(onDataChangedListner))
                    it.remove();
            }
        }
    }
}

This might be overkill. But this example should help you with updating the UI while your tasks are running. A free extra! :))

With the above code in place, create an onDataChanged() method in the same class where u defined the add and remove listener methods.

In that code call a handler

// Need handler for callbacks to the UI thread
final static Handler mHandler = new Handler();

// Create runnable for posting
final Runnable mNotifyDataChanged = new Runnable() {
    public void run() {
        if (mOnDataChangedListners != null){
            synchronized (mOnDataChangedListners){
                for (Iterator<OnDataChangedListner> it = mOnDataChangedListners.iterator(); it.hasNext();) {
                    OnDataChangedListner listener = it.next();
                    if (listener  != null)
                        listener.dataChanged(this.getClass());
                    else
                        it.remove();
                }
            }
        }
    }
};

/**
 * will notify registerred delegates on the main (UI) thread
 */
public void notifyDataChanged(){
    mHandler.post(mNotifyDataChanged);
}

Ok, so I ended up giving out an entire sample. Where you place this code is upto you. But when you call notifyDataChanged() it will fire the handler, which in turn will loop trough all current registered listeners for this class

then in turn it will call the listeners datachanged method.

To make this all work, all you have to do is have a class implement the interface

call addOnDataChangedListener(this);

and implement the method provided in the interface.

Note that this is deffinetly not the easiest way to do things. I don't know what the easiest way to do what you want is. I never have been in that situation before.

but you can execute the second task in the implemented method. Should work..

OTHER TIPS

AsyncTask is Asynchronous as its name suggest. You need to call your 2nd AsyncTask in onPostExecute of your 1st AsyncTask

OR

Loop and wait till AsyncTask is finished in your activity, but it may take more time and you can get Application Not Responding message.

As soon as you call execute() method, control comes to next statement which loadTask.getStatus(). As task is just started, loadTask.getStatus() will not return FINISH and your 2nd task is never getting executed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top