我有一个函数AppHelper.isOnline(Context context)
,我在我的应用程序的各个部分调用,以检查会话在发出HTTP请求之前没有超时。
public void onClick(View v) {
Intent intent = null;
switch (v.getId()) {
case R.id.buttonPagamenti:
if (AppHelper.isOnline(this))
{
//here AppHelper.isOnline should have finished it's async task
intent = new Intent(this, OrdineCreaActivity.class);
this.startActivityForResult(intent, R.id.buttonPagamenti);
}
break;
...
在AppHelper.isOnline()
内,我正在执行一个登录的AsyncTask
,从而发出一个网络请求,无法在UI上运行,否则我会收到异常。在使用if中的代码恢复之前,我需要等待它完成。我怎么能这样做?
问题是活动开始第一次,然后AsyncTask
执行,所以当活动期望有效的登录会话时,它会中断。
答案 0 :(得分:81)
您有两种选择:
使用AsyncTask
的方法get(long timeout, TimeUnit unit)
,就像那样:
task.get(1000, TimeUnit.MILLISECONDS);
这将使你的主线程等待AsyncTask
的结果最多1000毫秒(根据@ user1028741评论:实际上还有infinetly等待方法 - AsyncTask#get()
也可以做这项工作在某些情况下适合你。)
或者,您可以在异步任务中显示进度对话框,直到完成为止。请参阅此thread(我无需复制代码)。基本上,当异步任务运行时会显示进度对话框,并在完成时隐藏。
您甚至有第三种选择:“如果Thread
足以满足您的需求,您可以使用其join
方法。但是,如果任务需要很长时间,您仍需要显示进度对话框,否则你会得到一个异常,因为主线程处于非活动状态的时间太长了。
答案 1 :(得分:3)
尝试使用
if (AppHelper.isOnline(this))
{
while(!task.isCancelled()){
// waiting until finished protected String[] doInBackground(Void... params)
}
intent = new Intent(this, OrdineCreaActivity.class);
this.startActivityForResult(intent, R.id.buttonPagamenti);
}
有关详细信息,请参阅http://developer.android.com/reference/android/os/AsyncTask.html
答案 2 :(得分:1)
intent = new Intent(this, OrdineCreaActivity.class);
context.startActivityForResult(intent, R.id.buttonPagamenti);
在AsyncTask的onPostExecute()中写上面的行。因为如果我们使用AsyncTask,它将不会在那里等待任务完成。
答案 3 :(得分:1)
Rafiq的回复对我不起作用 - 应用程序挂了。我认为原因与isCancelled()的性质有关:“如果此任务在正常完成之前被取消,则返回true。”如果任务正常完成(即未取消),则while(!task.isCancelled()) { }
将永远循环。
要解决这个问题,请创建一个布尔标志,然后将其设置为false
,然后翻转到true
中的task.onPostExecute()
。然后在切换活动之前执行while(!flag) { }
。另外,如果你想给主线程一个'break'让AsyncTask进程加快一点,你可以试试这个:
while (!flag) {
try { Thread.sleep(100); }
catch (InterruptedException e) { e.printStackTrace(); }
}
这似乎对我有用。