如何在 Android 中更新自定义视图

How to update a custom view in Android

我正在开发一个简单的自定义视图来显示由背景图像组成的仪表,我在其上方打印一个数字 (rpm) 并绘制一个指针。
为了实现它,我定义了一个扩展 ImageView class 的 class (MyGauge)。在 onDraw() 成员中,我 drawLine() 和 drawText() 由 activity 发送并由 SetRpm() 成员收集的数字;然后我强制执行 invalidate() 调用。
activity运行一个Thread(一个Runnable实例)每秒生成一个不同的数字;线程向 activity 发送消息;处理程序接收消息并通过 SetRpm() 函数设置数字。

我收到的错误是:

03-12 09:39:33.280 1796-1827/com.stemmo.termi_up W/dalvikvm: threadid=16: thread exiting with uncaught exception (group=0xb178e678)
03-12 09:39:33.280 1796-1827/com.stemmo.termi_up E/AndroidRuntime: FATAL EXCEPTION: Thread-78
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5908)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:869)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:4253)
at android.view.View.invalidate(View.java:10539)
at android.view.View.invalidate(View.java:10494)
at com.stemmo.termi_up.CustomViews.MyGauge.SetRpm(MyGauge.java:61)
at com.stemmo.termi_up.GaugeActivity.handleMessage(GaugeActivity.java:54)
at android.os.Handler.dispatchMessage(Handler.java:99)
at com.stemmo.termi_up.GaugeActivity.run(GaugeActivity.java:83)
at java.lang.Thread.run(Thread.java:841)

那么,处理程序在线程的上下文中??
我该如何解决?
我需要 AsyncTask 对象而不是 Runnable 对象吗?

Android 中的视图只能从 UI 线程更新。你总是可以 post 一个 Runnable 到这样的视图

    MyGauge gauge = ... // your custom view
    gauge.post(new Runnable() {
        view.SetRPM();
    });

我回答是因为我最好写下代码..
这是 Activity:

的 onCreate() 上的代码
       final Handler myHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            Bundle data = msg.getData();
            String v = data.getString("value");
            myGauge.SetRpm(v);
        }
    };

    // Simul thread
    nValue = 0;
    bUpDown = true;
    Runnable thread = new Runnable() {
        @Override
        public void run() {
            while(true) {
                if (bUpDown)    // Up
                   ...
                }

                Bundle data = new Bundle();
                data.putString("value", String.valueOf(nValue));
                Message msg = new Message();
                msg.setData(data);
                myHandler.dispatchMessage(msg);

                // Delay
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    new Thread(thread).start();

MyGauge 中的 SetRpm() 成员是:

 public void SetRpm(String newRpm)
{
    m_strRpm = newRpm;
    invalidate();
}

我发现您的代码存在问题。请替换您的代码行

myHandler.dispatchMessage(消息);用 myHandler.sendMessage(味精);

它将修复异常 "Only the original thread that created a view hierarchy can touch its views."