UI线程等待异步结果并根据结果进行操作

时间:2013-07-11 12:15:49

标签: android android-asynctask ui-thread

在我的android项目中,我试图调用一个返回字符串结果的Web服务。执行后,结果将使用onPostExecution()在UI线程中更新,结果将决定是转移到下一个活动还是通知用户更正信息。

以上是我打算通过以下代码实现:

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

但问题是当我尝试运行上面的代码时它停留在UI线程并且后台线程没有运行或者可能没有获得CPU时间来执行。 请告诉我如何完成这项工作。我需要保留活动并显示消息(出现错误)如果结果未成功注册,则屏幕将更改为下一个活动。

谢谢&问候,
Sourabh

6 个答案:

答案 0 :(得分:1)

在onPostExecute而不是Async任务中执行此操作,而不是在while循环后执行此操作。

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

删除导致UI被攻击的while循环。

答案 1 :(得分:0)

AsyncTask正是您要找的!有一个例子。如果您有任何疑问,请随时询问!

答案 2 :(得分:0)

您可以在任务的构造函数中放置一个回调来实现此目的。

伪代码:

创建如下所示的界面

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

在代码中的某处实现此接口:

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

在任务的构造函数中传递此回调并将其存储为局部变量mCallback;

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

在你的onPostExecute()方法中:

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

请注意,上述内容尚未经过测试,可能包含较小的语法错误。祝你好运。

答案 3 :(得分:0)

为什么不将你的代码用于onPostExecute(),如下所示:它肯定会起作用

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

答案 4 :(得分:0)

最好的方法是在不担心同步事物的情况下做广播接收器:

这是您在服务中发送广播的方式:

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

然后你会在活动中收到它,并用它做你想做的事情:

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

答案 5 :(得分:0)

您的问题是在while循环/后台结果组合中。我无法判断backgroundResult的来源是什么,但如果你使用(1)wait(2)get(3)或任何需要停止UI线程的东西,这就是你的问题所在。

Morten使用回调的解决方案正确。这需要与AsyncTask结合才能达到正确的结果。

(1)创建一个界面

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

(2)创建一个异步任务,在其构造函数中接受此接口。

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

}

这是任务的基本设置。您需要对其进行修改以使用您的活动。基本思想是,使用构造函数传递interace将允许您在完成背景部分后回调启动活动。这样,您可以评估起始活动/片段中的结果。

DownloadTask getStuff = new DownloadTask(new OnTaskDone(){

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

});
getStuff.execute(stringParams);