目录介绍
https://segmentfault.com/a/1190000019111141
- 10.0.0.1 Window是什么?如何通过WindowManager添加Window(代码实现)?WindowManager的主要功能是什么?
- 10.0.0.2 Window概念解析?WindowSession的创建过程是怎样的?WindowSession的作用?Token的使用场景?
- 10.0.0.3 Activity、View、Window三者之间的关系,Window有哪几种类型?
- 10.0.0.5 Activity的启动过程是怎样的?Activity创建和Dialog创建过程的异同?
- 10.0.0.6 如何处理快速连续点击了多次按钮时Toast就触发了多次而关闭不掉?
- 10.0.0.7 DecorView何时才被WindowManager真正添加到Window中?Window的addView源码分析?
- 10.0.0.8 Dialog的Window创建过程?为什么Dialog不能用Application的Context?
- 10.0.0.9 什么是DecorView?如何获取到DecorView?DecorView的职责是什么?DecorView如何被加载到Window中?
- 10.0.1.0 DecorView如何显示出来,为什么setContentView()设置的界面,为什么在onResume()之后才对用户可见呢?
- 10.0.1.1 什么是ViewRoot?ViewRoot属于View树的一份子吗?ViewRoot的工作流程是怎么样的?
- 10.0.1.2 吐司为何会出现内存泄漏?在Toast构造方法中创建NT对象是干什么用的?Toast是怎么show出来的?
- 10.0.1.3 连续吐司是如何确定吐司的先后顺序?为什么Toast执行show后过了一会儿就自动销毁?
- 10.0.1.4 如何理解普通应用的Toast显示数量是有限制的?为什么要判断是否是系统吐司?为何Activity销毁后Toast仍会显示?
- 10.0.1.5 为什么说Toast尽量用全局上下文?说一下Toast的显示和隐藏重点逻辑,说下你的理解?
- 10.0.1.6 Toast报错Unable to add window是什么意思?Toast运行在子线程会问题,在子线程或者service中能运行吗?
- 10.0.1.7 为什么建议用DialogFragment替代Dialog?如何定义DialogFragment样式?使用dialogFragment有何好处?
- 10.0.1.8 Dialog的Window创建过程是怎样的?为什么Dialog不能用Application的Context,说一下原因?
- 10.0.1.9 Dialog和Window有什么关系?Dialog的dismiss和cancel()方法都可销毁弹窗,它们有什么区别?
- 10.0.2.0 PopupWindow中不设置为什么必须设置宽高?PopupWindow和Dialog有什么区别?说下创建和销毁的大概流程?
- 10.0.2.1 Snackbar与吐司有何区别在哪里?Snackbar控件show时为何从下往上移出来?为什么显示在最下面?
- 10.0.2.2 说一下Snackbar和SnackbarManager类的设计有哪些奥妙的地方,如何处理消息的显示顺序?
好消息
- 博客笔记大汇总【15年10月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计500篇[近100万字],将会陆续发表到网上,转载请注明出处,谢谢!
- 链接地址:https://github.com/yangchong2...
- 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变!
弹窗博客笔记汇总
-
- 最简单的创建,简单改造避免重复创建,show()方法源码分析,scheduleTimeoutLocked吐司如何自动销毁的,TN类中的消息机制是如何执行的,普通应用的Toast显示数量是有限制的,用代码解释为何Activity销毁后Toast仍会显示,Toast偶尔报错Unable to add window是如何产生的,Toast运行在子线程问题,Toast如何添加系统窗口的权限等等
-
- 最简单的使用方法,onCreate(@Nullable Bundle savedInstanceState)源码分析,重点分析弹窗展示和销毁源码,使用中show()方法遇到的IllegalStateException分析
-
- AlertDialog源码分析,通过AlertDialog.Builder对象设置属性,Dialog生命周期,Dialog中show方法展示弹窗分析,Dialog的dismiss销毁弹窗,Dialog弹窗问题分析等等
-
- 显示PopupWindow,注意问题宽和高属性,showAsDropDown()源码,dismiss()源码分析,PopupWindow和Dialog有什么区别?为何弹窗点击一下就dismiss呢?
-
- 最简单的创建,Snackbar的make方法源码分析,Snackbar的show显示与点击消失源码分析,显示和隐藏中动画源码分析,Snackbar的设计思路,为什么Snackbar总是显示在最下面
-
- DialogFragment使用中show()方法遇到的IllegalStateException,什么常见产生的?Toast偶尔报错Unable to add window,Toast运行在子线程导致崩溃如何解决?
-
- 你会发现,在这个弹窗封装库中,很多地方用到了builder模式,那么可以先了解下Builder模式使用场景,简单案例,Builder模式实际案例Demo展示,看看AlertDialog.Builder源代码如何实现,为什么AlertDialog要使用builder模式呢?builder模式优缺点分析。
10.0.0.1 Window是什么?如何通过WindowManager添加Window(代码实现)?WindowManager的主要功能是什么?
-
Window是什么?
- 表示一个窗口的概念,是所有View的直接管理者,任何视图都通过Window呈现(点击事件由Window->DecorView->View; Activity的setContentView底层通过Window完成)
- Window是一个抽象类,具体实现是PhoneWindow
- 创建Window需要通过WindowManager创建
- WindowManager是外界访问Window的入口
- Window具体实现位于WindowManagerService中
- WindowManager和WindowManagerService的交互是通过IPC完成
-
如何通过WindowManager添加Window(代码实现)?
-
如下所示
//1. 控件 Button button = new Button(this); button.setText("Window Button"); //2. 布局参数 WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, 0, 0, PixelFormat.TRANSPARENT); layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; layoutParams.gravity = Gravity.LEFT | Gravity.TOP; layoutParams.x = 100; layoutParams.y = 300; // 必须要有type不然会异常: the specified window type 0 is not valid layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; //3. 获取WindowManager并添加控件到Window中 WindowManager windowManager = getWindowManager(); windowManager.addView(button, layoutParams);
-
-
WindowManager的主要功能是什么?
-
添加、更新、删除View
public interface ViewManager{ public void addView(View view, ViewGroup.LayoutParams params); //添加View public void updateViewLayout(View view, ViewGroup.LayoutParams params); //更新View public void removeView(View view); //删除View }
-
10.0.0.2 Window概念解析?WindowSession的创建过程是怎样的?WindowSession的作用?Token的使用场景?
-
Window概念解析?
- Window和View通过ViewRootImpl建立联系
- Window并不是实际存在的,而是以View的形式存在
- WindowManager的三个接口方法也是针对View的
- 实际使用中无法直接访问Window,必须通过WindowManager
- View是视图的呈现方式,但是不能单独存在,必须依附在Window这个抽象的概念上
- WMS把所有的用户消息发给View/ViewGroup,但是在View/ViewGroup处理消息的过程中,有一些操作是公共的, Window把这些公共行为抽象出来, 这就是Window。
-
WindowSession的创建过程是怎样的?
- 在WindowManager的addView中会创建ViewRootImpl,内部会通过WMS去获取WindowSession
- WindowSession的类型是IWindowSession,本身是Binder对象,真正实现类是Session
-
WindowSession的作用?博客
- 表示一个Active Client Session
- 每个进程一般都有一个Session对象
- 用于WindowManager交互
-
Token的使用场景?
- Popupwindow的showAtLocation第一个参数需要传入View,这个View就是用来获取Token的。
- Android 5.0新增空间SnackBar同理也需要一个View来获取Token
-
Token是什么?
- 类型为IBinder,是一个Binder对象。
-
主要分两种Token:
- 指向Window的token: 主要是实现WmS和应用所在进程通信。
- 指向ActivityRecord的token: 主要是实现WmS和AmS通信的。
-
Activity中的Token
- ActivityRecord是AmS中用来保存一个Activity信息的辅助类。
- AMS中需要根据Token去找到对应的ActivityRecord。