6

基本的に、秒カウンターとレベルカウンターを実行しようとしています。10秒ごとに++レベルにしたい。
しかし、それはまだ実装されていません。これまでのところ、表示する秒数を取得しようとしていますが、ランタイム例外とクラッシュが発生しています。
グーグルでは、スレッドから UI を更新しようとしていて、それが許可されていないことが原因であることがわかりました。したがって、asyncTask が必要になると思いますが、単純な小さなプログラムでそれを行う方法がわかりません。助けてください、またはいくつかの代替案を教えてください...

package com.ryan1;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class main extends Activity {

int level = 1;
int seconds_running=0;

TextView the_seconds;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    the_seconds = (TextView) findViewById(R.id.textview_seconds);



    Thread thread1 = new Thread(){
        public void run(){
            try {
                sleep(1000); Log.d("RYAN", " RYAN ");

                updated_secs();
            } catch (Exception e) {
                e.printStackTrace();
                Log.d("RYAN", " "+e);
            }
        }
    };
    thread1.start();
}

public void updated_secs(){
    seconds_running++;
    the_seconds.setText(" "+seconds_running);
}
}
4

3 に答える 3

6

UI スレッドでハンドラーを作成し、ワーカー スレッドでハンドラーにメッセージを送信します (Handler.sendMessage(...))。

メッセージは UI スレッドで処理されるため、テキスト ウィジェットを正しく更新できます。このような:

private Handler myUIHandler = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    {
        if (msg.what == some_id_you_created)
        {
            //Update UI here...
        }
    }
};

Then in your thread, to send a message to the handler you do this:

Message theMessage = myHandler.obtainMessage(some_id_you_created);
myUIHandler.sendMessage(theMessage);//Sends the message to the UI handler.
于 2011-03-20T22:52:16.200 に答える
3

この種のことについては、別のスレッドを使用するのは無駄です。それは単なる無駄であり、マルチスレッドの問題に取り組む必要があります。代わりに、Handler.sendDelayedMessage()を使用してください。

static final int MSG_DO_IT = 1;
static final long TIME_BETWEEN_MESSAGES = 10 * 1000;  // 10 seconds

Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_DO_IT: {

                // Update your UI here...

                Message newMsg = obtainMessage(MSG_DO_IT);
                sendMessageDelayed(newMsg, TIME_BETWEEN_MESSAGES);
            } break;
        }
    }
}

@Override
void onResume() {
    super.onResume();

    // Start the timer, executing first event immediately.
    Message newMsg = mHandler.obtainMessage(MSG_DO_IT);
    mHandler.sendMessage(newMsg);
}

@Override
void onPause() {
    super.onPause();

    // Stop the timer.
    mHandler.removeMessages(MSG_DO_IT);
}

この実装には多少のずれがあることに注意してください。メッセージ間の実際の時間はTIME_BETWEEN_MESSAGES+(メッセージをディスパッチする時間)です。ドリフトしないものが必要な場合は、Hander.sendMessageAtTime()を使用し、onResumeのSystemClock.uptimeMillis()で取得した最初の時刻から始めて、毎回一定の値で新しい時刻をインクリメントすることにより、自分でタイミングをとることができます。 ()。

于 2011-03-20T23:29:11.853 に答える
1

AsyncTask を使用して構築されたタイマーと、postDelayed メソッドを使用したハンドラーの優れた例があります。

バックグラウンドから UI を更新することは禁止されていることは間違いありません。

于 2011-03-20T22:19:28.950 に答える