zoukankan      html  css  js  c++  java
  • 一手遮天 Android

    项目地址 https://github.com/webabcd/AndroidDemo
    作者 webabcd

    一手遮天 Android - 异步和多线程: Handler 的使用

    示例如下:

    /async/HandlerDemo1.java

    /**
     * Handler 的使用(Handler 用于在线程之间传递信息)
     *     本例演示后台线程向主线程发送信息
     *
     *
     * Message - 用于封装需要传递的信息(一般通过 handler 的 obtainMessage() 来构造 Message 对象,而不是 new 一个。因为 obtainMessage() 会从 Message 池中拿一个不用的过来,这样会省去创建对象的开销)
     *     what - 信息类型(以便接收方区分不同类型的信息)
     *     arg1, arg2 - 自定义整型参数
     *     obj - 具体的信息对象
     * Handler - 与相关的 MessageQueue 和 Looper 形成绑定关系,有两个作用
     *     1、将信息发送到 Handler 所属线程的 MessageQueue
     *     2、接收 Looper 获取到的信息,以便在 Handler 所属线程进行处理
     * MessageQueue - 用于保存 Message 对象的消息队列
     * Looper - 线程的 MessageQueue 管理者,循环从 MessageQueue 获取消息,并交给 Handler 处理
     *
     *
     * 通过 Handler 的 send 发送信息到 MessageQueue,以及接收 send 过来的信息
     *     sendMessage(Message msg) - 通过 send 发送 Message 对象
     *     sendMessageAtFrontOfQueue(Message msg) - 通过 send 发送 Message 对象,并将其放入 MessageQueue 队列的第一个
     *     sendMessageDelayed(Message msg, long delayMillis) - 通过 send 延迟指定的时间(相对于 SystemClock.elapsedRealtime)后发送 Message 对象
     *     sendMessageAtTime(Message msg, long uptimeMillis) - 通过 send 延迟指定的时间(相对于 SystemClock.uptimeMillis)后发送 Message 对象
     *     sendEmptyMessageDelayed(int what, long delayMillis) - 通过 send 延迟指定的时间(相对于 SystemClock.elapsedRealtime)后发送一个只有 what 值的空信息
     *     sendEmptyMessageAtTime(int what, long uptimeMillis) - 通过 send 延迟指定的时间(相对于 SystemClock.uptimeMillis)后发送一个只有 what 值的空信息
     *     通过重写 handleMessage(Message msg) 来处理 send 过来的信息
     *
     * 通过 Handler 的 post 发送信息到 MessageQueue,以及接收 post 过来的信息
     *     post(Runnable r) - 通过 post 发送消息,在指定的 Runnable(这个 Runnable 运行在 handler 所属线程)直接处理
     *     postAtFrontOfQueue(Runnable r) - 通过 post 发送消息,并将其放入 MessageQueue 队列的第一个,在指定的 Runnable(这个 Runnable 运行在 handler 所属线程)直接处理
     *     postDelayed(Runnable r, long delayMillis) - 通过 post 延迟指定的时间(相对于 SystemClock.elapsedRealtime)后发送消息,在指定的 Runnable(这个 Runnable 运行在 handler 所属线程)直接处理
     *     postAtTime(Runnable r, long uptimeMillis) - 通过 post 延迟指定的时间(相对于 SystemClock.uptimeMillis)后发送消息,在指定的 Runnable(这个 Runnable 运行在 handler 所属线程)直接处理
     *     postAtTime(Runnable r, Object token, long uptimeMillis) - token 用于信息的删除,其他和 postAtTime(Runnable r, long uptimeMillis) 一样
     *
     * 从 MessageQueue 移除指定的信息
     *     removeMessages(int what) - 移除指定 what 的 send 信息
     *     removeMessages(int what, Object object) - 移除指定 what 和 obj 的 send 信息
     *     removeCallbacks(Runnable r) - 移除 post 的指定 Runnable 的回调
     *     removeCallbacks(Runnable r, Object token) - 移除 post 的指定 Runnable 和 token 的回调
     *     removeCallbacksAndMessages(Object token) - 移除 post 的指定 token 的信息和回调
     *
     *
     * 注:
     * 1、主线程已经启动 Looper 了,不用再 Looper.prepare()/Looper.loop() 了
     * 2、新开线程需要自己写 Looper.prepare()/Looper.loop()/myLooper.quit()
     */
    
    package com.webabcd.androiddemo.async;
    
    import android.os.Message;
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    import com.webabcd.androiddemo.R;
    
    public class HandlerDemo1 extends AppCompatActivity {
    
        private TextView _textView1;
        private TextView _textView2;
        private Button _button1;
        private Button _button2;
    
        private Handler _handler;
    
        private final int NORMAL_MESSAGE = 100;
        private final int DELAY_MESSAGE = 200;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_async_handlerdemo1);
    
            _textView1 = (TextView) findViewById(R.id.textView1);
            _textView2 = (TextView) findViewById(R.id.textView2);
            _button1 = (Button) findViewById(R.id.button1);
            _button2 = (Button) findViewById(R.id.button2);
    
            sample();
        }
    
        private void sample() {
            // 在 UI 线程实例化 Handler(默认与 Looper.myLooper() 形成绑定关系,也可以与指定的 Looper 形成绑定关系)
            _handler = new MyHandler();
            // _handler = new MyHandler(looper);
    
            _button1.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View arg0) {
    
                    // 启动一个后台线程
                    Thread myThread = new MyThread();
                    myThread.setName("myThread");
                    myThread.setDaemon(true);
                    myThread.start();
    
                    _textView1.setText("后台线程开始执行
    ");
                }
            });
    
            _button2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    writeMessage(String.format("取消队列中的 what 值为 %d 的 send 信息的发送", DELAY_MESSAGE));
                    // 取消队列中的 what 值为 200 的 send 信息的发送
                    _handler.removeMessages(DELAY_MESSAGE);
                }
            });
        }
    
        // 自定义 Handler
        class MyHandler extends Handler {
            @Override
            public void handleMessage(Message msg) {
                // 本例的 Handler 是在 UI 线程上实例化的,所以这里的 handleMessage 也是在 UI 线程上执行的
                _textView1.append(String.format("收到通过 handler 的 send 发送的信息,what:%d, arg1:%d, arg2:%d, obj:%s
    ", msg.what, msg.arg1, msg.arg2, msg.obj));
            }
        }
    
        // 自定义 Thread
        class MyThread extends Thread {
            @Override
            public void run() {
                try {
                    writeMessage("耗时任务开始执行");
                    Thread.sleep(3 * 1000);
                    writeMessage("耗时任务执行完毕");
                } catch (InterruptedException e) {
    
                }
    
                // 用 handler 的 obtainMessage() 来构造 Message 对象,而不是 new 一个。因为 obtainMessage() 会从 Message 池中拿一个不用的过来,这样会省去创建对象的开销
                Message msgNormal = _handler.obtainMessage();
                msgNormal.what = NORMAL_MESSAGE; // 信息类型(用于在 handleMessage 中区分不同类型的信息)
                msgNormal.arg1 = 1; // 自定义整型参数
                msgNormal.arg2 = 2; // 自定义整型参数
                msgNormal.obj = "信息 A"; // 具体的信息对象
                writeMessage(String.format("send 一个信息,what:%d, obj:%s", msgNormal.what, msgNormal.obj));
                // send 信息到 handler 所属线程
                _handler.sendMessage(msgNormal);
    
                Message msgDelay = _handler.obtainMessage();
                msgDelay.what = DELAY_MESSAGE;
                msgDelay.arg1 = 1;
                msgDelay.arg2 = 2;
                msgDelay.obj = "信息 B";
                writeMessage(String.format("延迟 3000 毫秒 send 一个信息,what:%d, obj:%s", msgDelay.what, msgDelay.obj));
                // 延迟 3000 毫秒后 send 信息到 handler 所属线程
                _handler.sendMessageDelayed(msgDelay, 3000);
    
                writeMessage("延迟 5000 毫秒 post 一个信息");
                // 延迟 5000 毫秒后 post 信息到 handler 所属线程
                _handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        // 这里是在 handler 所属线程执行的
                        _textView1.append("收到通过 handler 的 post 发送的信息
    ");
                    }
                }, 5000);
            }
        }
    
        private void writeMessage(final String message) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    _textView2.append(String.format("%s
    ", message));
                }
            });
        }
    }
    

    /layout/activity_async_handlerdemo1.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="启动一个后台线程(用于向主线程发送消息)" />
    
        <Button
            android:id="@+id/button2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:text="取消队列中的 what 值为 200 的 send 信息的发送" />
    
        <TextView
            android:id="@+id/textView2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    

    项目地址 https://github.com/webabcd/AndroidDemo
    作者 webabcd

  • 相关阅读:
    IfcControlExtension (控件扩展)
    IfcKernel (内核)
    IFC4x0核心层
    IfcSharedMgmtElements (共享管理元素)
    IfcSharedFacilitiesElements (共享设施元素)
    IfcSharedComponentElements (共享组件元素)
    IfcSharedBldgServiceElements (共享建筑服务要素)
    IfcSharedBldgElements (共享建筑元素)
    IFC4x0共享层
    IfcStructuralElementsDomain (结构元素领域)
  • 原文地址:https://www.cnblogs.com/webabcd/p/android_async_HandlerDemo1.html
Copyright © 2011-2022 走看看