【问题标题】:How to add progress bar to standalone Asynctask?如何将进度条添加到独立 Asynctask?
【发布时间】:2012-09-13 11:22:30
【问题描述】:

我有一个在自己的活动中的异步任务。我向它传递一个字符串值,它连接到我的 Web 服务并根据我传入的名称下载 Json 数据,返回 Json 结果集。效果很好。

我想在异步任务中添加一个进度微调器,但我不知道怎么做。我仔细阅读了这个和许多其他博客,并接近但尚未找到解决方案。看来我要么需要将异步任务与 Activity 类一起获取上下文,要么必须将上下文作为参数传递——但我需要输入参数是字符串。我已经阅读了构建一个可以保存字符串和上下文参数的对象的可能性,但是我对 Java 很陌生,不知道如何构建类似的东西,也没有找到一个很好的解释来说明如何这样做。因此,当我需要知道 X 时,经常会给出我需要的解释,然后说:“......然后你做 X 就是这样”。

我想要的只是一个在下载发生时旋转的旋转器。没有文字,没有对话,只有一个微调器。

【问题讨论】:

  • 您介意分享您尝试过的代码吗?
  • 我现在手头没有。我会在今晚发布。
  • 这是我的代码。这本身就是一项活动。显然不是。我发布了我的代码,并被告知我还​​有 -419 个字符。我该怎么做才能把它全部放进去?没那么长。
  • 我认为我们误解了您的问题。 ProgressBar 是一个必须添加到 Activity/Fragment 的 Android View Widget,这是 Android 中唯一处理 View 组件的组件。如果要在 AsyncTask 中显示 ProgressBar,则必须将其放在 Activity 中并将对 Activity/progressbar 的引用传递给 asynctask。
  • 我也得出了这个结论。我现在正在处理这里和博客其他地方提出的各种想法,看看我能做些什么。当我到达我的跋涉结束时,我会再次发布。

标签: android android-asynctask progress-bar


【解决方案1】:
class MyTask extends AsyncTask<Request, Void, Result> {

 protected ProgressDialog progressDialog;

        @Override
        protected void onPreExecute()
        {
            super.onPreExecute();               
            progressDialog = ProgressDialog.show(YourActivity.this, "", "", true, false);
        }

    @Override protected Boolean doInBackground(Request... params) {
        // do some work here 
            return true;
    }

    @Override protected void onPostExecute(Result res) {
        progressDialog.dismiss();
    }
}

【讨论】:

  • 这个解决方案似乎存在将上下文获取到 AsyncTask 的问题,至少就 Eclipse 告诉我的而言。我的是真正独立的,而不是另一个 Activity 类的一部分,即其中没有“onCreate”。因此,在我的情况下,命令“this”是无效的。我的整个课程都以“扩展 AsyncTask”开始并以它结束——没有其他内容。
【解决方案2】:

在初始化 AsyncTask 的 Activity 布局中添加一个 ProgressBar(这实际上是它的名称,Spinner 就像 Android 中的下拉菜单)。

然后制作两个函数startProgress()stopProgress(),分别启动和停止进度条。

通过在初始化或执行期间发送它,或者在您的 asyncTask setActivity(MyActivity activity) 中创建一个函数并在您的 AsyncTask 初始化和执行之间调用它,为您的 AsyncTask 提供对 Activity 的引用。

覆盖 AsyncTask 的 onPreExecute() 以调用 activity.startProgress()onPostExecute() 以调用 activity.stopProgress()

编辑:您还可以尝试在 AsyncTask 的构造函数中传递对 ProgressBar 的引用。在活动的onCreate() 方法中获取对 ProgressBar 的引用,然后将其添加到 AsyncTask 构造函数中。在 AsyncTask 的 onPreExecute()onPostExecute() 方法中,相应地启动和停止进度条。

【讨论】:

  • 如上所述,鉴于我的 AsyncTask 的独立性质,setActivity 会在单独的线程中工作,实际上,在类中工作吗?我的整个难题是获得上下文,如果没有 Activity 类(如果我理解正确的话)。
  • Vinay,您意识到我不应该将 AsyncTask 单独运行,从而触及了问题的核心。我修改了代码以将 Activity 类与 AsyncTask 一起放入,并传递了该上下文。由于对 Java 如此陌生,我不确定我是否使用了关于活动、类等的正确术语,但这是有效的,并且教会了我仅将 AsyncTask 与 Activity 一起使用。谢谢!
  • 没问题,很高兴我能帮上忙.. :-)
