0

In my android project I am trying to call a web service which returns a string result. After execution, result will updated in UI thread using onPostExecution() and the result will decide whether to move to next activity or to notify user to correct information.

Above is my intention to achieve from below code :

 BackgroundTask bcktask = new BackgroundTask();
        bcktask.execute(servicemethodname, urlparameter, bMap);
    Thread.sleep(1000);
    //do nothing
    while (backgroundResult == null)
        ;

    if (backgroundResult == "Sucessfully Registered") {
        Intent intent = new Intent(this, VerifyDetail.class);
        startActivity(intent);
    } else {
        Toast.makeText(this, backgroundResult, Toast.LENGTH_LONG)
                .show();
    }

but problem is that when I try to run above code It stucks at UI thread and background thread is not running or perhaps not getting CPU time to execute. Please tell me how can I get this done. I need to hold the activity and show a message (what is wrong) if result is not Sucessfully Registered or screen will change to next activity.

Thanks & Regards,
Sourabh

user2376920
  • 242
  • 1
  • 7
  • 19

6 Answers6

1

Do this in onPostExecute instead of the Async task instead of doing it after a while loop.

 protected void onPostExecute(Long result) {
     if (backgroundResult == "Sucessfully Registered") {
        Intent intent = new Intent(this, VerifyDetail.class);
        startActivity(intent);
    } else {
        Toast.makeText(this, backgroundResult, Toast.LENGTH_LONG)
            .show();
    }
}

Remove the while loop which causes your UI to get struck.

user936414
  • 7,574
  • 3
  • 30
  • 29
  • how can I call onPostExecute(Long result) in UI thread. as much as I know it gets call automatically after doInBackground(String... params)? – user2376920 Jul 11 '13 at 13:29
  • and from background thread startActivity is not defined until it extends Activity which may lead to register activity in manifest file also and doing all this is logically wrong just to have a method working. – user2376920 Jul 11 '13 at 14:41
  • onPostExecute will be called automatically in the UI thread. only doInBackground will be in a non UI thread. If your async task class is not an inner class of your activity, then you can have a handler or a interface to communicate between the activity and the async task – user936414 Jul 11 '13 at 16:21
  • Thanks for your concern. I have done it by callback method. Anyway are you asking me to call onPostExecute() in place of execute(). will it automatically call doInBackgroud(), if yes how would it pass parameters. – user2376920 Jul 11 '13 at 17:50
0

The AsyncTask is what you are looking for! There is an example. Feel free to ask, if you have any questions!

malimo
  • 770
  • 6
  • 7
0

You can put a callback in the constructor of your task to achieve this.

Pseudo code:

Create an interface like the following

public interface MyCallback {
    public void onResult(String result);
}

Implement this interface somewhere in your code:

MyCallback callback = new MyCallback() {
    @Override
    public void onResult(String result) {
        if(result.equals("Sucessfully Registered") {
            // success
        } else {
            // not success
        }
    }
}

Pass this callback in the constructor of your task and store it as a local variable mCallback;

new BackgroundTask(callback).execute(...);

In your onPostExecute() method:

mCallback.onResult("<web service result String>");

Please note that the above has not been tested and might contain minor syntax errors. Good luck.

Morten Salte
  • 505
  • 5
  • 21
0

Why not to use your code into onPostExecute() like this:It will definitely work

    protected void onPostExecute(String (backgroundResult) {
        super.onPostExecute((backgroundResult);

        if(myProgressDialog!=null){
            myProgressDialog.dismiss();
            myProgressDialog = null;
        }

        if(backgroundResult != ""){
                if (backgroundResult == "Sucessfully Registered") {
                    Intent intent = new Intent(this, VerifyDetail.class);
                    startActivity(intent);
                } else {
                    Toast.makeText(this, backgroundResult, Toast.LENGTH_LONG).show();
                }
        }
    }
Div
  • 3
  • 2
  • I think it is not defined startActivity(intent) in asyncTask type. you can get context or intent from UI to Background somehow but I don't know how to use startActivity() form background. – user2376920 Jul 11 '13 at 14:36
0

the best way to do it without worrying about syncronizing things is a broadcast receiver:

this is how you send a broadcast in your service:

Intent intent = new Intent("YOUR_ACTION");
intent.putExtra("EXTRA", result);
sendBroadcast(intent);

then you receive it like that in the activity, and do what you want with it:

private BroadcastReceiver mEventReceiver = new BroadcastReceiver(){

    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equalsIgnoreCase("YOUR_ACTION") ){
            String yourExtra = intent.getStringExtra("EXTRA");
            // DO YOUR UI THING!!
        }
    }
};

IntentFilter eventsFilter = new IntentFilter();
eventsFilter.addAction("YOUR_ACTION");
registerReceiver(mEventReceiver, roundsEventsFilter);
Taldroid
  • 382
  • 1
  • 8
  • I tried to use broadcast in my project but I was unable to understand logically how it works and its flow. Can you please give me little detail. also when I try to use sendBroadcast(intent) in onPostExecute() it was asking for definition and not any suggestion. can you give me any tutorial for it. I think this should be a good way to check the background process status. – user2376920 Jul 11 '13 at 17:47
0

Your issue is in the while loop/background result combo. I cannot tell from what is provided where backgroundResult is coming from but if you are using either (1) wait (2) get (3) or anything that requires stopping the UI thread this is where your problem is.

Morten's solution of using a callback is on the right track. This needs to be combined with an AsyncTask to reach the right result.

(1) create an interface

public interface OnTaskDone {
    public void onResult(String resultString);
}

(2) create an async task that takes this interface in its constructor.

public class DownloadTask extends AsyncTask<String, Void, String>{

    private OnTaskDone listener = null;

    public DownloadTask(OnTaskDone listener){
        this.listener = listener;
    }

    @Override
    protected String doInBackground(String . . . params){
        //do your i/o stuff here
        return stringResult
    }

    @Override
    protected void onPostExecute(String result){
        listener.result(result);
    }

}

This is the basic set up of the task. You need modify it to work with your activity. The basic idea is that passing an interace in with the constructor will allow you to call back to the starting activity once the background portion is done. This way you can evaluate the result in your starting activity/fragment.

DownloadTask getStuff = new DownloadTask(new OnTaskDone(){

    @Override
    public void onResult(String resultString){
        //check result here and do whatever
    }

});
getStuff.execute(stringParams);
Rarw
  • 7,645
  • 3
  • 28
  • 46