如何在 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."
我正在开发一个简单的自定义视图来显示由背景图像组成的仪表,我在其上方打印一个数字 (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:
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."