从源码到原理剖析activity核心知识点

news2024/11/15 8:27:24

在这里插入图片描述

  • 如何在onResume方法中获取到View的宽高?
    有两种方式:post和addOnGlobalLayoutListener
    override fun onResume() {
        super.onResume()
        Log.e("onresume",tabBottom.width.toString()+"--"+tabBottom.height.toString())
        //view.post之所以能够拿到宽高,是因为在绘制之前,会将获取宽高的任务放到Handler的消息队列,等到View的绘制结束之后,便会执行。
        tabBottom.post {
            Log.e("onresume:post",tabBottom.width.toString()+"--"+tabBottom.height.toString())

        }
        tabBottom.viewTreeObserver.addOnGlobalLayoutListener {
            tabBottom.viewTreeObserver.removeOnGlobalLayoutListener{this}//防止被多次绘制
            Log.e("onresume:viewTreeObserver",tabBottom.width.toString()+"--"+tabBottom.height.toString())

        }
    }
  • 为什么无法在onCreate或onResume方法中获取到View的宽高?
    因为这个时候view的绘制流程还没有开始。要拿到View的宽高,那么View的绘制流程(measure—layout—draw)至少要完成measure阶段。
    有看过onCreate方法源码的同学应该知道:

    • onCreate流程中的setContentView只是解析了xml,初始化了DecorView,创建了各个控件的对象;即将xml中的 转化为一个TextView对象。并没有启动View的绘制流程。
    • 调用performResumeActivity, 该方法中r.activity.performResume(r.startsNotResumed, reason);会调用Activity的onResume方法。执行完Activity的onResume后调用了wm.addView(decor, l);,到这里,开始将此前创建的DecorView添加到视图中,也就是在这之后才开始布局的绘制流程,真正开始是在ViewRootImpl类里面的。
  • 子线程中真的不能更新UI吗?
    各位读者可以参考这篇博客:https://www.jianshu.com/p/fbd748a533e1

  • 接下来,我们来认识下ViewRootImpl类的相关功能:
    在这里插入图片描述

  • View的三大流程主要涉及到的核心类,笔者列在下面了:
    在这里插入图片描述

  • 手势分发
    在这里插入图片描述
    具体逻辑可以参考靠=笔者之前写的博客:https://blog.csdn.net/qq_36828822/article/details/103658941

  • 如何获取栈顶的activity以及监听activity前后台切换

总所周知:Android的sdk并没有提供相关的api。那么,我们如何设计一个管理任务栈的工具类呢?

package com.example.myapplication.demo

import android.app.Activity
import android.app.Application
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import java.lang.ref.WeakReference

class ActivityManager private constructor() {
    private val activityRefs = ArrayList<WeakReference<Activity>>()
    private val frontbackCallback = ArrayList<FrontBackCallback>()
    private var activityStartCount =0
    private var front = true

    fun init(application: Application){
        application.registerActivityLifecycleCallbacks()
    }

    inner class InnerActivityLifecycleCallbacks:ActivityLifecycleCallbacks{
        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
            activityRefs.add(WeakReference(activity))
        }

        override fun onActivityStarted(activity: Activity) {
            activityStartCount++
            //activityStartCount>0 说明应用处于可见状态,也就是应用在前台
            //!front 之前是不是在后台
            if(!front && activityStartCount>0){
                front = true
                onFrontBackChanged(front)
            }
        }

        override fun onActivityResumed(activity: Activity) {
        }

        override fun onActivityPaused(activity: Activity) {
        }

