我正在开发一个简单的自定义视图来显示由背景图像组成的仪表,在该背景图像上方打印数字(rpm)并绘制指针。
为了实现它,我定义了一个扩展ImageView类的类(MyGauge)。在onDraw()成员中,我将drawLine()和drawText()一个由活动发送并由SetRpm()成员收集的数字;然后我强制使用invalidate()调用
该活动运行一个Thread(一个Runnable实例),每秒生成一个不同的数字;线程将一条消息发送给活动;处理程序接收消息并通过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$2.handleMessage(GaugeActivity.java:54)
at android.os.Handler.dispatchMessage(Handler.java:99)
at com.stemmo.termi_up.GaugeActivity$3.run(GaugeActivity.java:83)
at java.lang.Thread.run(Thread.java:841)
所以,处理程序在线程的上下文中? 我怎么解决呢? 我需要AsyncTask对象而不是Runnable对象吗?
答案 0 :(得分:0)
Android中的视图只能从UI线程更新。您始终可以将Runnable发布到此类视图
MyGauge gauge = ... // your custom view
gauge.post(new Runnable() {
view.SetRPM();
});
答案 1 :(得分:0)
我回答因为我最好写下代码..
这是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();
}
答案 2 :(得分:0)
我发现您的代码存在问题。请替换您的代码行
myHandler.dispatchMessage(MSG); with myHandler.sendMessage(msg);
它将修复异常“只有创建视图层次结构的原始线程才能触及其视图。”