Android UI线程等待异步结果并根据结果进行操作
在我的android项目中,我试图调用一个返回字符串结果的web服务。执行后,结果将在UI线程中使用onPostExecution()进行更新,结果将决定是移动到下一个活动还是通知用户更正信息 以上是我从以下代码实现的意图: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);
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);