【问题标题】:AsyncTask block UI thread and show progressbar with delayAsyncTask 阻塞 UI 线程并延迟显示进度条
【发布时间】:2011-04-07 14:57:01
【问题描述】:

我的 AsyncTask 在下载图像时阻止了阻止按钮元素,并且进度对话框延迟显示 - 它会在图像显示之前显示一段时间,但下载需要很长时间并且按钮被阻止(橙色)并且未显示对话框。

 public  Bitmap download(String url, ProgressBar progressbar) throws InterruptedException, ExecutionException {
     BitmapDownloaderTask task = new BitmapDownloaderTask(progressbar);
     task.execute(url);
     return task.get();
}

class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {



    public BitmapDownloaderTask(ProgressBar progressbar) {

    }
    @Override
    protected void onPreExecute() {
        dialog = new ProgressDialog(ShowActivity.this);
        dialog.setMessage("Loading");
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.show();
    }

    @Override
    protected Bitmap doInBackground(String... Params) {
        return imageLoader.getBitmap(params[0]);

    }
    @Override
    protected void onPostExecute(Bitmap bitmap) {
         dialog.dismiss();


    }
}    

在按钮监听器中,只需调用下载函数,进度参数是因为我在imageview中有进度条圈-该对话框仅用于测试,以找出为什么会出现延迟和阻塞。在另一个应用程序中,我使用可运行且线程和元素未被阻止,但在教程中提到 AsyncTask 作为更好的解决方案。

【问题讨论】:

标签: android android-asynctask


【解决方案1】:

图片下载确实是在后台线程中执行的,但是使用 return task.get(); 你只是在等待它完成,这就是阻塞你的主线程的原因。

您应该使用onPostExecute() 作为任务完成时的回调,这样不仅可以关闭对话框,还可以使用doInBackground() 返回的位图执行您需要的操作。

【讨论】:

  • 非常感谢您的解释!
【解决方案2】:

因为你打电话给AsyncTask#get:

如有必要,等待计算完成,然后检索其结果。

你应该在onPostExecute()内执行任何你需要使用图像的操作

【讨论】:

  • 该描述,直接来自 Android 文档,可能更清楚一点,“等待”在技术意义上意味着“在调用线程中不会发生任何事情,例如 UI 更新。”
【解决方案3】:

老问题,但面临这个问题。 是的,AsyncTask.get 将阻塞 UI 线程,直到结果到达,不给对话框显示处理空间,我遇到了同样的问题,用更通用的解决方案解决。基本上,我使用接收 AsyncTaskData 的构造函数创建我的 AsyncTasks(AsyncTaskData 是我创建的一个类,如下所示),其中包含所有必要的数据和回调。我把我的课程和一个例子留给你。

AsyncTaskData.java

public class AsyncTaskData {

    private Context activityContext;
    private Object inputData; // whatever you want
    private AsyncTaskCallback callback;

    public AsyncTaskData(Context activityContext, Object inputData, AsyncTaskCallback callback) {
        this.activityContext = activityContext;
        this.inputData = inputData;
        this.callback = callback;
    }

    // getters and setters
}

AsyncTaskCallback.java

public interface AsyncTaskCallback {
    // method to be called when the task is finished (onPostExecute)
    void onAsyncTaskTerminated(Object result);
}

因此,例如,如果我有一个 AsyncTask 进行登录,它将声明如下:

public class LoginAsyncTask extends AsyncTask<Void, Void, Boolean> {

    private AsyncTaskData asyncTaskData;
    private ProgressDialog progressDialog;

    public LoginAsyncTask (AsyncTaskData asyncTaskData) {
        this.asyncTaskData = asyncTaskData;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        progressDialog = new ProgressDialog(asyncTaskData.getActivityContext(), R.style.AppTheme);
        progressDialog.show();
    }

    @Override
    protected Boolean doInBackground(Void... voids) {
        // if needed, get your data with asyncTaskData.getInputData()
        AuthenticationData authData = (AuthenticationData) asyncTaskData.getInputData();
        boolean loggedIn = // your heavy authentication process goes here
        return loggedIn;
    }

    @Override
    protected void onPostExecute(Boolean loggedIn) {
        super.onPostExecute(searchResponse);

        progressDialog.dismiss();

        if(asyncTaskData.getCallback() == null) return;

        asyncTaskData.getCallback().onAsyncTaskTerminated(loggedIn);
    }
}

最后,只需在 Fragment/Activity 中使用它:

AsyncTaskData asyncTaskData = new AsyncTaskData(
    getActivity(), // or this if you are calling from an Activity
    new AuthenticationData("username", "password"), 
    result -> {
        boolean loggedIn = (boolean) result;
        // your login logic goeas here
    });

new SearchAsyncTask(asyncTaskData)
    .execute();

经过很多方法,我最终使用了这个,因为它是通用的,保持代码干净并解决了调用 .get() 方法和阻塞 UI 线程的问题。 希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多