你怎么解决Android开发中更新UI报错的异常吗?
来源:网络收集 点击: 时间:2024-08-11要实现的功能:
在App上点击”变透明“的按钮后,App的背景色先变为透明,等等10秒后,
再把背景色改为半透明(alpha值为0.5)
Show the code:
AndroidManifest.xml:
LinearLayout
android:layout_width=fill_parent
android:layout_height=wrap_content
android:gravity=center
android:orientation=horizontal
Button
android:id=@+id/clickTransparency
android:layout_width=wrap_content
android:layout_height=wrap_content
android:onClick=turnTransparencyClickHandler
android:text=变透明 /
MainActivity.java
public void turnTransparencyClickHandler(View view) {
changeBackgroundAlphaTo(0.0f);
}private void changeBackgroundAlphaTo(final float alphaValue) {
new Thread(new Runnable() {
@Override public void run() {
final WindowManager.LayoutParams attributes = getWindow().getAttributes();
attributes.alpha = alphaValue;//0.0全透明.1.0不透明.
getWindow().setAttributes(attributes);
}
}).start();
}


执行上述代码。
在App中点击”变透明“的按钮后,App就退出了。
logcat中打印了这个错:
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: FATAL EXCEPTION: Thread-15651
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: Process: com.example.cy.myapplication, PID: 11640
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6090)
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:879)
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at android.view.View.requestLayout(View.java:16463)
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at android.view.View.setLayoutParams(View.java:10593)
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at android.view.WindowManagerGlobal.updateViewLayout(WindowManagerGlobal.java:292)
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at android.view.WindowManagerImpl.updateViewLayout(WindowManagerImpl.java:74)
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at android.app.Activity.onWindowAttributesChanged(Activity.java:2347)
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at android.support.v7.internal.view.WindowCallbackWrapper.onWindowAttributesChanged(WindowCallbackWrapper.java:105)
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at android.view.Window.setAttributes(Window.java:847)
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at com.example.cy.myapplication.MainActivity$1.run(MainActivity.java:78)
03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: at java.lang.Thread.run(Thread.java:841)

和Swing中的用法还不一样啊。
哪就在UI线程中更新吧。
Android中有个组件android.os.Handler的postDelayed可以解决这个问题
源码:
/**
* Causes the Runnable r to be added to the message queue, to be run
* after the specified amount of time elapses.
* The runnable will be run on the thread to which this handler
* is attached.
* bThe time-base is {@link android.os.SystemClock#uptimeMillis}./b
* Time spent in deep sleep will add an additional delay to execution.
*
* @param r The Runnable that will be executed.
* @param delayMillis The delay (in milliseconds) until the Runnable
* will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the Runnable will be processed --
* if the looper is quit before the delivery time of the message
* occurs then the message will be dropped.
*/
public final boolean postDelayed(Runnable r, long delayMillis)
{
return sendMessageDelayed(getPostMessage(r), delayMillis);
}

改改刚才报错的代码
Code:
MainActivity.java:
定义一个字段
private Handler handler = new Handler();
public void turnTransparencyClickHandler(View view) {
changeBackgroundAlphaTo(0.0f);
handler.postDelayed(new Runnable() {
@Override
public void run() {
Log.i(turnTransparency, begin to change alpha to 0.5);
changeBackgroundAlphaTo(0.5f);
Log.i(turnTransparency, end to change alpha to 0.5);
}
}, 10 * 1000);
}
private void changeBackgroundAlphaTo(float alphaValue) {
WindowManager.LayoutParams attributes = getWindow().getAttributes();
attributes.alpha = alphaValue;//0.0全透明.1.0不透明.
getWindow().setAttributes(attributes);
}

执行下,看看是否达到预期效果
达到了,Success!


从截图看不出这个变化。
在执行变成半透明的代码中,加有日志打印,在logcat中看看能否找到
日志:
03-20 15:16:14.986 16571-16571/com.example.cy.myapplication I/turnTransparency: begin to change alpha to 0.5
03-20 15:16:14.986 16571-16571/com.example.cy.myapplication I/turnTransparency: end to change alpha to 0.5

版权声明:
1、本文系转载,版权归原作者所有,旨在传递信息,不代表看本站的观点和立场。
2、本站仅提供信息发布平台,不承担相关法律责任。
3、若侵犯您的版权或隐私,请联系本站管理员删除。
4、文章链接:http://www.1haoku.cn/art_1107106.html