Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/196.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android UI线程等待异步结果并根据结果进行操作_Android_Android Asynctask_Ui Thread - Fatal编程技术网

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

Android UI线程等待异步结果并根据结果进行操作,android,android-asynctask,ui-thread,Android,Android Asynctask,Ui Thread,在我的android项目中,我试图调用一个返回字符串结果的web服务。执行后,结果将在UI线程中使用onPostExecution()进行更新,结果将决定是移动到下一个活动还是通知用户更正信息 以上是我从以下代码实现的意图: BackgroundTask bcktask = new BackgroundTask(); bcktask.execute(servicemethodname, urlparameter, bMap); Thread.sleep(1000);

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

以上是我从以下代码实现的意图:

 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时间来执行。 请告诉我怎样才能完成这件事。如果结果未成功注册,我需要保留活动并显示一条消息(有什么问题),否则屏幕将切换到下一个活动

谢谢和问候,

苏拉布

这就是你要找的!有一个例子。如果您有任何问题,请随时提问

在onPostExecute中执行此操作,而不是异步任务,而不是在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();
    }
}

删除导致用户界面被击中的while循环。

您可以在任务的构造函数中放置回调来实现这一点

伪代码:

创建一个如下所示的接口

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(“”);

请注意,以上内容尚未测试,可能包含一些小的语法错误。祝你好运。

为什么不像这样在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();
                }
        }
    }

不必担心同步的最好方法是使用广播接收器:

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

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

您的问题在while循环/后台结果组合中。我无法从所提供的内容判断backgroundResult来自何处,但如果您使用(1)等待(2)获取(3)或任何需要停止UI线程的操作,这就是您的问题所在

莫顿使用回调的解决方案是正确的。这需要与
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);
    }

}

while循环是故意的吗?我如何在UI线程中调用onPostExecute(长结果)。据我所知,在doInBackground(字符串…参数)之后,它会自动得到调用?从后台线程开始,直到扩展活动(可能导致在清单文件中也注册活动)时,才定义startActivity,并且仅为了让方法正常工作,这样做在逻辑上是错误的。onPostExecute将在UI线程中自动调用。只有doInBackground将位于非UI线程中。如果异步任务类不是活动的内部类,那么您可以使用处理程序或接口在活动和异步任务之间进行通信。我已经通过回调方法完成了。不管怎样,您是要我调用onPostExecute()来代替execute()。它是否会自动调用doinBackground(),如果是,它将如何传递参数。我认为它没有在asyncTask类型中定义startActivity(intent)。您可以通过某种方式从UI到后台获取上下文或意图,但我不知道如何从后台使用startActivity()。谢谢您的回答!但我在问如何完成我要求的上述任务。我试图在我的项目中使用广播,但我无法从逻辑上理解它是如何工作的及其流程的。你能告诉我一些细节吗。另外,当我尝试在onPostExecute()中使用sendBroadcast(intent)时,它要求的是定义,而不是任何建议。你能给我一些指导吗。我认为这应该是检查后台进程状态的好方法。
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);
    }

}
DownloadTask getStuff = new DownloadTask(new OnTaskDone(){

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

});
getStuff.execute(stringParams);