四大组件
Activity
生命周期
生命周期衍生
- onSaveInstanceState 调用时机
在onStop()方法回调之前,系统会自动调用onSaveInstanceState(Bundle outState)
该方法用于存储当前Activity状态,并在onCreate时拿到之前保存的数据
-
onSaveInstanceState 使用场景
- 存储数据为bundle,一定是可序列化的数据
- 页面被异常销毁,需要存储之前显示状态
- 如屏幕旋转,切换深色模式都会导致页面重建,保存用户当前浏览状态可以提高用户体验
-
页面旋转不重建页面
配置的变化都会导致页面重建,如果想要在配置发生变化时不重建页面,可进行如下设置
- manifest增加权限
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
- activity 增加状态监听
android:configChanges="orientation|keyboard"
-
onConfigurationChanged
回调中处理变化的属性 -
开源库 LifeCycle
https://www.jianshu.com/p/1ae41dc6c828
Activity启动模式
4个启动模式
- standard :默认模式,直接在栈顶加入一个
- singleTop:栈顶复用模式,当前栈顶已经存在该页面会直接复用
- singleTask:栈内只存在一个实例,若已有该实例,复用该实例,其上方的实例全部出栈
- singleInstance:单独存在于一个堆栈中
2个使用方式
- manifest中配置
- intent添加flag
- FLAG_ACTIVITY_CLEAR_TOP -> singleTask
- FLAG_ACTIVITY_SINGLE_TOP -> singleTop
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS ->
android:excludeFromRecents="true"
不会出现在最近任务
taskAffinity
可以为activity指定存放的堆栈名,只和singleTask
启动模式共同使用
不可声明为包名,因为默认堆栈名为包名
Activity 打开方式
显式启动
指定包名类名启动,常见于应用内部页面间跳转
隐式启动
声明action,category
Activity启动流程(重要)
https://www.jianshu.com/p/56023d8902ee
时序图已经比较细致,过一遍文章然后看时序图即可
Service
启动方式
- startService:不可操作Service,调用方销毁时不影响Service
- bindService:可以操作Service,调用方销毁时Service也会被回收
进程保活
1px大小Activity
监听系统广播,锁屏时启动一个1px大小的页面放置左上角,亮屏时关闭。背景透明,无启动动画。
前台服务
- API<18,startForeground(ID, new Notification())发送空的通知,图标不会显示
- API>=18,需要提高优先级的ServiceA启动一个InnerService,2个服务同时startForeground,且绑定同一个ID,然后Stop掉InnerService,图标会被移除。
相互唤醒
同一系的应用,其中一个应用启动会把其他的应用唤醒
AndroidN之前,可以监听系统广播唤醒。
ContentProvider
BroadcastReceiver
注册方式
静态注册
Manifest中声明,接收广播的优先级低,在无序广播时,晚于动态注册。
新特性:Android8.0以后静态注册的广播无法通过隐式的方式调用,必须指定包名
动态注册
Java代码中实例化一个Receiver,通过registerReceiver的方式注册
广播类型
默认广播(无序)
context.sendBroadcast方法发送广播,每个接受者都可以收到广播,互相无影响,接受者无法中止广播。
有序广播
context.sendOrderedBroadcast 发送广播,接受者需要定义优先级,传递从高优先级传递至低优先级,高优先级有能力中止传送
应用场景:辣鸡短信拦截。
View
Fragment
生命周期
使用
Fragment fragment1 = new Fragment1();
getFragmentManager().beginTransaction().replace(R.id.main_layout,fragment1).commit();
- 获取FragmentManager
- 开启一个事物,可以通过beginTransaction() 方法获取
- 加入fragment,一般通过replace实现
- 提交事物commit
数据通信
Arguments(Bundle)
延伸
replace/add/remove
replace :直接替换
add/remove:可以一直往里添加,不可重复添加
共同点
replace/add 时都会走生命周期
差异点
每次replace都要走生命周期,add时走了一次之后,后面可以通过show/hide方法动态控制Fragment的显示,此时不会再重走生命周期
应用于ViewPager
多tab页面一般基于ViewPager去做,ViewPager不仅可以展示图片,简单布局等,也可以展示Fragment
FragmentPagerAdapter与FragmentStatePagerAdapter的区别
- FragmentPagerAdapter:不需要的Fragment,仅销毁视图,不销毁实例,适用于3-4个tab的页面
- FragmentStatePagerAdapter:不需要的Fragment,销毁视图和实例,适用于很多页面的ViewPager,节省内存。可以再onSaveInstcanceState时存储状态,onCreate时还原状态。缺陷是重建会耗时。
坑(面试回答用)
- 所有add进来的Fragment都是visible的,需要手动控制show hide
如果仅add去覆盖,会导致点击事件的透传
- 为了节省内存提高展示效率,一般使用add添加
ListView
使用
缺陷
- 不支持局部刷新
- 不支持宫格显示
- 不支持点击事件(无接口)需要手写clickListener
- 不支持动画
二级缓存(缓存View)
1.activeViews :缓存界面上活跃的View (第一级缓存很少被利用起来,几乎很少发挥作用)
作用:作用几乎很小,低版本的Android 在首次刷新界面的时候可能会重复的onLayout,不同sdk的首次渲染到屏幕上的onLayout次数是不同的,所以一级缓存是复用界面上已有的View,避免首次重复onLayout
2.复用划出界面的View避免重复的绑定(findViewById)
ScrapViews数组列表(二维)
通过ViewType找到被缓存的View,重新加载数据
ListView的RecycleBin对应RecyclerView的Recycler
使用
RecyclerView
使用
LayoutManager
Animator
Adapter
遇过的坑(面试可以装逼用)
- getItemId(int position)
这个id应当是独一无二的
在做删除动画时,出现remove+notifyRangeChanged时闪退,报下标越界的问题,识别item的唯一标识就是通过这个id判断
四级缓存
各级缓存意义的区别:
一级缓存:意义是为了重新更新界面上已有的UI(与复用无关)
二三四级缓存:复用UI
两种缓存类型
Scrap (view):在布局期间进入临时分离状态的子视图。指那些连数据都不需要改变的ViewHolder (第一级缓存)
Recycle (view):先前用于显示适配器特定位置的数据的视图可以放置在高速缓存中以供稍后重用再次显示相同类型的数据。这可以通过跳过初始布局或构造来显着提高性能。类型相同的ViewHolder (其他级缓存)
一级缓存:mAttachedScrap 和 mChangedScrap ,用来缓存还在屏幕内的 ViewHolder(实际上不是缓存,只是暂存,就是在一次界面的重新布局的时候暂存View,onLayout结束的时候即使有没复用到的View也会从mAttachedScrap中移除到RecycledViewPool中)
mAttachedScrap 存储的是当前还在屏幕中的 ViewHolder;按照 id 和 position 来查找 ViewHolder
mChangedScrap 表示数据已经改变的 ViewHolder 列表, 存储 notifyXXX 方法时需要改变的 ViewHolder
一般调用adapter的notifyItemRangeChanged被移除的viewholder会保存到mChangedScrap,其余的notify系列方法 (不包括notifyDataSetChanged)移除的viewholder会被保存到mAttachedScrap中
二级缓存:mCachedViews ,用来缓存移除屏幕之外的 ViewHolder,默认情况下缓存容量是 2,可以通过 setViewCacheSize 方法来改变缓存的容量大小。如果 mCachedViews 的容量已满,则会根据 FIFO 的规则移除旧 ViewHolder,这里被复用的View不会触发onBindViewHolder
三级缓存(可略):ViewCacheExtension ,开发给用户的自定义扩展缓存,需要用户自己管理 View 的创建和缓存。个人感觉这个拓展脱离了 Adapter.createViewHolder 使用的话会造成 View 创建 与 数据绑定及其它代码太分散,不利于维护,使用场景很少仅做了解
四级缓存:RecycledViewPool ,ViewHolder 缓存池,在有限的 mCachedViews 中如果存不下新的 ViewHolder 时,就会把 ViewHolder 存入RecyclerViewPool 中。
ConstraintLayout
特色
优点
基础Layout
- FrameLayout
- LinearLayout
- RelativeLayout
本文由 bt 创作,采用 知识共享署名4.0 国际许可协议进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。