【解决方案3】:

您可以将各种参数传递给AsyncTask,而不仅仅是一个!

一种方法是在 AsyncTask 中创建成员变量,并使用接受参数的构造函数对其进行初始化。 例如:

private class MyAsyncTask extends AsyncTask<null, null, null> {
String mFirstParam = null;
Context mContext = null;
// Constructor which accepts parameters
public MyAsyncTask(String _firstParam, Context _context){
 this.mFirstParam = _firstParam;
 this.mContext = _context;
 }
}

当您创建AsyncTask 的实例时,按如下方式创建它:

MyAsyncTask task = new MyAsyncTask(myFirstStringParam, mySecondContextParam);
task.execute();

现在您可以在AsyncTask 的整个范围内使用这两个参数。

在完成下载数据后,考虑传递包含“正在加载”图像的ImageView 并将其可见性设置为View.GONE

即在doInBackground 方法中下载您的数据,然后在onPostExecute 方法中将ImageViews 可见性更改为View.GONE

【讨论】:

  • 这个解决方案很有趣。今晚我会试一试,看看我能做些什么。
【解决方案4】:

我认为您可以在 AsyncTask 的构造函数中创建进度条实例时将其传递给它。这是一个使用 AsyncTask 的下载器示例 -

public void downloadFile(String url, String path, ProgressDialog progress) {

    DownloadFileAsync downloader = new DownloadFileAsync(progress);

    File file = new File(path);

    if (file.exists()) {
        file.delete();
    }

    downloader.execute(url, path);
}

class DownloadFileAsync extends AsyncTask<String, String, String> {

    private final WeakReference<ProgressDialog> progressbarReference;

    public DownloadFileAsync(ProgressDialog progress) {
        progressbarReference = new WeakReference<ProgressDialog>(progress);
    }

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

    @Override
    protected String doInBackground(String... aurl) {
        int count;

        try {

            URL url = new URL(aurl[0]);
            URLConnection conexion = url.openConnection();
            conexion.connect();

            int lenghtOfFile = conexion.getContentLength();

            /*
             * android.util.Log.v("downloadFile", "Lenght of file: " +
             * lenghtOfFile + ":" + aurl[1]);
             */
            InputStream input = new BufferedInputStream(url.openStream());
            OutputStream output = new FileOutputStream(aurl[1]);

            try {
                byte data[] = new byte[1024];

                long total = 0;

                while ((count = input.read(data)) != -1) {
                    total += count;
                    publishProgress(""
                            + (int) ((total * 100) / lenghtOfFile));
                    output.write(data, 0, count);
                }

            } finally {

                if (output != null) {
                    output.flush();
                    output.close();
                }

                if (input != null) {

                    input.close();
                }
            }
        } catch (Exception e) {

            ProgressDialog p = null;

            if (progressbarReference != null) {
                p = progressbarReference.get();
            }

            if (p != null && p.isShowing()) {
                p.dismiss();
            }
        }
        return null;

    }

    protected void onProgressUpdate(String... progress) {
        if (progressbarReference != null) {
            ProgressDialog p = progressbarReference.get();

            if (p != null) {
                p.setProgress(Integer.parseInt(progress[0]));
            }
        }
    }

    @Override
    protected void onPostExecute(String unused) {

        ProgressDialog p = null;

        if (progressbarReference != null) {
            p = progressbarReference.get();
        }

        if (p != null && p.isShowing()) {
            p.dismiss();
        }

    }
}

ProgressDialog 是一个自定义对话框,里面有一个进度条。 希望对您有所帮助。

【讨论】:

  • 这个解决方案似乎有可能,但我需要的是从 AsyncTask 返回一个结果集到主线程。现在我可以用“new GetData.execute(string).get();”来做到这一点命令。如果我在上述活动中与 AsyncTask 合作,那么我的主线程中会返回什么调用?我还没有弄清楚 Java 中返回数据的所有调用技术(我在自学)。
  • 我不知道你在你的 AsyncTask 类上做了什么,但我认为你可以稍微修改你的 AsyncTask,只需要修改你的类构造函数并在其中添加一些变量成员,这样你就可以传递进度栏到你的 AsyncTask,在课堂上,你可以做你想做的事。例如,首先您设置一个进度微调器(可能使用对话框),然后在 AsyncTask 中您可以关闭对话框。你不需要复制我在这里发送的所有代码。
猜你喜欢
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多