IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android handler 之消息屏障 -> 正文阅读

[移动开发]Android handler 之消息屏障

handler中的消息类型有3种:

(1)?? ?普通消息(同步消息);

(2)?? ?消息屏障(同步屏障);

(3)?? ?异步消息;

?屏障消息就是为了确保异步消息的优先级,设置了屏障后,只能处理其后的异步消息,同步消息会被挡住,除非撤销屏障。

插入消息屏障

?消息屏障:

  1. 没有target,即没有handler,不能分发;
  2. 带时间戳,在队列中也是按照时间戳排序的;而且,只能影响的时间戳后面的消息;
  3. 消息队列是可以插入多个消息屏障的;
  4. 插入到消息队列中,是没有唤醒线程的;
  5. 插入的消息屏障会返回一个token,这个token就是这个屏障的序号;
  6. 这个postSyncBarrier是一私有函数,只能通过反射来调用;

撤销(删除)消息屏障

?添加屏障的时候没有唤醒线程,反而是删除屏障的时候唤醒了线程;

消息屏障的处理

?

相关问题

插入消息时,如果消息队列中有消息屏障会怎么样?

?

//第一个问题:不会

//第二个问题,不会;

//第三个问题,可能会,看屏障的时间到了没有;

//第二个问题,可能会,看屏障的时间到了没有;

android源码中使用的消息屏障

在线程绘制的时候;

代码示例

对于的layout文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/addBarrier"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Add Barrier"
        android:textSize="22sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"

        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/removeBarrier"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Remove Barrier"
        android:textSize="22sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/normal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send normal message"
        android:textSize="22sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/async"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Send async message"
        android:textSize="22sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</LinearLayout>

对应的activity文件:

package inuker.com.testbarrier;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Deque;
import java.util.LinkedList;

public class MainActivity extends Activity {

    private HandlerThread mThread;
    private Handler mHandler;

    private Deque<Integer> mBarrierTokens = new LinkedList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mThread = new HandlerThread("");
        mThread.start();

        mHandler = new Handler(mThread.getLooper());

        findViewById(R.id.addBarrier).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                addBarrier();
            }
        });

        findViewById(R.id.removeBarrier).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                removeBarrier();
            }
        });

        findViewById(R.id.normal).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                sendNormalMessage();
            }
        });

        findViewById(R.id.async).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                sendAsyncMessage();
            }
        });
    }

    private void addBarrier() {
        try {
            Method method = MessageQueue.class.getMethod("postSyncBarrier");
            method.setAccessible(true);
            int barrierToken = (int) method.invoke(mHandler.getLooper().getQueue());
            showToast(String.format("addBarrier success: %d", barrierToken));
            mBarrierTokens.add(barrierToken);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    private void removeBarrier() {
        if (mBarrierTokens.isEmpty()) {
            return;
        }
        try {
            Method method = MessageQueue.class.getMethod("removeSyncBarrier", int.class);
            method.setAccessible(true);
            int barrierToken = mBarrierTokens.pollLast();
            method.invoke(mHandler.getLooper().getQueue(), barrierToken);
            showToast(String.format("removeBarrier success: %d", barrierToken));
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    private void sendNormalMessage() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
//                showToast("Normal Message");
                Log.d("999","111 Normal");
            }
        });
    }

    private void sendAsyncMessage() {
        Message msg = Message.obtain(mHandler, new Runnable() {
            @Override
            public void run() {
                showToast("Async Message");
                Log.d("999","222 Async Message");
            }
        });
        msg.setAsynchronous(true);
        msg.sendToTarget();
    }

    private void showToast(final String s) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, s, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

说明:在点击插入屏障后,此时,插入普通消息,是不会执行的,当删除消息屏障时,普通消息才会执行;

参考:

Android Handler 机制(四):屏障消息(同步屏障)

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-26 10:17:52  更:2021-09-26 10:19:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:10:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码