Android 异步任务延迟程序流/屏幕冻结
我有一个简单的登录屏幕。如果单击“登录”,在后台等待AsyncTask检查登录凭据时,将出现一个进度条 如果在后台运行代码时没有AsyncTask,我的进度条会立即出现。但是,如果我使用AsyncTask,我在进度条出现后设置了AsyncTask,那么应用程序会在我单击“登录”时冻结。然后,它等待AsyncTask得到结果(Android 异步任务延迟程序流/屏幕冻结,android,android-asynctask,Android,Android Asynctask,我有一个简单的登录屏幕。如果单击“登录”,在后台等待AsyncTask检查登录凭据时,将出现一个进度条 如果在后台运行代码时没有AsyncTask,我的进度条会立即出现。但是,如果我使用AsyncTask,我在进度条出现后设置了AsyncTask,那么应用程序会在我单击“登录”时冻结。然后,它等待AsyncTask得到结果(get()命令),然后才解冻,使我的进度条无用 这是一个众所周知的问题吗?你怎么解决这个问题 这就是我在显示进度条后设置AsyncTask的方式 showProgre
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();
这是我的任务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.";
}
}
private DownloadData data=new DownloadData();
公共布尔makeConnection(字符串url、字符串参数、上下文){
如果(iWiFi(上下文)| | iMobile(上下文)){
argsString=参数;
数据执行(url);
返回true;
}否则{
返回false;//没有可用的网络。
}
}
公共字符串getResult(){
试一试{
返回data.get();
}捕捉(中断异常e){
返回“检索数据时出错。”;
}捕获(执行例外){
返回“检索数据时出错。”;
}
}
私有类下载数据扩展异步任务{
@凌驾
受保护的字符串doInBackground(字符串…url){
试一试{
返回下载url(url[0]);
}捕获(IOE异常){
返回“无法检索数据。”;
}
}
您不应该调用get()
它会阻塞等待返回结果的ui,从而使asynctask不再是异步的
你有
private DownloadData data = new DownloadData();
你有
data.get(); // this why it freezes
及
如果您的asynctask是activity类的内部类,您可以在
doInbackground
中返回结果,并在onPostExecute
中更新ui。否则,您可以使用接口作为对activity的回调来返回结果。您不应该调用get()
它阻止ui等待返回结果,从而使asynctask不再异步
你有
private DownloadData data = new DownloadData();
你有
data.get(); // this why it freezes
及
如果您的asynctask是activity类的内部类,您可以在
doInbackground
中返回结果,并在onPostExecute
中更新ui。否则,您可以使用接口作为对activity的回调来返回结果。您的问题与您正在从ui线程调用getResult
有关。>getResult
调用data.get()
这是一个阻塞操作。这就是为什么您会被冻结。您的UI线程
正在等待get()
完成,它无法绘制所有其他内容您的问题与您正在从UI线程调用getResult
有关。getResult
调用data.get()
这是一个阻塞操作。这就是您被冻结的原因。您的UI线程正在等待get()
完成,无法绘制其他所有内容按如下方式操作:
@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);
}
要使用来自不同类的同一异步任务,请执行以下操作:
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);
如果进度是一个字符串,则行是项目的最大数量。按如下方式操作:
@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);
}
要使用来自不同类的同一异步任务,请执行以下操作:
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);
当进度是字符串时,行是最大项数。在onPreExecute()中启动进度对话框,在onPostExecute中关闭它,这将100%起作用在onPreExecute()中启动进度对话框,在onPostExecute中关闭它,这将100%起作用。然而,我的目标是将AsyncTask外包到另一个类中(InternetConnection),以避免被迫在我的应用程序中复制该AsyncTask Internet代码。这是可能的,还是我必须将该代码放在我使用该任务的每个类中?这是可能的,只要确保您使用的是“上下文”在您的异步任务中,不要乱说。您也可以使用onProgressUpdate在所述对话框中更新进度。异步任务是保持代码整洁并在具体流程中工作的最佳方法。但是我如何从InternetConnection中调用showProgress?super.onPostExecute(result)有什么功能精确调用?后台执行过程完成后,根据您选择的返回类型,相同的返回将传递给onPostExecute().super.onPostExecute(结果)是从doInBackground获得的结果,结果参数是可选的。这取决于是否从doInBackground返回任何内容。好的,如果我理解正确,我可以调用MyTask.execute()和MyTask.get()在我的主要活动中没有冻结它?不幸的是,我仍然不知道如何在onPreExecute()中使用showProgress函数。然而,我的目标是将AsyncTask外包到另一个类(InternetConnection)中,以避免被迫将AsyncTask Internet代码复制到我的应用程序中。这是可能的,还是我必须将该代码放在我使用任务的每个类中?这是可能的,只要确保您使用的是“上下文”在异步任务中,不要乱说。您也可以使用onProgressUpdate在上述对话框中更新进度。异步任务是保持代码整洁并在具体流程中工作的最佳方法。但是