• Android中多线程编程(三)Handler更新UI的方式


    Handler更新UI的方式和原因以及遇到的问题

    1.方式:

    仅仅能通过Handler来更新UI。

    代码例如以下:

    package com.chengdong.su.handlerdemo;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.TextView;
    
    /**
     * android中更新UI的方式
     * 
     * @author scd
     * 
     */
    public class SixActivity extends Activity {
        private String TAG = getClass().getSimpleName();
        private String mName = "HandlerThread";
    
        private TextView mView;
        /** the object of the Handler */
        private Handler mHandler = new Handler() {
            public void handleMessage(Message msg) {
                Log.d(TAG, "------>handleMessage() 主线程:" + Thread.currentThread());
                mView.setText("主线程02");
            };
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            init();
            Log.d(TAG, "------>onCreate() 主线程:" + Thread.currentThread());
            new Thread() {
                public void run() {
                    try {
                        Thread.sleep(2000);
                        Log.d(TAG, "------>Thread() 子线程:" + Thread.currentThread());
                        // updateUI01();
                        // updateUI02();
                        // updateUI03();
                        updateUI04();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                };
    
            }.start();
        }
    
        /**
         * init the view
         */
        private void init() {
            mView = (TextView) findViewById(R.id.textView1);
    
        }
    
        /**
         * 更新UI的方式1
         */
        public void updateUI01() {
            Log.d(TAG, "------>updateUI01() Thread() 子线程:" + Thread.currentThread());
    
            mHandler.post(new Runnable() {
    
                @Override
                public void run() {
                    Log.d(TAG,
                            "------>updateUI01() Thread() run() 主线程:"
                                    + Thread.currentThread());
    
                    mView.setText("主线程01");
    
                }
            });
    
        }
    
        /**
         * 更新UI的方式2
         */
    
        public void updateUI02() {
            Log.d(TAG,
                    "------>updateUI02()  Thread() 子线程:" + Thread.currentThread());
            mHandler.sendEmptyMessage(0);
    
        }
    
        /**
         * 更新UI的方式3
         */
        public void updateUI03() {
            Log.d(TAG,
                    "------>updateUI03()  Thread() 子线程:" + Thread.currentThread());
            // 更新UI界面中的组件
            runOnUiThread(new Runnable() {
    
                @Override
                public void run() {
                    Log.d(TAG,
                            "------>updateUI03()  Thread() run() 主线程:"
                                    + Thread.currentThread());
                    mView.setText("主线程03");
    
                }
            });
    
        }
    
        /**
         * 更新UI的方式4
         */
        public void updateUI04() {
            Log.d(TAG,
                    "------>updateUI04()  Thread() 子线程:" + Thread.currentThread());
            mView.post(new Runnable() {
    
                @Override
                public void run() {
                    Log.d(TAG,
                            "------>updateUI04()  Thread() run() 主线程:"
                                    + Thread.currentThread());
                    mView.setText("主线程04");
    
                }
            });
        }
    }

    推荐使用第一种和另外一种。

    2.使用Handler更新UI的原因:

    假设当前线程和主线程不相等的话,更新UI就会抛出异常。
    Activity检查当前线程和主线程是否相等是在onResume()方法才開始的。


    所以在新开启的线程。假设不休眠直接更新UI的话不会抛出异常。
    假设休眠再做更新UI操作的话就会抛出异常。

    样例例如以下:(不要这样使用,仅仅是为了演示说明)

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            init();
            Log.d(TAG, "------>onCreate() 主线程:" + Thread.currentThread());
            new Thread() {
                public void run() {
                    // 不会出现异常
                    // mView.setText("主线程02");
                    try {
                        Thread.sleep(2000);
                        // 出现异常
                        mView.setText("主线程02");
    
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                };
    
            }.start();
        }

    3. Android开发中Handler的使用遇到的问题:

    1.不能在子线程中更新UI。
    2.假设在子线程创建Handler的时候,一定要创建一个Looper对象:Looper.prepare();

  • 相关阅读:
    开场白
    八皇后(DFS)
    function-paren-newline (Rules) – Eslint 中文开发手册
    Java面试题:Error和Exception有什么区别?
    Linux mmove 命令
    字母间距 | letter-spacing (Scalable Vector Graphics) – CSS 中文开发手册
    object.watch (Object) – JavaScript 中文开发手册
    ASP.NET MVC HTML 帮助器
    C 库函数 – strerror()
    Java中的初始化模块
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7252077.html
Copyright © 2020-2023  润新知