6

ActionBarSherlockの進行状況の実装を更新するAsyncTaskがあります。どういうわけか、onProgressUpdateはUIスレッドで実行すると主張していますが、スレッドエラーをスローしています。

protected void onProgressUpdate(Integer... values)
{
    setSupportProgress(values[0]);
}

エラーは次のとおりです。

03-06 00:13:11.672:E / AndroidRuntime(4183):com.anthonymandra.framework.GalleryActivity $ ShareTask.onProgressUpdate(GalleryActivity.java:476)

ビュー階層を作成した元のスレッドのみがそのビューにアクセスできます。

私が知る限り、このためにUIスレッドにアクセスする必要があります...

私のアプリには多くの動作するAsyncTasksがありますが、要求されたとおり、doInBackground(簡略化)は次のとおりです。

for (MediaObject image : toShare)
{
    BufferedInputStream imageData = image.getThumbStream();
    File swapFile = getSwapFile(...);
    write(swapFile, imageData);
    ++completed;
    float progress = (float) completed / toShare.size();
    int progressLocation = (int) Math.ceil(progressRange * progress);
    onProgressUpdate(progressLocation);
}
4

3 に答える 3

4

問題は、publishProgressを呼び出す必要があるときにonProgressUpdateを呼び出していることです。OPはこれを自分で理解したので、コピーして貼り付けただけなので、答えを受け入れるのを待つ必要はありません。以下は、AsyncTasksがどのように機能するかについての情報であり、それは良い知識です。


AsyncTaskUIスレッドで作成していますか?そうでない場合はそれが問題です。onProgressUpdateを作成したスレッドで実行されますAsyncTask

更新:コードを掘り下げる時間(API 15ソースコード)を用意しましょう!

protected final void publishProgress(Progress... values) {
    if (!isCancelled()) {
        sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
                new AsyncTaskResult<Progress>(this, values)).sendToTarget();
    }
}

この仲間はそれを静的HandlersHandlerと呼びます。ドキュメントには次のように書かれています。

新しいハンドラーを作成すると、それを作成しているスレッドのスレッド/メッセージキューにバインドされます。その時点から、メッセージとランナブルがそのメッセージキューに配信され、メッセージから出てきたときに実行されます。列。

ドキュメント検索スキルを備えたBrunoMateusに感謝します。

ドキュメントページで見つけたものを見てください。スレッドルール-このクラスが正しく機能するために従わなければならないスレッドルールがいくつかあります。-AsyncTaskクラスをUIスレッドにロードする必要があります。これは、JELLY_BEANの時点で自動的に行われます。-タスクインスタンスはUIスレッドで作成する必要があります。execute(Params ...)はUIスレッドで呼び出す必要があります。-onPreExecute()、onPostExecute(Result)、doInBackground(Params ...)、onProgressUpdate(Progress ...)を手動で呼び出さないでください。-タスクは1回だけ実行できます(2回目の実行が試行されると、例外がスローされます)。

于 2013-03-05T14:39:19.833 に答える
1

次のように、AsyncTaskをアクティビティの内部クラスとして宣言できます。

public void onClick(View v) {
   new DownloadImageTask().execute("http://example.com/image.png");
}

 private class DownloadImageTask extends AsyncTask {
      protected Bitmap doInBackground(String... urls) {
          return loadImageFromNetwork(urls[0]);
     }

     protected void onPostExecute(Bitmap result) {
          mImageView.setImageBitmap(result);
     }
 }
于 2013-03-05T15:19:18.237 に答える
1

私は手動で呼んでいました:

onProgressUpdate

あなたは電話する必要があります

publishProgress

簡単な間違いですが、すばらしい情報です。サイモンとブルーノは称賛に値します。必要に応じて回答を投稿してください。迅速かつ広範な応答をありがとう!

于 2013-03-05T15:38:36.173 に答える