Question

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

Was it helpful?

Solution 2

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.

OTHER TIPS

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.

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

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();
                }
        }
    }

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);

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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top