4

I've been working on an app and I've managed to get the AsyncTask to work fine when it's in an inner class.

Now, I am refactoring the code so that the AsyncTask is in a separate class of its own, but I am wondering, how do I kill the ProgressDialog and start a new Activity once the task is completed successfully? I've tried starting a new Activity in the onPostExecute(..) method, but I know that won't work.


Passing my UI thread activity as an argument in the constructor for the AsyncTask did not seem to work:

//In UI Thread I had
public class Test101 extends Activity {
    private Button btnLogin;
    private LoginTask mLoginTask;
    private Context context=this;
    private Test101 mTest101;

    mLoginTask=new LoginTask(context,mTest101);
    mLoginTask.execute(null);

    // In the AsyncTask I had
    Activity mParentActivity;

    public LoginTask(Context context,Activity act){
        this.ctx=context;
        this.mParentActivity=act;
    }

    onPostExecute(..){
        mParentActivity.callSomeMethod();
    }

    ...
}

I kept getting a NullPointerException, maybe I'm missing something but that didn't work for me.

Can
  • 8,502
  • 48
  • 57
jwesonga
  • 4,249
  • 16
  • 56
  • 83
  • Made a good amount of progress, this what I have so far, in the onPostExecute(String result) method I dismissed the progressDialog, now I'm trying to pass the result of the AsyncTask back to the Activity in the UI thread. Haven't figured out that part yet: @Override protected void onPostExecute(String result) { pDialog.dismiss(); //pass result of AsyncTask back to Activity in UI thread???? } – jwesonga Mar 04 '10 at 17:36

6 Answers6

7

Instead of passing 2 parameters pass only one like this:

public class Test101 extends Activity {
    private Button btnLogin;
    private LoginTask mLoginTask;

    mLoginTask=new LoginTask(this);
    mLoginTask.execute(); 
    //Instead of sending null put the 1st parameter of the AsyncTask as Void

AsyncTask Code:

  Activity mParentActivity;

public LoginTask(Activity act){
    this = act;
}

onPostExecute(..){
    ((Test101)mParentActivity).callSomeMethod();
}
dakshbhatt21
  • 3,558
  • 3
  • 31
  • 40
neteinstein
  • 17,529
  • 11
  • 93
  • 123
  • @NeTeInStEiN: Is passing the `Activity` as a parameter prefer to passing it as a `Context`, like `public LoginTask(Context context){...}`? – ChuongPham Dec 07 '14 at 15:05
  • No. You should pass the Application Context to avoid leaks. But if you need a callback, you need to pass the reference to it. – neteinstein Dec 09 '14 at 10:55
6

All one needs to start a new Activity is the context object that you pass in the constructor of the AsyncTask:

private Context ctx;
private ProgressDialog pDialog;
private String r="";

public LoginTask(Context context){
    super();
    this.ctx=context;
}

@Override
protected void onPostExecute(String result) {
    Log.i("LOGGER", "Done...");
    pDialog.dismiss();
    Intent i=new Intent(ctx,SillyActivity.class);
    ctx.startActivity(i);
}

If you pass the activity within the constructor in the AsyncTask and try to call startActivity(Intent intent) you will always get a null pointer exception.

Can
  • 8,502
  • 48
  • 57
jwesonga
  • 4,249
  • 16
  • 56
  • 83
1
step 1 : create your master class and declare 

mNetworkMaster.runForgetAsync();

step 2: write another class for AsyncTask

package com.example.xxx;

import java.util.HashMap;
import java.util.Map;

import android.app.Activity;
import android.os.AsyncTask;

public class NetworkMaster {

    Activity mMasterActivity;
    LoadingDialog objLoadingDialog;
    Map<String, String> serverUrls = new HashMap<String,String>();


    // create a constructor
    public NetworkMaster(Activity mMasterActivity){

        this.mMasterActivity = mMasterActivity;     

    }// end constr NetworkMaster


    // Method to run the Async task
    public void runForgetAsync(){

        new ForgetPasswordAsync().execute();

    }// end runForgetAsync


    // dynamically call the thread
    public class ForgetPasswordAsync extends AsyncTask<String, String, String> {

        @Override
        protected void onPreExecute(){ 
            super.onPreExecute();

        }

        protected String doInBackground(String... urls) {

            serverUrls = Ipsum.getServerUrls();     

            int response = HttpRequest.post().send("name=xxxx").code();

            return ""+response;
        }

        protected void onPostExecute(String result) {

            // return the result to master activity
            ((Login)mMasterActivity).ForgetPassword(result);            

        }

    }// end ForgetPasswordAsync

}// end NetworkMaster
Vinod Joshi
  • 7,696
  • 1
  • 50
  • 51
0

Use Android Annotations for AsyncTask easy, fast, simple!

Pierry
  • 979
  • 7
  • 17
0

mTest101 isn't initiated. It is just null... So you can see only null pointer exception and that's the ordinary thing. Or you can make static method to work fine without initiating class.

0

pass the Activity as a constructor parameter to your AsyncTask and keep it in a field. this is effectively what being an inner class was getting you (only the compiler would write the code for you).

Elliott Hughes
  • 4,595
  • 2
  • 23
  • 21
  • I modified my AsyncTask constructor to: public LoginTask(Context context,Activity ax){ super(); this.ctx=context; this.mActivity=ax; } and then in onPostExecute() i tried start a new activity: mActivity.startActivity(i); I got a null pointer exception – jwesonga Mar 08 '10 at 09:49