Android面试(三)BroadCastReceiver和Se
BroadCastReceiver定义和应用场景
定义:在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制,Android中我们要发送的广播内容是一个intent 这个intent中可以携带我们要传送的数据
场景 : 用于接收系统的广播通知,系统会很多sd卡挂载,手机重启,广播通知,低电量,来电,来短信 等…….一些应用通过这些广播启动后台服务 电量改变广播, 必须动态注册
特点:类似于观察者模式 (一个发送 多个接收)
同一APP具有多个进程的不同组件之间的消息通信
不同app之间的组件之间消息通信
广播的种类和区别?
普通广播 : 广播可以被终止 数据可以被修改(指定接收者的广播是不可以被拦截掉的)
有序广播 : 广播不可以被终止 数据不可以被修改
本地广播 :只在app内传播
广播的注册方式
静态注册 :清单文件,注册完成就一直运行,activity应用销毁都还可以接收广播
动态注册 : 跟随activity的生命周期,activity销毁时要退出
广播内部实现原理?
1 自定义广播接收者BroadcastReceiver,并复写onRecvice()方法
2 通过binder机制向AMS(Activity Manager Service)进行注册
3 广播发送者通过binder机制向AMS发送广播
4 AMS查找符合相应条件(IntentFilter / Perrmission等)的BroadCastReceiver,将广播发送到
BroadcastReceiver(一般情况下是Activity)相应的循队列中
5 消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法
本地广播 LocalBroadcastManager介绍
1 使用它发送的广播将只在自身app内传播,因此你不必担心泄漏隐私数据
2 其它APP无法对你的App发送该广播,因为你的app根本就不可能接收到非自身应用发送的该广播,因此你不必担心有安全漏洞可以利用
3 比系统的全局广播更加高效
LocalBroadcastManager详解
1 LocalBroadCastManager高效的原因主要是因为它内部是通过Handler实现的,它的sendBroadCast()方法含义并非和我们平时所有的一样,它的sendBroadCast()方法其实是通过Handler发送一个Message实现的
2 既然内部是通过Handler来实现广播的发送的那么相比与系统广播通过binder实现那瞬下是更高效了,同时使用Handler来实现,别的应用无法向我们的应用发送该广播,而我们应用内发送的广播也不会离开我们的应用
3 LocalBroadcastManager内部协作主要是靠这两个Map集合:mReceivers和mActions,当然还有一个List集合mPendingBroadcasts,这个主要就是存储待接收的广播对象
什么是service?
1 service 是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件
2 activity和fragment销毁也不会有影响
3 在主线程中运行
4 不能做耗时操作
Service生命周期(两种)
oncreate 首次创建服务时,系统调用此方法执行一次性设置,该方法只调用一次
onbind 绑定服务时才会调用
onStartCommand 每次通过startService方法启动Service时都会被调用
ondestory 服务销毁时会调用
service启动方式
1 通过startService Service会经历 onCreate 到onStart,然后处于运行状态,stopService的时候调用onDestroy方法。如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行。
2 通过bindService Service会运行onCreate,然后是调用onBind, 这个时候调用者和Service绑定在一起。调用者退出了,Srevice就会调用onUnbind->onDestroyed方法。所谓绑定在一起就共
存亡了。调用者也可以通过调用unbindService方法来停止服务,这时候Srevice就会调用、onUnbind->onDestroyed方法。
IntentService 简介
先看 Service 本身存在两个问题:
1 Service 不会专门启动一条单独的进程,Service 与它所在应用位于同一个进程中;
2 Service 也不是专门一条新线程,因此不应该在 Service 中直接处理耗时的任务;
IntentService 特征
IntentService 是 Service 的子类,比普通的 Service 增加了额外的功能。
1 IntentService它是一个抽象类,必须创建它的子类才能使用IntentService
2 IntentService 可用于后台耗时的任务,当任务执行后会自动停止
3 IntentService 因为是服务所以优先级很高创建IntentService 必须要有一个空的构造函数 否则会报错 OnHandleIntent() 处理耗时的操作而且这个方法是在分线程中执行的
4 IntentService里执行的任务是执行完一个再执行另一个 最后一个任务执行完毕后再销毁
service里面是否可以弹对话框
//可以弹对于对话框, 需要加权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
//显示一个系统界别的dialog,即全局性质的dialog。这种dialog在任何界面下都可以弹出来。
//显示悬浮窗
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("标题")
.setMessage("内容")
.setPositiveButton("确定", null)
.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
在Service中新开线程和Activity直接新开线程的区别
(1)直接在Activity中新开一条线程来做耗时操作,当该Activity退出到桌面或其他情况时将成为一个背景进程。
(2)在Service中新启动线程,则此时Android会依据进程中当前活跃组件重要程度,将其判断为服务进程,优先级比(1)高。
四进程保活(让进程在应用中始终活着)
场景 : 开机通知只能动态注册,定位
进程被杀死 人为 第三方应用
1 android进程的优先级
* 前台进程(用户操作的进程)
* 可见进程
* 服务进程
* 后台进程
* 空进程(做缓存)
2 android进程的回收策略
* Low memory killer 通过一些比较复杂的评分机制,对进程进行打分,然后将分数高的进程判定为bad进程杀死并释放内存
* oom_odj 判别进程的优先级
3 进程保活方案
* 利用系统广播拉活 (缺限 :不能立即拉活)
* 利用系统service机制拉活(service第一次杀死 5 第二次 10 第三次 20 不再拉活,stop后不能拉活)
* 利用native进程拉活(5.0后失效)
* 利用jobScheduler机制拉活
* 利用账号同步机制拉活(新系统也失效了)