多语言展示
当前在线:210今日阅读:4今日分享:26

你怎么解决Android开发中更新UI报错的异常吗?

想实现一个sleep 一会再更新UI的操作,结果报错了。最后使用android.os.Handler来实现这个功能本文就分享一下解决这个报错的办法
工具/原料
1

Android Studio

2

Java

3

Android真机

方法/步骤
1

要实现的功能:在App上点击”变透明“的按钮后,App的背景色先变为透明,等等10秒后,再把背景色改为半透明(alpha值为0.5)Show the code:AndroidManifest.xml:    

2

执行上述代码。在App中点击”变透明“的按钮后,App就退出了。logcat中打印了这个错:03-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: FATAL EXCEPTION: Thread-1565103-20 14:47:31.326 11640-11796/com.example.cy.myapplication E/AndroidRuntime: Process: com.example.cy.myapplication, PID: 1164003-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)

3

和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. * The time-base is {@link android.os.SystemClock#uptimeMillis}. * 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);}

4

改改刚才报错的代码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);}

5

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

6

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

推荐信息