Android 四大组件
- 四大组件的分类
注册方式上
Activity Service ContentProvider 必须在AndroidManifest中注册,BroadcastReceiver可以在清单文件注册,也可以在代码中注册
调用方式上
Activity Service BroadcastReceiver必须借助Intent启动,ContentProvider不需要
Service
- Service有两种状态 启动状态和绑定状态
- Service启动方式有显示启动和隐式启动
同一个包中,显示启动和隐式启动都可以用,不同包只能用隐式启动
隐士启动通过设置Action的方式启动
***** 需要注意的是在5.0上采用隐式启动时,会出现java.lang.IllegalArgumentException: Service Intent must be explicit异常。也就是说Service的Intent必须明确。
解决方法就是给Intent设置一下具体的包名,指明具体是哪个包启动的Service。
intent.setPackage("com.android.vending")
或者通过给Intent设置ComponentName的方式启动
或者通过隐式Intent反查找Component转化成显示Intent启动。
- Service 本身运行与主线程中
- ContentProvider 中的query,insert,delete,update运行与binder线程池中
- ContentProvider不需要手动停止
-
Instrumentation 主要功能完成Application,Activity实例的创建,生命周期调用的具体实现。
-
Activity的启动流程
一张简单泳道图 从startActivity()开始
- Activity 的Context mBase (getBaseContext)赋值是在attach中的attachBaseContext方法中,创建是在ActivityThread中的performLaunchActivity中创建的Context,传递给Activity.
Context appContext = createBaseContextForActivity(r, activity);
-
Activity App的Context创建实现都是在ContextImpl中实现
- BroadCastReceiver不能bindService,会报错,具体看ContextImpl
- onStartCommand方法返回值意义:
- START_STICKY
服务被异常杀死后,会被重新调起,但传入onStartCommand的Intent为null,适用于不执行命令的媒体播放器,无限期运行等待着工作的到来
- START_NOT_STICKY
服务被杀死后就退出了启动状态,除非重新调用startService启动服务,不然服务不会运行。
- START_REDELIVER_INTENT
服务被异常Kill后,系统会重启服务,并且保留kill之前的Intent,并且在该服务调用stopSelf之前,一直保留Intent,适用于应该立即恢复正在执行的工作的服务,如文件下载
- START_STICKY_COMPATIBILITY
START_STICKY的兼容版本,但不保证服务被终止后一定能重启。
- BroadcastReceiver 需要在合适的时机unRegiestReceiver()
- 静态广播在应用安装时由系统完成注册,具体来说是由PMS(PackageManagerService)完成具体注册任务
除了广播外,其他三大组件也是由PMS在安装时完成注册
- onReceive()方法运行在主线程中
- Android 本地广播LocalBroadcastManager
只在app内传播的广播,为单例模式。
- ActivityThread 创建Application对象并加载ContentProvider
ActivityThread会先加载ContentProvider,然后执行Application的onCreate()
ActivityThread.handleBindApplication->LoadApk.makeApplication()->ActivityThread.installContentProviders()->mInstrumentation.callApplicationOnCreate->Applicaiton.onCreate()
- ContentProvider提供insert,delete,update,query
- ContentProvider默认在程序中都是单例的,如果指定android:multiProcess为true,则为多例,每个进程中都会有一个ContentProvider实例
- Context.getContentResolver 返回ApplicationContentResolver
- ApplicationContentResolver是ContentResolver的实现类,完成与AMS间的bind通信