我有一个简单的登录屏幕。如果单击“登录”,则在我们等待后台的AsyncTask检查登录凭据时,应显示进度条。
如果我在后台运行没有AsyncTask的代码,我的进度条会立即显示。但是,如果我使用AsyncTask(我在之后设置),我会显示进度条,应用程序会在我点击“登录”的时候冻结。然后等待,直到AsyncTask得到结果(get()
命令),然后才解冻,使我的进度条无用。
这是一个众所周知的问题吗?你是如何解决的?
这是我设置AsyncTask的地方,之后我显示进度条。
showProgress(true, "Logging in ...");
mAuthTask = new InternetConnection();
String arguments = "email="+mEmail+"&pwd="+mPassword;
boolean k = mAuthTask.makeConnection("ADDRESS", arguments, getBaseContext());
String f = mAuthTask.getResult();
这是我的AsyncTask。 downloadUrl()
设置HttpURLConnection
。这是有效的,我测试了它。
private DownloadData data = new DownloadData();
public boolean makeConnection(String url, String arguments, Context context) {
if(isWifi(context) || isMobile(context)) {
argsString = arguments;
data.execute(url);
return true;
} else {
return false; //No network available.
}
}
public String getResult() {
try {
return data.get();
} catch (InterruptedException e) {
return "Error while retrieving data.";
} catch (ExecutionException e) {
return "Error while retrieving data.";
}
}
private class DownloadData extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... url) {
try {
return downloadUrl(url[0]);
} catch (IOException e) {
return "Unable to retrieve data.";
}
}
答案 0 :(得分:2)
你不应该调用get()
它阻止ui等待返回结果,使asynctask不再异步。
你有
private DownloadData data = new DownloadData();
你有
data.get(); // this why it freezes
和
private class DownloadData extends AsyncTask<String, Void, String>
http://developer.android.com/reference/android/os/AsyncTask.html#get()
你只需要
data.execute(url);
如果您的asynctask是活动类的内部类,您可以在doInbackground
返回结果并在onPostExecute
中更新ui。如果不是,您可以使用interface作为活动的回调来返回结果。
答案 1 :(得分:2)
您的问题与您从UI线程调用getResult
这一事实有关。 getResult
调用data.get()
这是一个阻止操作。这就是你冻结的原因。您的UI Thread
正在等待get()
完成,而且无法绘制其他所有内容
答案 2 :(得分:2)
这样做:
@Override
protected void onPreExecute() {
Asycdialog.setMessage("Working");
Asycdialog.getWindow().setGravity(Gravity.CENTER_VERTICAL);
Asycdialog.getWindow().setGravity(Gravity.CENTER_HORIZONTAL);
Asycdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
Asycdialog.setCancelable(false);
//Dialog Show
Asycdialog.show();
super.onPreExecute();
然后在onPostExecute:
protected void onPostExecute(String result) {
// hide the dialog
Asycdialog.dismiss();
super.onPostExecute(result);
}
要使用来自不同类的相同Async任务:
class MainActivity{
new MyTask().execute();
}
class DifferentActivity {
new MyTask().execute();//a new instance
}
class MyTask extends AsyncTask{
public MyTask(Context context){
}//Pass in context.
}
如果需要一致的“进度”对话框,请将上下文传递给构造函数。
要从doInBackground发布进度,您可以使用以下内容:
publishProgress(progress);
Asycdialog.setMax(lines);
Asycdialog.incrementProgressBy(1);
如果progress是一个字符串,则lines是最大项目数。