AsyncTask延迟程序流程/屏幕冻结

时间:2014-01-30 14:24:37

标签: android android-asynctask

我有一个简单的登录屏幕。如果单击“登录”,则在我们等待后台的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.";
            }
    }

3 个答案:

答案 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是最大项目数。