Service
- service和线程的区别和场景
- 安卓线程(主线程-包括UI控件的绘制和事件响应,工作线程)
- 一般的线程还可以执行一些耗时的异步操作,一般不要在主线程上做耗时操作,会导致ANR
- service运行在主线程中,系统进程托管
- 如何管理service生命周期
- 生命周期1:service会通过绑定服务,进行service和Activity之间的绑定
- 生命周期2:直接去开启一个服务
- 这两种生命周期不同。但是共同点是从OnCreate开始到OnDestory结束
- service和IntentService的区别
- service不是独立的进程,是依赖于应用程序主线程,在service中进行耗时操作也会产生ANR
- IntentService中会有工作线程去处理耗时操作,任务执行完成之后IntentService会自动停止
- 启动服务和绑定服务先后次序问题
- Android只会为service创建一个实例对象
- 序列化:Parcelable和Serializable
- Binder:多进程间通信依赖Binder
service和线程的区别和场景
- Thread:程序执行的最小单元,它是分配CPU的基本单位
- UI线程:主线程中
- 工作线程(子线程):耗时异步操作
- 为了保证应用响应及时,所以尽量不在主线程做耗时操作
- Thread的声明周期
- 新建:new Thread()
- 就绪:线程已经启动了,正在等待CPU时间
- 运行:running 正在执行任务
- 死亡:dead 线程被其他线程杀死,或执行完毕
- 阻塞:block 由于某种原因,正在运行线程让出自己的CPU时间,并暂停自己的运行
- Thread的致命缺点
- 无法控制!
- Service
- Service是Android的一种机制,服务是运行在主线程上的
- 轻量级进程间通信机制,在Liunx层
- 不可以进行耗时操作
- Service的生命周期
- onCreate
- onStart
- onDestory
- onBind
- onUnbind
- 管理Service生命周期
- startSerice
- 启动之后,只会执行一次onCreate
- 但是onStartCommand()会启动多次,启动次数是与startService相同
- stopService
- onDestory
- 如果服务已经被绑定的状态下stopService是无法停止服务的
- bindService
- 绑定Service服务
- 调用onCreate onBind
- unbindServce
- 解绑Service服务
- 调用onUnbind onDestory
- startSerice
Service 和 IntentService
- 不建议在Service中编写耗时的逻辑和操作,可能会引起ANR
- IntentService
- IntentService是继承Service并处理异步请求的类
- 内部有一个工作线程HandlerThread处理耗时操作
- IntentService内部是通过消息的方式发送给HandlerThread的,然后由Handler中的Looper来处理消息。
- 执行完成之后,会自动停止
- onHandleIntent
启动服务&绑定服务
- 先绑定服务后启动服务
- 绑定的服务会转变为启动服务状态,当绑定的Activity结束时,服务并不会停止
- 先启动服务后绑定服务
- 不会转为绑定服务状态,还是会和Activity绑定。即使Activity解除绑定,服务还是回按照启动服务的生命周期进行
- 启动服务的优先级比绑定服务高
- 服务在其托管进程的主线程中运行(UI线程)
序列化:Parcelable和Serializable
- 序列化:内存中对象–>磁盘
- 反序列化:磁盘中对象–>内存
- 实现上
- Serializable:实现简单,但是内存开销大
- serialVersionUID
- Parcelable:实现复杂,内存开销小
- 在内存间传输数据,推荐使用。例如:Activity使用Intent传值(组件之间传输数据)
- Serializable:实现简单,但是内存开销大
binder应用: AIDL
- AIDL
- 进程间通信(IPC)机制
2.AIDL创建 - 创建AIDL:实体对象,新建AIDL文件,make工程
- 服务端:新建Service,创建Binder对象,定义方法
- 客户端:实现serviceConnection,BindService
- 进程间通信(IPC)机制
静态注册&动态注册
- 广播接收器 BoardcastReceiver
- 静态注册:在Manifest中
1
<receiver></receiver>
- 动态注册
- (在代码中调用Context.registerReceiver)
- 在onResume调用registerReceiver
- 在onPause销毁 unregisterReceiver
- 在onResume注册,onPause注销原因:防止内存泄露
- 特点
- 静态:常驻进程中,不受组件生命周期影响(即使应用程序关闭,如果有广播发送,程序也会被系统唤醒)
- 动态:跟随组件的生命周期变化
- 应用场景
- 静态:需要时刻监听广播(计算每隔一段时间的网络访问量)
- 动态:需要在特定时刻接收广播
- 广播接收器在接收到广播之后会自动回调onReceive()方法
- 默认广播接收器运行在UI线程(ANR注意)
Webview
- Webview常见的坑
- API16 WebView.addJavascriptInterface 攻击者使用Java反射机制,执行任意Java对象的方法
- Webview在布局文件的使用:webview写在其他容器中时
- jsbridge:通过JavaScript构建的桥,web->native
- webviewClient.onPageFinished -> webChromeClient.onProgressChanged(更推荐)
- 后台耗电:解决方法,在Activity中onDestory,一定要销毁掉webview
- Webview硬件加速导致页面渲染问题:可能会出现页面加载白块,同时界面闪烁(解决方法,暂时关闭硬件加速)
- 关于Webview的内存泄露问题(webview可能会一直持有Activity引用,不能回收)解决办法
- 独立进程,简单暴力,不过可能涉及到进程间通信
- 动态添加WebView,对传入WebView中使用的Context使用弱引用,动态添加WebView意思在布局创建个ViewGroup用来放置WebView,Activity创建时add进来,在Activity停止时remove掉
异步消息处理
Handler
- Android SDK 提供给开发者方便进行异步消息处理的类
- Handler
- Looper:轮询操作
- MessageQueue消息队列:FIFO原则的消息
- Handler:会取出当前线程的Looper,Looper从消息队列中取出消息,交给Handler处理 -> handleMessage()
- Handler发送消息,处理解决消息
- 总结:
- Looper类主要是为每个线程开启的单独的消息循环(ThreadLocal)
- Handler是Looper的一个接口
- 在非主线程中无法直接new Handler()