0

私はTextViewを持っています。ボタンをクリックしてから1秒後にテキストを更新(「1」を追加)したい。

public class HaikuDisplay extends Activity {
    Method m;
    Timer t;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        t = new Timer();
        m = HaikuDisplay.class.getMethod("change");
    }
    //Event handler of the button
    public void onRefresh(View view)
    {       
        //To have the reference of this inside the TimerTask
        final HaikuDisplay hd = this;
        TimerTask task1 = new TimerTask(){
            public void run(){
                /*
                 * I tried to update the text here but since this is not the UI thread, it does not allow to do so.
                 */
                //Calls change() method
                m.invoke(hd, (Object[])null);
            }
        };
        t.schedule(task1, 1000);
    }
    public void change()
    {
        //Appends a "1" to the TextView
        TextView t = (TextView)findViewById(R.id.textView1);
        t.setText(t.getText() + "1");
    }

    //Event handler of another button which updates the text directly by appending "2".
    //This works fine unless I click the first button.
    public void onRefresh1(View view)
    {
        TextView t = (TextView)findViewById(R.id.textView1);
        t.setText(t.getText() + "2");
    }
}

すべての例外が処理されることを考慮してください。

最初のクリックで、m.invokeを与えInvocationTargetExceptionます。change()ただし、例外なしで連続して呼び出されたときにメソッドを呼び出します(ロギングによって確認されます)。ただし、テキストは更新されません。私はどこが間違っていますか?

また、ボタンをクリックするたびに新しいスレッドが作成されることがデバッガーで確認できます。それは結構です。しかし、実行が完了したのに、なぜ以前のスレッドを削除しないのでしょうか。

4

4 に答える 4

2
                new Handler().postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        // Update UI

                    }
                }, 1000);

ボタンクリックでこれを実装する

アップデート:

他にもいくつか答えがあります。dtmilanoは、ViewクラスのpostDelayedメソッドを呼び出していることを除いて、私のものとほぼ同じ別のソリューションを提案しました。私の答えでは、ハンドラークラスのpostDelayedメソッドを使用しました。

アンドロイドのAPIリファレンスから、ハンドラーのpostDelayedメソッドは言います

ランナブルは、このハンドラーが接続されているスレッドで実行されます。

そして、ビューのpostDelayedメソッドは言います

ランナブルは、ユーザーインターフェイススレッドで実行されます。

これが、これら2つのソリューションの唯一の違いです。私の答えでは、他のハンドラーインスタンスを使用できるたびに新しいハンドラーを作成する代わりに。次に、ランナブルは、その特定のハンドラーが宣言されているスレッドで実行されます。また、EditTextのpostDelayedが使用されている場合、runnableメソッドはユーザーインターフェイススレッドで実行されます。

パフォーマンスの問題ですが、どちらも同じパフォーマンスです(誰かが参照して私が間違っていることを証明できれば、私は幸せになります)

于 2013-03-04T06:24:52.713 に答える
2

このようなことをする

public void onRefresh1(View v) {
    // You can have this in a field not to find it every time
    final EditText t = (EditText) findViewById(R.id.textView1);
    t.postDelayed(new Runnable() {

        @Override
        public void run() {
            t.append("1");
        }
    }, 1000);
}
于 2013-03-04T08:04:28.657 に答える
1

それはひどく複雑に見えます-代わりにCountDownTimerを使用することを検討しましたか?

new CountDownTimer(1000, 1000) {
    public void onTick(long millisUntilFinished) {
        // no-op
    }

    public void onFinish() {
        change();
    }
}.start();

これにより、UIスレッドでchangeを呼び出す(したがってテキストを変更する)必要があり、リフレクションとスレッドエラーを回避します。

于 2013-03-04T05:52:57.270 に答える
0

こんにちはそのために次のコードを使用してください。これがお役に立てば幸いです。

new java.util.Timer().schedule( 
        new java.util.TimerTask() {
            @Override
            public void run() {
                // your code here
            }
        }, 
        1000 
);

この質問も見てください。

Androidで10秒ごとにデータを表示する

これでもお試しいただけます。

private Handler handler = new Handler();    
private Runnable runnable = new Runnable() {   
    public void run() {
        doStuff();
        /*
         * Now register it for running next time
         */
        handler.postDelayed(this, 1000);
    } 
    };




**EDIT 3**



  Try with this once you are need to enable once (i mean if you put your code in yourmethod()== this will get automatically call 1 seconds once. 

    private Timer timer;
    TimerTask refresher;

              // Initialization code in onCreate or similar:

              timer = new Timer();    
              refresher = new TimerTask() {
                  public void run() {
                      yourmethod();
                  };
              };
              // first event immediately,  following after 1 seconds each
              timer.scheduleAtFixedRate(refresher, 0,100); 
于 2013-03-04T05:56:26.483 に答える