0

我正在按照本教程 学习如何制作进度条。我试图在我的活动顶部显示进度条,并让它在后台更新活动的表格视图。

所以我为接受回调的对话框创建了一个异步任务:

package com.lib.bookworm;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;



public class UIThreadProgress extends AsyncTask<Void, Void, Void> {
    private UIThreadCallback callback = null;
    private ProgressDialog dialog = null;
    private int maxValue = 100, incAmount = 1;
    private Context context = null;
    
    public UIThreadProgress(Context context, UIThreadCallback callback) {
        this.context = context;
        this.callback = callback;
    }
    
    @Override
    protected Void doInBackground(Void... args) {
        while(this.callback.condition()) {
            this.callback.run();
            this.publishProgress();
        }
        return null;
    }
    
    @Override protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        dialog.incrementProgressBy(incAmount);
    };
    
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        
        dialog = new ProgressDialog(context);
        dialog.setCancelable(true);
        dialog.setMessage("Loading...");
        dialog.setProgress(0);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setMax(maxValue);
        dialog.show();
    }
    
    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        
        if (this.dialog.isShowing()) {
            this.dialog.dismiss();
        }
        this.callback.onThreadFinish();
    }
    
}

在我的活动中:

final String page = htmlPage.substring(start, end).trim();

//Create new instance of the AsyncTask..

new UIThreadProgress(this, new UIThreadCallback() {
    
    @Override
    public void run() {
        row_id = makeTableRow(row_id, layout, params, matcher); //ADD a row to the table layout.
    }
    
    @Override
    public void onThreadFinish() {
        System.out.println("FINISHED!!");                       
    }
    
    @Override
    public boolean condition() {
        return matcher.find();
    }
}).execute();

因此,上面创建了一个异步任务来运行以更新表格布局活动,同时显示显示已完成工作量的进度条。

但是,我收到一条错误消息,说只有启动活动的线程才能更新其视图。我尝试将异步任务的运行更改为以下内容:

MainActivity.this.runOnUiThread(new Runnable() {
    @Override public void run() {
        row_id = makeTableRow(row_id, layout, params, matcher); //ADD a row to the table layout.
    }
}

但这给了我同步错误。有什么想法可以显示进度并同时在后台更新我的表格吗?

目前我的用户界面看起来像:

在此处输入图像描述

4

2 回答 2

1

无论您在 UI 中进行什么更新,都在进行更新,用于Global Variables传递值或使用Getter Setter.

这是一个简单的例子,来自我当前的一个项目。它改变了作为进度条的 LinearLayout 的宽度,并且还使用X%. 我正在打电话更新onProgressUpdate

    public class Updater extends AsyncTask<Void, Void, Void> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        width = getWindowManager().getDefaultDisplay().getWidth();
        Log.wtf(tag, "width" + width);
    }

    @Override
    protected Void doInBackground(Void... params) {

        while (updated < sleep) {
            try {
                Thread.sleep(updateEveryXmillSec);
                updated = updated + updateEveryXmillSec;
                publishProgress();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        mTextView.setText((int) (100 * updated / sleep) + " %");
        xwidth = (width * ((int) (100 * updated / sleep)) / 100);
        mLayout.setLayoutParams(new RelativeLayout.LayoutParams(xwidth,
                height));
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);

        startActivity(new Intent(getApplicationContext(), Main.class));
        finish();

    }
}

调用new Updater().execute();触发动作。

于 2013-10-18T22:26:07.383 回答
0

您应该从行数据中拆分您的 UI 数据。创建一个包含要在表中显示的数据的 RowObject:

class RowData {
    String program;
    String course;
    String bookName;

    // get/set etc
}

您可以在 UIThreadProgress 类的 run 方法中填充此对象并将其推送到同步列表。

在 onProcessUpdate() 中,您可以基于同步列表构建视图对象并将其添加到视图层次结构中。您现在在 UI 线程上,应该可以添加。

在此期间,您必须关心同步列表。因为后台线程和 UI 线程会同时添加和删除对象。同步将在这里有所帮助。根据算法计算所需数据的速度,比同步列表更快的方法更好。但理念始终如一。您必须拆分数据和视图操作。

于 2013-10-18T22:02:55.930 回答