java - 在 Android 上创建了一个简单的计时器,没有按预期工作

标签 java android multithreading handler

我正在尝试在我的应用程序上显示一个计时器,其中一个线程计算耗时,一个处理程序修改 View 。

我知道 Android 不允许 UI 线程修改 View 的其他线程,所以我使用 Handler 来执行此操作。

但是好像没有效果,因为我还有“android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

我该怎么办?

(哦,下面是代码,如果这可能有帮助的话)

package com.hangin.arround.emergency;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockActivity;

public class MainActivity extends SherlockActivity {

    private static final String TAG = "MainActivity";

    private TextView elapsedTime;

    private Button startButton;
    private Button stopButton;

    private boolean shouldContinue = false;
    private Handler mHandler;
    private Runnable runnable;

    private static final int MESSAGE_ELAPSED_TIME = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // Creating the action bar, initializing my views and stuff

        // Creating the Handler
        mHandler = new Handler() {
            @SuppressLint("SimpleDateFormat")
            @Override
            public void handleMessage(Message msg){
                super.handleMessage(msg);
                switch(msg.what) {
                    case MESSAGE_ELAPSED_TIME :
                        // Converting from milliseconds to a String
                        DateFormat formatter = new SimpleDateFormat("hh:mm:ss.SSS");
                        Calendar calendar = Calendar.getInstance();


                        calendar.setTimeInMillis(msg.arg1);
                        String elapsedTimeString = formatter.format(calendar.getTime());


                        elapsedTime.setText(elapsedTimeString);
                        break;
                    default:
                        break;
                }
            }
        };

        // Creating the Runnable
        runnable = new Runnable(){

            @Override
            public void run() {
                int startTime, actualTime;
                startTime = (int) System.currentTimeMillis();
                Log.d(TAG, "startTime = " + startTime);

                while(shouldContinue) {
                    // Calcul du temps écoulé
                    actualTime = (int)System.currentTimeMillis() - startTime;
                    Log.d(TAG, "actualTime = " + actualTime);

                    // Creating the message sent to the Handler
                    Message elapsedTimeMessage = new Message();
                    elapsedTimeMessage.what = MESSAGE_ELAPSED_TIME;
                    elapsedTimeMessage.arg1 = (int) actualTime;

                    // Sending the message
                    mHandler.handleMessage(elapsedTimeMessage);
                }
            }

        };


        // Adding the OnClickListeners on startButton and stopButton
        startButton.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {

                // Launching Thread 
                (new Thread(runnable)).start();
                shouldContinue = true;
            }
        });

        stopButton.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {

                // Stopping the thread
                shouldContinue = false;
            }
        });
    }   
}

最佳答案

改变

Message elapsedTimeMessage = new Message();
elapsedTimeMessage.what = MESSAGE_ELAPSED_TIME;
elapsedTimeMessage.arg1 = (int) actualTime;
// Sending the message
mHandler.handleMessage(elapsedTimeMessage);

Message.obtain(mHandler, MESSAGE_ELAPSED_TIME, (int) actualTime, 0).sendToTarget();

从 API 文档来看,handleMessage 似乎是稍后在处理过程中调用的东西,不应直接调用。

关于java - 在 Android 上创建了一个简单的计时器,没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13941714/

相关文章:

java - 使用wait()和notify()进行同步

java - JPA 保留具有外键值的实体,但不想显式查找外键实体

java - 有没有一个java库可以合成法语语音(TTS)?

android - MapView 渲染,中间缺少 "x"的图 block

android - 在服务与其 Activity 之间共享数据

java - 在有效用户的情况下执行错误的循环

python - 为什么在只有一个线程的情况下需要使用线程锁? (Python)

java - 为 Apache Spark 指定外部配置文件

java - 远程连接工作时无法在本地从 java 连接到 mysql

java - ComputeIfAbsent 错误的 map 大小