Android四大组件
Activity(活动): 提供界面用于交互操作。
Service(服务):用来后台执行不需要界面但是需要长时间运行的操作。
Broadcast Receiver(广播接收器):用来在应用之间传输信息。
Content Provider(内容提供器):在应用之间实现数据的共享。
Activity的状态
运行:在屏幕前台(位于当前任务堆栈的顶部)
暂停:失去焦点但仍然对用户可见(覆盖Activity可能是透明或未完全遮挡)
停止:完全被另一个Activity覆盖
销毁:退出,完全销毁
Activity的生命周期
onCreate() 活动首次创建时调用
onStart() 活动由不可见变为可见时调用
onResume() 活动准备好交互操作时调用
onPause() 系统准备启动或恢复另一个活动时调用
onStop() 活动完全看不见时调用
onDestroy() 活动销毁之前调用
onRestart() 活动重新启动时调用
Activity的四种启动模式
(1) standard 模式:默认的启动模式,每次启动Activity的时候都会创建一个新的实例,对内存消耗大。
(2) single Top 模式:栈顶复用模式,如果要创建的Activity已经在栈顶的话,直接复用不会重新创建,否则仍然会重新创建。
(3) single Task 模式:栈内复用模式。
(4) single Instance 模式:单一实例模式,会启用一个新的返回栈来管理这个活动。
几种启动模式的生命周期
- standard模式,活动在栈顶,再次启动这个活动时:
onCreate() -- onStart() -- onResume() - singleTop模式,活动在栈顶,再次启动这个活动时:
onPause() -- onResume() - singleTask模式,活动不在栈顶,再次启动这个活动时:
onRestart() -- onStart() -- onResume() 返回栈会把这个活动之上的所有活动全部出栈
ListView的优化,和RecycleView的区别
- 优化
(1) 重用convertView:convertView是用于将之前加载好的布局进行缓存,通过重用它来减少不必要的view的创建。
(2) 减少findViewById()操作:新增一个内部类ViewHolder,把控件的实例封装到其中。 - 和RecycleView的区别:
(1) ListView只能垂直方向滚动,RecycleView能实现水平,垂直,瀑布流。
(2) RecycleView 添加、删除Item时有动画效果。
(3) 监听点击事件不同,ListView 通过OnItemClickListner接口,RecycleView通过OnItemTouchListener接口,能监听更多的触摸方式。
Android的五种数据存储方式
- SharedPreferences
- 文件
- SQLite
- ContentProvider
- 网络存储
Fragment生命周期
onAttach()
onCreate()
onCreateView()
onActivityCreated()
onStart()
onResume()
onPause()
onStop()
onDestroyView()
onDestroy()
onDetach()
Sevice生命周期
onCreate() 服务创建的时候调用
onStartCommand() 每次服务启动的时候调用
onDestroy() 服务销毁的时候调用
Activity的UI层级
Activity > PhoneWindow > DecorView > ViewGroup
PhoneWindow是Activity和View进行交互的接口,由WindowManager来管理
DecorView本质是一个FrameLayout,是Activity中所有View的祖先
View绘制流程
页面布局是一个树形结构,绘制就是从上到下进行整个遍历,每个View负责绘制自己和通知自己的子View进行绘制。
- onMeasure(测量):测量View的大小。从顶层View到子View递归调用measure方法。
- onLayout(布局):确定View在父容器的位置,进行布局。
- onDraw(绘制):绘制View显示出来。
三个方法在ViewRootImpl类中
MeasureSpec是什么
MeasureSpec是View类中的一个静态内部类,是个32位的整数值,前2位负责表示测量模式,后30位负责该模式下的规格大小。
- UNSPECIFIED:未指定模式。一般用于系统内部,开发时很少使用。
- EXACTLY:精确 模式。视图的 layout_width 或者 layout_height 指定为具体数值或者 match_parent 时。
- AT_MOST:最大值模式,视图的 layout_width 或者 layout_height 指定为 wrap_content 时生效,此时子视图的尺寸可以是不超过父视图运行的最大尺寸的任何尺寸。
View事件分发机制
dispatchTouchEvent()
onInterceptTouchEvent()
onTouchEvent()
一个触摸事件,首先调用ViewGroup的dispatchTouchEvent方法,这个方法调用onInterceptTouchEvent方法,用于判断是否拦截该事件,如果拦截则调用onTouchEvent,否则传递给子View。
Android创建子线程的两种方式
- 直接创建Thread类对象
- 实现Runnable接口
Handler机制
- Message:线程之间传递的消息,携带少量信息。
- Handler:处理者,用于发送和处理消息。
- MessageQueue:消息队列,存放所有Handler发送的消息,每个线程有一个MessageQueue。
- Looper:MessageQueue的管家,MessageQueue中有消息时就会取出来传递给Handler。
子线程刷新UI
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long);
AsyncTask
把Handler和Thread进行封装的异步执行框架,用于耗时较短的异步操作。
IPC机制
进程间通信
- Bundle通过Intent传递数据
- 文件共享
- ContentProvider
- 基于Binder的:Message、AIDL、Socket
Android布局优化
- 常用相对布局,因为一般情况下线性布局比相对布局的层级深。
- 常用布局标签include、merge、ViewStub
- 使用最新的布局方式ConstraintLayout
内存溢出(OOM)和内存泄漏
内存溢出:是指程序申请内存时,系统没有足够的内存供其使用。
内存泄漏:是指程序在申请内存后,无法释放已申请的内存空间。
常见OOM:加载大图片。
常见内存泄漏
- 单例模式传入Activity的Context:因为单例模式的生命周期和Application一样长,当Activity退出时,单例对象仍持有该Activity的引用,内存不会被回收。解决方法,传入Application的Context。
- 非静态内部类创建静态实例:静态实例的生命周期和应用一样长,内部类会传入外部类的引用,就导致Activity一直被引用不能正常回收。解决方法,内部类抽取出来封装成单例。
- 创建Handler的非静态匿名内部类的实例: 当Activity退出时消息队列中还有未处理完的消息,实例会持有Activity的引用,不能正常回收。解决方法,创建一个静态Handler内部类,对Handler持有的对象使用弱引用,Activity退出时,移除消息队列中的消息。
- 新建线程创建匿名内部类(例如Runnable),Activity退出时任务还未完成,内存不能回收。解决方法,使用静态内部类,Activity销毁时,取消相应的任务。
- 资源未关闭,例如File、Cursor、Bitmap。解决方法:Activity销毁时及时关闭。
加载大图片的方法
BitmapFactory中有个Options类,用于解码Bitmap时的各种参数控制。
inJustDecodeBounds参数:为true时,只会解析图片的宽和高,不会把图片加载到内存中。
inSampleSize参数:即采样率,例如设置为4,分辨率宽和高将为原来的1/4,内存变为原来的1/16。
- inJustDecodeBounds设为true,不读取图片到内存中,仅读取图片大小。
- 获取屏幕的分辨率,计算出合适的采样率。
- inJustDecodeBounds设为false,按照设定的采样率把图片加载到内存中。
图片的三级缓存
- 内存缓存,缓存在内存中,基于LRU算法(最近最少使用淘汰),机器重启后消失。
- 本地缓存,一般是键值对形式。
- 网络缓存,从网络加载资源,然后缓存在内存、本地中。
ANR
应用程序无响应
四种情况:
- 5秒内无法响应屏幕触摸事件或键盘输入事件
- 前台服务20秒内,后台服务在200秒内没有执行完毕。
- 在执行前台广播(BroadcastReceiver)的onReceive()函数时10秒没有处理完成,后台为60秒。
- ContentProvider的publish在10s内没进行完。
ANR分析方法:
- traces.txt文件
- log分析
避免ANR:
避免在主线程进行复杂耗时的操作,特别是文件读取或者数据库操作。
如何保证Service在后台不被杀死
- 修改onStartCommand() 方法的返回值为START_STICKY,可以实现服务停止后重启服务。
- 提升service的优先级。修改intent-filter中的android:priority属性,数值越大优先级越高,最大1000。
- 提升service所在进程的优先级。
- onDestroy()方法中重启service。
广播的种类、注册方式
标准广播:广播发出之后,所有广播接收器同时受到。
有序广播:发出之后接收器按照优先级顺序先后受到。
两种注册方式
动态注册:带代码中注册,只有程序运行的时候才监听,程序关闭后不再监听。
静态注册:在AndroidManifest.xml中注册,无论程序是否运行,都进行监听。
MVC、MVP、MVVM
MVC
- View:视图
- Controller:控制器
- Model:业务数据
三个部分之间为单向通信
MVP
把MVC中的Controller替换成Presenter,View和Model不进行联系全通过Presenter通信。
MVVM
把Presenter替换成ViewModel,View和ViewModel之间采用双向绑定,View的变动自动反映在ViewModel中。
RecyclerView的性能优化
onBindViewHolder方法是在UI线程进行的,减少该方法中的耗时操作。
分页加载远端数据,对拉取的远端数据进行缓存,提高二次加载速度。
对item进行布局优化。
通过重写onViewRecycled()来回收资源。
应用的性能优化
四点:流畅、稳定、省电省流量、安装包小
性能优化详解
网友评论