如何在android中重新进入活动后用asynctask更新进度条

时间:2012-05-02 05:08:07

标签: android android-asynctask

我正在尝试实现一些功能,如文件下载,下载启动按钮位于某些列表视图中。为了更清楚,这里用图表说明它。

首先,我在那里输入一些列表视图的Book1_Activity: [book_chapter_name_1 [download_1]] [book_chapter_name_2 [download_2]] 我点击了download_1按钮,下载开始,有一个进度条显示进度。下载是通过AsyncTask实现的。

之后,我想切换到其他一些活动,比如book_read_activity,这样我就可以下载一些书籍,同时继续阅读。

我的问题是在我读完这本书之后,当我想检查下载书籍的进度时,所以我重新进入Book1_Activity,因为Book1_Activity被销毁并重新创建,我怎样才能获得下载进度并更新它?

3 个答案:

答案 0 :(得分:0)

考虑使用服务而不是?然后你可以让它运行,即使关闭? 但是如果你想继续你的方法,我会把asynctask写入进程到全局访问点,然后从那里读取进度。

答案 1 :(得分:0)

这是我一直使用的东西。我不会谈论您的UI,列表框更新等。这只是Task和ProgressDialog处理:

ProgressDialog的样式:

<resources>
    <style name="MyProgressDialog" parent="@android:style/Theme.Dialog">
        <item name="android:background">@android:color/transparent</item>
        <item name="android:backgroundDimEnabled">false</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowFrame">@null</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
        <item name="android:windowTitleStyle">@null</item>
    </style>
</resources>

我的ProgressDialog课程:

public class MyProgressDialog extends Dialog {

    public MyProgressDialog(Context context) {
        super(context, R.style.MyProgressDialog);
    }

    public static MyProgressDialog show(Context context, CharSequence title, CharSequence message) {
        return show(context, title, message, false);
    }

    public static MyProgressDialog show(Context context, CharSequence title, CharSequence message, boolean indeterminate) {
        return show(context, title, message, indeterminate, false, null);
    }

    public static MyProgressDialog show(Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable) {
        return show(context, title, message, indeterminate, cancelable, null);
    }

    public static MyProgressDialog show(Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable, OnCancelListener onCancelListener) {
        MyProgressDialog dialog = new MyProgressDialog(context);
        dialog.setCancelable(cancelable);
        dialog.setOnCancelListener(onCancelListener);
        dialog.setTitle(title);

        dialog.addContentView(new ProgressBar(context), new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        dialog.show();

        return dialog;
    }
}

现在来了牛肉。带有AsyncTask作为内部类的ListView。 AsyncTask包含对周围ListActivity(上下文)的引用,ListActivity包含对AsyncTask的引用。 ProgressDialog将在常规启动时在AsyncTask中创建。如果ListActivity停止并且AsyncTask仍在运行,则对话框将从ListActivity中解除,并在重新启动后重新创建。

重要的是要注意谁在做什么:

public class MyListActivity extends ListActivity {

    private class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> {

        /* package */ MyListActivity   context;
        /* package */ MyProgressDialog dialog;

        public MyAsyncTask(MyListActivity context) {
            super();

            this.context = context;
        }

        @Override
        protected Boolean doInBackground(final Void... voids) {
            Boolean rc = false;

            // Put your running task here

            return rc;
        }

        @Override
        protected void onPostExecute(final Boolean result) {
            if (dialog != null) {
                try {
                    dialog.dismiss();
                } catch (Exception exception) {
                }

                dialog = null;
            }

            if (result) {
                // Whatever you need to update in UI
            }

            context.task = null;
        }

        @Override
        protected void onPreExecute () {
            dialog = MyProgressDialog.show(context, null, null, true, false);
        }
    }

    /* package */ MyAsyncTask task;

    // Save AsyncTask if running, dismiss ProgressDialog if open
    @Override
    public Object onRetainNonConfigurationInstance() {
        if (task != null) {
            if (task.dialog != null) {
                task.dialog.dismiss();
                task.dialog = null;
            }
        }

        return task;
    }

    @Override
    public void onCreate(final Bundle bundle) {

        // Usual start here

        // Was task running?
        task = (MyAsyncTask) getLastNonConfigurationInstance();
        if (task != null) {
            // Task was running, update context, restart ProgressDialog
            task.context = this;
            task.dialog = MyProgressDialog.show(this, null, null, true, false);
        } else {
            // Task was not running. Start from beginning
            task = new MyAsyncTask(this);
            task.execute();
        }
    }

答案 2 :(得分:0)

我必须在我的一个应用程序中执行相同的操作(使用API​​ 8)。我选择在通知栏中显示下载进度,并使用服务进行更新。工作得很好。

由于我开发了API 8的应用程序,因此我无法使用DownloadManager类,但您可能需要查看它。如果您的应用程序使用API​​ 9+,那么它似乎比自己重新编写流程更合适。