        override fun onActivityStopped(activity: Activity) {
            activityStartCount--;
            if(activityStartCount<=0&&front){
                front = false
                onFrontBackChanged(front)
            }
        }

        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
        }

        override fun onActivityDestroyed(activity: Activity) {
            for (activityRef in activityRefs){
                if(activityRef!=null && activityRef.get()==activity){
                    activityRefs.remove(activityRef)
                    break
                }
            }
        }

    }

    private fun onFrontBackChanged(front: Boolean){
        for (callback in frontbackCallback){
            callback.onChanged(front)
        }
    }

    val topActivity:Activity?
        get() {
            if (activityRefs.size<=0){
                return null
            }else{
                return activityRefs[activityRefs.size-1].get()
            }
            return null
        }

    fun addFrontBackCallback(callback: FrontBackCallback){
        frontbackCallback.add(callback)
    }

    fun removeFrontBackCallback(callback: FrontBackCallback){
        frontbackCallback.remove(callback)
    }

    interface FrontBackCallback {
        fun onChanged(front: Boolean)
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/935901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker之私有仓库 RegistryHabor

目录 一、Docker私有仓库&#xff08;Registry&#xff09; 1.1 Registry的介绍 二、搭建本地私有仓库 2.1首先下载 registry 镜像 2.2在 daemon.json 文件中添加私有镜像仓库地址 2.3运行 registry 容器 2.4Docker容器的重启策略 2.5为镜像打标签 2.6上传到私有仓库 2…

SpringBoot+MyBatisPlus+MySql+vue2+elementUi的案例、java访问数据库服务、java提供接口服务

文章目录 前言后端关键代码前端关键代码完整代码 前言 1、项目不使用前后端分离。 2、在创建SpringBoot的时候要注意各个插件间的版本问题。 3、后端技术SpringBootMyBatisPlusMySql。 4、前端技术vue2elementUi。 后端关键代码 简单介绍 1、数据库名称ssm_db 2、表名称tbl_bo…

「MySQL-03」用户管理与给用户授权

目录 一、用户管理 1. 用户信息 2. 创建用户 3. 删除用户 4. 修改用户密码 二、给用户授权 0.MySQL数据库提供的权限列表 1. 给用户授权 2. 回收权限 一、用户管理 1. 用户信息 1.0 数据库mysql和user表 安装好 MySQL后&#xff0c;里面会有一个默认的数据库mysql里面有一个u…

保姆级 Keras 实现 Faster R-CNN 十

保姆级 Keras 实现 Faster R-CNN 十 一. 建议区域矩形二. 定义 ProposalLyaer1. __init__函数2. build 函数3. call 函数3.1 生成 anchor_box3.2 找出 anchor 处最大分数, 最大分数对应的 anchor_box 和修正参数3. 3 修正 anchor_box3.4 完成 call 函数 4. compute_output_shap…

高精度地图定位在高速公路自动驾驶系统中的应用

近年来随着汽车保有量不断增加&#xff0c;随之而来的是: ( 1) 严重的交通拥堵&#xff0c;通行效率低下&#xff0c;用在通行上的时间不断增加; ( 2) 交通事故频发&#xff0c;交通事故导致的伤亡人数和费用不断增加&#xff0c;而且绝大多数事故是由人为因素导致的; ( 3) 大气…

视频批量剪辑利器!轻松在固定的位置上添加str字幕,

在如今的数字时代&#xff0c;视频内容的制作和分享变得越来越普遍。如果你是一个视频创作者&#xff0c;或者经常需要编辑和分享视频内容&#xff0c;那么我们为你带来了一款视频批量剪辑工具&#xff0c;让你轻松在固定位置添加字幕&#xff0c;打造专业级剪辑效果&#xff0…

Markdown中的LaTeX公式详解

引言 LaTeX是一种用于排版科学和数学文档的排版系统&#xff0c;它能够以高质量的方式生成复杂的数学公式。在CSDN&#xff08;Cnblogs和CSDN&#xff09;这样的博客平台中&#xff0c;也支持使用LaTeX语法插入数学公式。本文将详细介绍在CSDN中使用LaTeX公式的方法和常用语法&…

开源代码扫描工具 Socket新增对 Go 生态系统的支持

导读继日前宣布完成 2000 万美元的 A 轮融资后&#xff0c;开源代码扫描工具 Socket 紧接着宣布新增了对 Go 语言的支持&#xff1b;此前其仅支持 JavaScript 和 Python 语言。 “在过去的几个月中&#xff0c;我们观察到针对 Golang 的供应链攻击有所增加。意识到这种迫在眉睫…

聚类分析 | MATLAB实现基于FCM模糊C均值聚类结果可视化

聚类分析 | MATLAB实现基于FCM模糊C均值聚类结果可视化 目录 聚类分析 | MATLAB实现基于FCM模糊C均值聚类结果可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 FCM模糊C均值聚类&#xff0c;聚类结果可视化&#xff0c;MATLAB程序。 FCM&#xff08;Fuzzy C-Means&a…

【KafkaStream】简单使用

Kafka Stream是什么 Kafka Streams是一套客户端类库&#xff0c;它可以对存储在Kafka内的数据进行流式处理和分析。 1. 什么是流处理 流处理平台&#xff08;Streaming Systems&#xff09;是处理无限数据集&#xff08;Unbounded Dataset&#xff09;的数据处理引擎&#x…

C++的静态栈以及有点鸡肋的array数组

目录 1.静态栈 1.举例展示 2.注意事项 2.array 1.静态栈 1.举例展示 1.我们想到栈&#xff0c;就会想到是一个数组来维护它的&#xff0c;并且一般由于不知道存储的多少内容&#xff0c;所以一般都是用动态数组不断的在堆上开辟新的空间。 但是C支持了一个新的语法就是静…

【Java基础增强】类加载器和反射

1.类加载器 1.1类加载器【理解】 作用 负责将.class文件&#xff08;存储的物理文件&#xff09;加载在到内存中 1.2类加载的过程【理解】 类加载时机 创建类的实例&#xff08;对象&#xff09; 调用类的类方法 访问类或者接口的类变量&#xff0c;或者为该类变量赋值 …

机器学习实战笔记(蜥蜴书)—— 第二章:端到端项目

目录 前言机器学习前的准备工作1、机器学习需要用到的库&#xff1a;安装&#xff1a;文件导入库 2、所用工具 数据准备1、获取数据2、检查数据3、创建训练/测试集 数据可视化数据预处理1、缺失值处理2、文本属性处理3、数据集添加其他列4、数值缩放5、得到预处理的数据 模型建…

Rabbitmq消息积压问题如何解决以及如何进行限流

一、增加处理能力 优化系统架构、增加服务器资源、采用负载均衡等手段&#xff0c;以提高系统的处理能力和并发处理能力。通过增加服务器数量或者优化代码&#xff0c;确保系统能够及时处理所有的消息。 二、异步处理 将消息的处理过程设计为异步执行&#xff0c;即接收到消息…

STM32 Cubemx 同名外设中断及回调

文章目录 前言示例工程个人理解 前言 最近在学习STM32&#xff0c;采用HAL库开发方式。记录一下同名外设中断及回调。 这里提及的同名外设指USART1/2之类的相同外设&#xff0c;但不是同一个instance。 示例工程 以使用cubemx配置两个同名外设EXTI0/EXT4为例。 在NVIC配置…

QPainter主要功能说明与使用

图形填充QBrush主要功能&#xff1a; QBrush类定义QPaint绘制的形状的填充图案。 函数原型功能void setColor(QColor &color)设置画刷颜色&#xff0c;实体填充时即填充颜色void setStyle(Qt::BrushStyle style)设置画刷填充样式&#xff0c;参数为枚举类型Qt::BrushStyl…

在vue项目中用vue-watermark快捷开发屏幕水印效果

我们先引入一个第三方依赖 npm install vue-watermark然后 因为这只是个测试工具 我就直接代码写 App.vue里啦 参考代码如下 <template><div><vue-watermark :text"watermarkText"></vue-watermark><!-- 正常的页面内容 --></div…

Git基本操作(Idea版)

第一次发布项目&#xff08;本地->远程&#xff09; 方式一 通过push的方式推送本地库到远程库&#xff08;远程已创建好仓库&#xff09; 这种方式需要提前创建好仓库。 右键点击项目&#xff0c;可以将当前分支的内容 push 到 GitHub 的远程仓库中。 注意&#xff1a…

2023/8/27周报

目录 摘要 论文阅读 1、标题和现存问题 2、过度平滑和度量方法 3、处理过坡 4、实验结果 深度学习 1、解决可视化问题 2、CART算法 总结 摘要 本周在论文阅读上&#xff0c;阅读了一篇Pairnorm:解决GNNS中的过平滑问题的论文。PairNorm 的核心思想是在图卷积层之间引…

LeetCode——回溯篇(一)

刷题顺序及思路来源于代码随想录&#xff0c;网站地址&#xff1a;https://programmercarl.com 目录 77. 组合 216. 组合总和 III 17. 电话号码的字母组合 39. 组合总和 40. 组合总和 II 77. 组合 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的…