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();

したがって、上記は、実行された作業量を示す進行状況バーを表示しながら、テーブル レイアウト アクティビティを更新するために実行する非同期タスクを作成します。

ただし、アクティビティを開始したスレッドのみがそのビューを更新できるというエラーが表示されます。Async Task の実行を次のように変更してみました。

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

しかし、これにより同期エラーが発生します.進行状況を表示し、同時にバックグラウンドでテーブルを更新する方法はありますか?

現在、私のUIは次のようになっています:

ここに画像の説明を入力

4

2 に答える 2

1

UIで行っている更新は、進行中の更新で行い、Global Variables値を渡すために使用するか、を使用しますGetter Setter

これは、私の現在のプロジェクトの 1 つからの簡単な例です。プログレスバーとして機能し、textview を更新する 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 に答える