0

私はたくさんのボタンを持っています(カスタム、他の背景を適用し、元に戻すためのいくつかの追加の方法があります)、背景を割り当てることができます。しかし、これらの背景がどれだけ大きくなるか、または大きくなる可能性があるかわからないため、別のスレッドで背景を設定することにしました。まず、私はこのコードを持っていました:

public void updateButton(final Button b, final String d, final String s) {
    b.nullify(); //Recycles previous background, else OOM error
    b.setText(s);
    if (d != null) {
        new Thread() {
            @Override
            public void run() {
                b.setBackgroundFromBase64(d);
            }
        }.run();
    }
    else b.setBackgroundToDefault(); //Sets standard android background
}

しかし、私はすぐにこれが進むべき道ではないことに気づきました。このメソッドを数千回呼び出すと、ゆっくりとメモリが氾濫しました。パーツを取り外したときnew Thread()、メモリがフラッディングしていなかったので、スレッドが原因でした(メモリアナライザツールが同じことを教えてくれました)。

それから私は試しましたAsyncTask

private class UpdateButtonTask extends AsyncTask<Object, Void, Void> {
    @Override 
    protected Void doInBackground(Object... objs) {
        String s = (String)objs[0];
        Button b = (Button)objs[1];
        String d = (String) objs[2];
        b.nullify(); //Recycles previous background, else OOM error
        b.setText(s);
        if (d != null) b.setBackgroundFromBase64(d);
        else b.setBackgroundToDefault();
        return null;
     }
     @Override
     protected void onProgressUpdate(Void v) {
         //As far as I know, I don't need this method
     }
     @Override
     protected void onPostExecute(Void v) {
         //Neither this one
     }
 }

と電話

new UpdateButtonTask().execute("Button", myButton, base64String);

ボタン更新メソッドで。しかし、それも機能しませんでした(ボタンはまったく更新されませんでした。テキストもカスタム背景もありません)。スレッドに関するいくつかの記事や質問(これこれ、そして これなど)を読みましたが、うまく機能していないようです。今のところ、スレッドはなく、電話がUIスレッドで問題を引き起こさないほど高速であることを期待するのが最善の選択肢のようですが、スレッドのようなもっと信頼できるものが欲しいです。 私は何が間違っているのですか?または、完全な質問です。背景スレッドのボタンの背景を更新するにはどうすればよいですか(大きな背景を適用してもUIが機能しなくなることはありません) 。

4

2 に答える 2

0

問題は、UI以外のスレッドでUIを更新しようとしていることだと思います。これは例外をスローし、あなたを殺しますAsyncTask

処理の多いタスクをに分離してから、AsyncTaskUIの変更をメインスレッドに適用する必要があります(を使用してrunOnUiThread(Runnable))。

カスタムボタンを使用しているので、UI以外のスレッドで何が許可されていないのかよくわかりません。setTextオーバーライドしていなければ、関数が問題を引き起こしていると思います。

doInBackgroundまず、メソッド全体をtry/catchブロックでラップし、例外をログに記録して問題を特定する必要があります。

于 2012-10-11T14:24:49.927 に答える
-1

このコードがあなたを助けるかもしれません

new Thread(new Runnable() {

public void run() {

context.runOnUiThread(new Runnable() {

public void run() {
      b.setBackgroundFromBase64(d);
}

});

}

}).start();
于 2012-10-11T14:33:21.297 に答える