Activity与Service启动分析

Activity启动:


Laucher:
1.Instrumentation mInstrumentation负责应用程序与系统的交互操作
2.ActivityThread mMainThread 启动应用程序时加载
2.1ApplicationThread 是ActivityThread的内部类是Binder用于与ActivityManagerService交互
3.mToken Binder代理对象指向了ActivityManagerService中的ActivityRecord(每一个启动的Activity对应一个ActivityRecord,维护Activity组件的运行状态以及信息)


ActivityManagerService:
1.ActivityStack mMainStack (成员变量)描述Activity组件堆栈
ActivityStack :
1.1 mHistory 描述系统的Activity组件堆栈(对战中,每一个启动的Activity组件用ActivityRecord描述)
ActivityRecord:
1.1.1ProcessRecord app
ProcessRecord app:
1.1.1.1ApplicationThreadProxy thread
1.2 ProcessRecord 描述对应每一个应用程序的进程
1.3 ActivityManagerService mService
1.4 ActivityRecord mResumedActivity 当前激活的Activity组件
1.5 ActivityRecord mLastPausedActivity 上一次被终止的Activity组件
1.6 ActivityRecord mPausingActivity 正在被终止的Activity组件
2.mPidsSelfLocked 保存的已经创建的应用程序进程的ProcessRecord,应用程序创建成功pid>0 ,以pid为key以ProcessRecord app为valuse保存
3.mProcessNames mProcessNames.put(processName,info.uid,app)
Apk:
1.ActivityThread mMainThread 启动应用程序时加载
1.1 HashMap<IBinder,ActivityClientRecord> mActivites 描述应用程序启动的activity对应的ActivityClientRecord集合
2.1 ActivityClientRecord对应ActivityRecord(用于描述应用程序中启动的Activity组件描述
3.1LoadedApk描述一个已经加载的Apk文件

Task :任务(相关联的activity可以包含不同的进程)


Activity启动流程
1.Laucher.startActivitySafely(Intent intent,Object tag) (Laucher通过PackageManagerService根据查询条件Action Categary,应用的信息是在安装时,PackageManagerService解析AndroidManifest.xml文件获取)
2.Activity.startActivity(Intent intent)
3.Activity.startActivityForResult(Intent intent,int requestCode)
4.Instrumentation.execStartActivity(Context show,IBinder contextThread,IBinder token,Activity target,Intent intent,int requestCode)参数2.ApplicationThread,参数3.Binder代理对象,指向ActivityRecord,参数4.Laucher-->获取ActivityManagerService代理对象ActivityManagerProxy
5.ActivityManagerProxy.startActivity
1.将参数写入到Parcel data 中
2.通过ActivityManagerProxy的成员变量mRemote-->mRemote.transact(START_ACTIVITY_TRANSACTION,data,rParcel reply,0)向ActivityManagerService发送START_ACTIVITY_TRANSACTION进程间请求
6.ActivityManagerService.startActivity
7.ActivityStack.startActivityMayWait
1.通过PackageManagerService解析Intent,获取即将启动的Activity更多的信息保存在ActivityInfo aInfo
8***6.ActivityStack.startActivityLocked
1.根据Laucher传递过来的ApplicationThread创建ProcessRecord callerApp
2.根据Laucher传递过来的mToken在mHistory中找到对应的ActivityRecord然后保存在ActivityRecord sourceRecord
3.根据callerApp以及传递过来的参数创建即将启动的Activity的ActivityRecord r
9.ActivityStack.startActivityUncheckedLocked
1.检查Activity启动位标志 Intent.FLAG_ACTIVITY_NEW_TASK (决定将即将启动的Activity是放在专属任务)
1.FLAG_ACTIVITY_NEW_TASK与singleTask模式效果一样
2.FLAG_ACTIVITY_SINGLE_TOP与singleTop模式一样
3.FLAG_ACTIVITY_CLEART_TOP一般与FLAG_ACTIVITY_NEW_TASK使用
4.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS等同于XML中指定android:excludeFromRecents="true",表示该Activity不现实在历史列表里
2.检查lauchFlags的Intent.FLAG_ACTIVITY_NO_USER_ACTION==1表示非用户手动启动==0用户启动表示后面需要向源Activity发送一个用户离开通知
3.根据android:taskAffinity属性<主要和singleTask或者allowTaskReparenting属性使用>,决定将即将启动的Activity是放在专属任务,还是目前的任务,若是专属任务则判断是否存在
4.调用重载函数startActivityUncheckedLocked
4.1将即将启动的Activity对应的ActivityRecord加入到mHistory
4.2判断是否为即将启动的Activity开启新的任务,true则ActivityStack将其放在Acitity组件堆栈的最顶端
10.ActivityStack.resumeTopActivityLocked-->
1.判断ActivityStack 的mResumedActivity mLastPausedActivity mPausingActivity来决定是否启动传来的Activity以及停止源Activity(Laucher可能)让即将启动的Activity获取焦点
11.ActivityStack.startPausingLocked
1.调用ApplicationThreadProxy的schedulePauseActivity
2.向ActivityManagerService所在的线程的消息队列发送一个PAUSE_TIMEOUT_MSG mHandler.sendMessageDelayed(msg,PAUSE_TIMEOUT),在PAUSE_TIMEOUT时间内,如果
Laucher不能向ActivityManagerService发送有一个启动MainActivity通知,则认为没有响应


12.ApplicationThreadProxy.schedulePauseActivity
1.写参数到Parcel data通过mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION,data,null,Iinder.Flag_oneway),次通信请求是异步的,ActivityManagerService发送后立马返回
13.ApplicationThread.schedulePauseActivity
1.调用ActivityThread.queueOrSendMessage发送PAUSE_ACTIVITY消息
14.ActivityThread.queueOrSendMessage
1.使用handler原因:1.1当前线程可以尽快返回Binder线程池中处理其他进程请求 2.2可能涉及用户界面操作
15.H.handleMessage
1.ActivityThread.handlePauseActivity
16.ActivityThread.handlePauseActivity
1.根据ActivityRecord作为key从mActivities中获取相对应的ActivityClientRecord
2.
2.1调用performUserLeavingActivity向Laucher发送用户离开事件,即调用其onUserLeaveHint函数
2.2调用函数performPauseActivity向Laucher发送一个终止事件通知,即调用其onPause方法
2.3调用QueueWork.waitToFinish等待Laucher保存数据
3.ActivityManagerProxy.activityPaused
17.ActivityManagerProxy.activityPaused
1.写参数到Parcel data通过mRemote.transact(ACTIVITY_PAUSE_TRANSACTION,data,reply,0);
18.ActivityManagerService.activityPaused
1.ActivityStack mMainStack.activityPaused
19.ActivityStack.activityPaused
1.根据传入的参数token在mHistory中找到Laucher对应的ActivityRecord r
2.删除ActivityMangerService消息队列中PAUSE_TIMEOUT_MSG
3.mPausingActivity = r;
4.ActivityStack.completePauseLocked
20.ActivityStack.completePauseLocked
1. 1.1ActivityRecord prv=mPausingActivity ,1.2mPausingActivity = null;
2.判断系统是否正在进入睡眠或者关闭,不是则继续调用ActivityStack.resumeTopActivityLocked
21.ActivityStack.resumeTopActivityLocked
1.再次执行21步判断Laucher已经停止则执行ActivityStack.startSpecificActivityLocked
22.ActivityStack.startSpecificActivityLocked
1.ActivityManagerService中每个Activity都有一个用户ID(安装Activity组件时PackageManagerService分配)和进程名称(android:process属性)
2.判断activity对应的进程是否存在即ProcessRecord app app!=null && app.thread!=null 非空则调用realStartActivityLocked,
否则调用ActivityManagerService mService.startProcessLocekd创建应用程序进程
23.ActivityManagerService mService.startProcessLocekd
1.判断ProcessRecord是否存在,不存在创建 ProcessRecord app = new ProcessRecordLocked(null,info,processName)
2.保存app到ActivityManagerService 中的mProcessNames mProcessNames.put(processName,info.uid,app)
3.调用重载函数startProcessLocekd
3.1获取要创建的应用程序进程的用户ID和用户组ID
3.2调用int pid = Process.start创建进程
3.3创建成功pid>0 ,以pid为key以ProcessRecord app为valuse保存在ActivityManagerService mPidsSelfLocked中
3.4向ActivityManagerService所在的线程的消息队列发送一个PROC_START_TIMEOUT_MSG,应用程序创建成功需通知ActivityManagerService
以便ActivityManagerService在应用程序进程中启动Activity否则ActivityManagerService认为应用程序进程启动超时,则不能将Activity启动
24.ActivityThread.main (是在23步中Process.start中指定的进程入口)
1.创建ActivityThread对象(同时内部创建了ApplicationThread mAppThread),并调用函数attach向ActivityManagerService发送启动通知
1.1attach方法中获取ActivityManagerService代理对象,ApplicationThreadProxy.attachApplication(mAppThread)并将ApplicationThread mAppThread传递过去,用于进程间通信
2.Lopper.prepareMainLopper创建消息循环,在向ActivityManagerService发送启动通知后,是当前进程进入消息循环
25.ApplicationThreadProxy.attachApplication
1.1.写参数到Parcel data通过mRemote.transact(APPTACH_APPLICATION_TRANSACTION,data,reply,0)
26.ActivityManagerService.attachApplication
1.ActivityManagerService.attachApplicationLocked
27.ActivityManagerService.attachApplicationLocked
1.根据传入的参数pid 从mPidsSelfLocked获取ProcessRecord 并赋值给app
2.初始化ProcessRecord app.thread = 传入的ApplicationThread
3.删除ActivityMangerService消息队列中PROC_START_TIMEOUT_MSG
4.获取Activity组件堆栈顶端的ActivityRecord hr 
5.比对ProcessRecord app的app.info.uid==hr.info.applicationInfo.uid && hr.app==null && processName.equals(hr.processName)比对进程名称与用户ID,true则调用
ActivityStack mMainStack.realStartActivityLocked
28.ActivityStack mMainStack.realStartActivityLocked
1.ActivityRecord r r.app = ProcessRecord app将传入的参数ProcessRecord保存在ActivityRecord内部成员变量ProcessRecord
2.app.activities.add(r)  将传入的ActivityRecord又保存其内部的ProcessRecord app的内部成员变量activities中
3.调用app.thread 即ApplicationThreadProxy.scheduleLauchActivity
29.ApplicationThreadProxy.scheduleLauchActivity
1.写参数到Parcel data通过mRemote.transact(SCHEDULE_LAUCH_ACTIVITY_TRANSACTION)

30.ApplicationThread.scheduleLauchActivity
1.根据传入的参数封装ActivityClientRecord其中ActivityClientRecord.token = ActivityRecord r
2.调用ActivityThread.queueOrSendMessage发送LAUCH_ACTIVITY消息
31.ActivityThread.queueOrSendMessage
1.ActivityThread.mH.sendMessage
32.ActivityThread.mH.handleMessage
1.ActivityClientRecord r = (ActivityClientRecord)msg.obj
r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo)加载Apk
LoadedApk = getPackageInfoNoCheck(r.activityInfo.applicationInfo)
2.ActivityThread.handleLauchActivity
33.ActivityThread.handleLauchActivity
1.调用performLauchActivity启动Activity
2.调用handleResumeActivity将MainActivity的状态设置为Resumed表示它是系统当前激活的Activity组件
34.ActivityThread.performLauchActivity
1.ComponentName componentName = ActivityClientRecord r.intent.getComponent()获取要启动的Activity组件的包名,类名
2.ClassLoader cl = r.packageInof.getClassLoader(r)加载类文件
3.Activity activity = mInstrumentation.newActivity(cl,component.getClassName,r.intent)创建Activity对象
4.Application app = r.packageInfo.makeApplication(false,mInstrumentation)创建Application
5.ContextImpl appContext = new ContextImpl();
appContext.init(r.packageInfo,r.token,this)
appContext.setOuterContext(activity)
6.mInstrumentation.callActivityOnCreate(activity,r.state)调用Activity的OnCreate
35.MainActivity.onCreate


Service启动:
继承关系:
Context:
1. ContextWrapper 
1.1 Application
1.2 ContextThemeWrapper
1.2.1Activity
1.3 Service

ContextWrapper:
1.Context mBase 指向ContextImpl该对象在每一个Activity组件启动时,ActivityThread为其创建
ContextImpl:
1.1LoadedApk描述一个已经加载的Apk文件
1.2ActivityThread mMainThread
1.3Context mOuterContext 指向一个Activity组件

ActivityManagerService:
1.ServiceRecord r 用于描述Service组件
2.ActivityManagerService mPendingServicer.add(r);用于保存ServiceRecordd


Service启动流程:
1.Activity.onCreate()
2.ContexWrapper.startService
2.1Context mBase
3.ContextImpl.startService(Intent service)-->获取ActivityManagerService代理对象ActivityManagerProxy
4.ActivityManagerProxy.startService(IApplicationThread caller,Intent service,String resolvedType)-->参数1.ApplicationThread
1.将参数写入到Parcel data 中
2.通过ActivityManagerProxy的成员变量mRemote-->mRemote.transact(START_SERVICE_TRANSACTION,data,rParcel reply,0)向ActivityManagerService发送START_SERVICE_TRANSACTION进程间请求
5.ActivityManagerService.startService
6***8.ActivityManagerService.startServiceLocked
1.首先去ActivityManagerService查找对应的ServiceRecord,不存在才创建ServiceRecord 区别与Activity没有查询而是直接创建,因为Service只能被启动一次
7.ActivityManagerService.bringUpServiceLocked
1.根据Service android:process属性 ServiceRecord r所描述的用户ID在ActivityManagerService查找ProcessRecord app,进程存在,则调用realStartServiceLocked启动Service,否则调用startProcessLocked
2.ActivityManagerService mPendingServicer.add(r);
8.ActivityManagerService.startProcessLocked
1.调用 Process.start创建进程

9.ActivityThread.main
10.ActivityManagerProxy.attachApplication
11.ActivityManagerService.attachApplication
12.ActivityManagerService.attachApplicationLocked
1.同Activity启动步骤即27优先启动Activity再启动Service
2.realStartServiceLocekd(ServiceRecord sr,ProcessRecord app)
13.ActivityManagerService.realStartServiceLocekd(ServiceRecord r,ProcessRecord app)
r.app = app;
1.ApplicationThreadProxy.scheduleCreateService(r,r.serviceInfo);
14.ApplicationThreadProxy.scheduleCreateService
1.1.写参数到Parcel data通过mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION,data,null,IBinder.FLAG_ONEWAY)
15.ApplicationThread.scheduleCreateService(IBinder token,ServiceInfo info)
1.将ServiceRecord封装成CreateServiceData,同Activity步骤30
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info
2.ActivityThread.queueOrSendMessage
16.ActivityThread.queueOrSendMessage
17.H.handleMessage
18.ActivityThread.handleCreateService(CreateServiceData data)
1.LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo)
2.ClassLoader cl = r.packageInof.getClassLoader()加载类文件
3.Service service =(Service) cl.loadClass(data.info.name).newInstance()//创建Service对象
4.ContextImpl appContext = new ContextImpl();
appContext.init(packageInfo,null,this)
4.Application app = r.packageInfo.makeApplication(false,mInstrumentation)创建Application
appContext.setOuterContext(service)
5.service.attach();
6.service.onCreate
7.mServices.put(data.token,service)
19.Service.onCreate


Service绑定过程:
1.Activity.onCreate
2.ContexWrapper.bindService
3.ContextImpl.bindService
3.1.将ServiceConnection封装成实现了IServiceConnection接口Binder本地对象sd
class LoadedApk
mServices 保存map mServices.put(context,map)
3.1.1绑定过的Service组件的Activity组件在LoadedApk对应一个ServiceDispatcher (负责将service组件与Activity关联一起)
3.12.HashMap<ServiceConection,LoadedApk.ServiceDispatcher> map ;以ServiceConnection未key,以ServiceDispatcher为value
3.13.从mService获取map,不存在则创建map,并保存在mService中
3.1.4.sd.getIServiceConnection()获取sd
ServiceDispatcher{//每一个绑定过Service组件的Activity组件在LoadedApk中对应有一个ServiceDispatcher
mContext指向Activity组件
mConnection指向ServiceConnection组件
mActivityThread指向与Activity组件相关联的Handler
class InnerConnection extends IServiceConnection.Stub{
WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
}
}
3.1.5.如果sd为空则创建,并且返回sd.getIServiceConnection()即将ServiceConenction封装成Binder (ServiceConection作为ServiceDispatcher成员变量,
SInnerConnection内部含有final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher成员变量,并在InnerConnection的构造函数中创建ServiceDispatcher对象)
3.2.获取ActivityManagerProxy并将sd,Intent对象以及service发送给ActvityManagerService

4.ActivityManagerProxy.bindService()
4.1.写参数到Parcel data通过mRemote.transact(BIND_SERVICE_TRANSACTION,data,reply,0)
5.ActivityManagerService.bindService(IApplicationThread caller,IBindertoken,Intent service,String resolvedType,IServiceConnection connection,int flags)
5.1.根据传入的Application获取ProcessRecord callerApp
5.2.根据传入的参数获取ServiceRecord s
5.3.AppBindRecord b  = s.retrieveAppBindingLocked(service,callerApp)//b即是用来表示ServiceRecord对象s所描述的Service组件时绑定在ProcessRecord对象callerApp所描述的进程
class ServiceRecord extends Binder{
final HashMap<Intent.FilterComparison,IntentBindRecord> bindings = new HashMap<Intent.FilterComparison,IntentBindRecord>();
public AppBindRecord retrieveAppBindingLocked(Intent intent,ProcessRecord){
Intent.FilterComparison filter = new Intent.FilterComparison(intent);
IntentBindRecord i = bindings.get(filter)
if(i==null){
i = new IntentBindRecord(this,filter);//IntentBindRecord保存在ServiceRecord的 成员变量bindings中,AppBindRecord保存在IntentBindRecord成员变量apps中
bindings.put(filter,i);
}
AppBindRecord a = i.apps.get(app);
if(a!=null){
return a;
}
a = new AppBindRecord(this,i,app);
i.apps.put(app,a);
return a;

}
}
5.4创建ConnectionRecord new ConnectionRecord(b,activity,connection,flags,clientLabel,clientIntent)此对象用来描述组件activity通过connection
绑定到ServiceRecord描述的Service并且次Activity运行在ProcessRecord对象callerApp描述的进程中
5.4判断ArrayList<ConnectionRecord>clist是否为空,为空则创建clist = new ArrayList<ConnectionRecord>c;ServiceConection s.connections.put(binder,clist);
将ConenctionRecord放到ServiceRecord的成员变量clist中
6.ActivityManagerService.bringUpServiceLocked
6.1获取ProgressRecord app
6.2判断Service所在运行的进程是否存在,存在则启动Service
7.ActivityManagerService.realStartActivityLocked
1.同启动service步骤
2.requestServiceBindingsLocked(r)
8.ApplicationThreadProxy.scheduleCreateService
9.ApplicationThread.scheduleCreateService(IBinder token,ServiceInfo info)
10.ActivityThread.queueOrSendMessage
11.H.handleMessage
12.ActivityThread.handleCreateService
13.Service.onCreate
14.ActivityManagerService.requestServiceBindingsLocked(r)
1.遍历ServiceRecord中bindings中的IntentBindRecord,调用重载的requestServiceBindingsLocked(r,i,false)一个个去绑定
1.1重载函数中判断是否已经绑定过,没有则调用ApplicationThreadPoxy.scheduleBindleService请求获取需要绑定的Service的Binder对象

15.ApplicationThreadPoxy.scheduleBindleService
1.写参数到Parcel data通过mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION)
16.ApplicationThread.scheduleBindleService
1.将传入的参数封装成BindServiceData scheduleBindleService
2.ActivityThread.queueOrSendMessage
17.ActivityThread.queueOrSendMessage
18.H.handleLauchActivity
19.ActivityThread.handleBindService
1.从mServices中获取Service对象 Service s = mServices.get(ServiceRecord )
2.判断s是否绑定过,false,则调用需要绑定的Service的onBind函数获取Binder binder对象
3.ActivityManagerProxy.publishService(ServiceRecord,intent,binder)
20.Service.onBind
21.ActivityManagerProxy.publishService
1.写参数到Parcel data通过mRemote.transact(PUBLISH_SERVICE_TRANSACTION,data,reply,0)
22.ActivityManagerService.publishService
1.根据FilterComparison filter从ServiceRecord获取IntentBindRecord b = binding.get(filter)
2.判断b是否为空,以及是否已经将需要绑定的Service对象的Binder对象传递给了ActivityManagerService,及多次绑定服务
true
b.binder = service;//将需要绑定的Service对象的Binder对象赋值给b.binder
b.requested = true;
b.received = true;
3.循环遍历ServiceRecord 成员变量connections根据InnenerConnection获取对应的ConenctionRecord的集合clist
4.变量clist 获取ConnectionRecord c,然后调用c.conn.connection c.conn是一个IServiceConnection的Binder代理对象,引用了InnerConnection Binder对象

23.InnerConnection.connected()
24.ServiceDispatcher.connected
1.将传入的ComponentName name,IBinder service封装成RunConnection对象
25.RunConnection.run
26.ServiceDispatcher.doConnected

27.ServiceConection.OnServiceConnected


ContentProvider

ContentProvider: onCreate方法不能做耗时逻辑操作,不然会导致启动超时
1.客户端查询数据向ContentProvider
1.ContexWrapper.getContentResolver
2.ContextImpl.getContentResolver
ContetextImpl.init(){mContentResolver = new ApplicationContentResolver(this,mainThread)}
2.ContentResolver.acquireProvider
3.ApplicationContentResolver.acquireProvider
4.ActivityThread.acquireProvider
5.ActivityThread.getProvider
1.HashMap mProviderMap//用于保存当前应用程序访问过的Content Provider代理对象
2.查找mProviderMap是否存在要查找的Provider
3.false ActivityManagerProxy.getContentPorvider
6.ActivityManagerProxy.getContentPorvider
7.ActivityManagerService.getContentPorvider
8.ActivityManagerService.getContentPorviderImpl
1.获取ProcessRecord r = getRecordForAppLocked(ApplicationThread)
2.mProviderByName 以ContentProvider android:authorities为key mProviderByClass 以ContentProvider的类名为key,两个成员变量存储ContentProvider
3.在mProviderByName中查找ContentProvider,不存在则去PackageManagerService中查找ContentProvider信息,并保存在ProviderInfo中
4.在mProviderByClass中查找ContentProvider 不存在去PackageManagerService中查找ContentProvider应用程序信息保存在ApplicationInfo中
5.将ProviderInfo与ApplicationInfo封装成ContentProviderRecord cpr
6.判断ContentProvider android:multiprocess属性 true表明ContentProvider需要在访问他的应用程序中启动,否则在新的的进程启动
7.所有正在启动的ContentProvider保存在mLaunchingProviders
8.判断传入的ContentProvider是否正在启动,true ActivityManagerService等待其完成 false 启动新的应用程序进程
9.新建的应用程序使用ProcessRecord proc  保存在ContentProviderRecord cpr中的lauchingApp中 并将cpr保存在mProviderByClass和mProviderByName
9.ActivityManagerService.startProcessLocked
10.ActivityThread.main
11.ActivityManagerProxy.attchApplication
12.ActivityManagerService.attachApplication
13.ActivityManagerService.attachApplicationLocked
1.ActivityManagerService 以PID(启动的应用程序)为key ProcessRecord app 为value保存在mPidsSelfLocked 并将app.thread = thread
2.generateApplicationPorvidersLocked
1.去PackageManagerService查询要在应用程序中启动的ContentProvider 并保存在providers 并启动里面全部的ContentProvider
2.循环遍历providers 检查 ContentProvider是否有对应的ContentProviderRecord false则创建 并保存在mProviderByClass中
14.ApplicationThreadProxy.bindApplication
15.ApplicationThread.bindApplication
1.将ContentProvider封装成AppBindData
16.ActivityThread.queueOrSendMessage
17.H.handleMessage
18.ActivityThread.handleBindApplication
19.ActivityThread.installContentProviders
1.循环传入的providers列表将ContentProvider启动后封装成ContentProviderHolder,然后传递给ActivityManagerService
20.ActivityThread.installProvider
1.创建ContentProvider 并创建对应的ProviderClientRecord 并保存在ActivityThread 成员变量mProviderMap,是本应用程序启动的ContentProvider 保存在mLocalProviders
21.ContentProvider.getIContentProvider return mTransport
1.Transport mTransport = new Transport()Binder本地对象传递给ActivityManagerService
22.ContentProvider.attachInfo
23.Provider.onCreate
24.ActivityManagerProxy.publicshContentProviders
25.ActivityManagerService.publicshContentProviders
26.ActivityThread.installProvider
ContentProvider数据传输过程:
1.Adpater.getArticleByPos
2.ContentResolver.query
3.ContentResolver.acquireProvider
4.ApplicationContentResolver.acquireProvider
5.ActivityThread.acquireProvider
6.ActivityThread.getProvider
7.ContentProviderProxy.query
1.创建CursorWindow window(同时创建一块匿名共享内存) 以及BulkCursorToCursorAdaptor adaptor
8.CusorWindow.native_init
1.创建C++层的CursorWindow window 
2.window.initBuff()创建匿名共享内存
1.创建MemoryHeapBase(创建匿名共享内存) heap对象 将MemoryHeapBase 封装成MemoryBase mMemory(管理匿名共享内存的一部分)对象

9.ContentProviderProxy.bulkQueryInternal
1.CusorWindow.writeToParcel
2.mRemote.transact(IContentProvider.QUERY_TRANSACTION,data,reply,0)
10.CursorWindow.writeToParcel
wiriteToParcel(Parcel dest ,int flag){
dest.writeStrongBinder(native_getBinder)
}
11.CursorWindow.native_getBinder
1.将MemoryBase封装成java Binder本地对象
12.ContentProviderNative.onTransact
1.onTransact(int code,Parcel data,Parcel reply,int flags)
2.判断是否需要返回查找数据的元数据
3.根据传入的data封装成CursorWindow
4.ContentProvider内部的一个Binder代理对象mRemote实际上引用了Transport Transport包含在ContentProvider内部,
负责处理其他与其父组件ContentProvider的通信
5.调用Transport.bulkQuery获取CursorToBulkCursorAdapter bulkCursor(包含需要返回的信息)
13.CursorWindow.CREATOR.createFromParecle
1.new CusorWindow(Parcel source)
1.CursorWindow.native_init
14.CursorWindow.native_init
1.将从传入的Memory转换成C++层的MemoryBase Binder代理对象
2.创建C++层的CursorWindow对象,然后调用setMemory将传入的内存设置成其内存
15.Transport.bulkQuery
1.Cursor cursor  = ContentProvider.query
2.将cursor以及CusorWindow封装成 CursorBulkCursorAdaptor对象
16.Provider.query
17.SQLiteQueryBuilder.query
18.SQLiteDatabase.rawQueryWithFctory
19.SQLiteDirectCursorDriver.query 返回Cursor
20.AbstractWindowedCursor.setWindow(CursorWindow window)
21.CursorToBulkCursorAdaptor.count
22.SQLiteCursor.getCount
23.SQLiteCursor.fillWindow
24.SQLiteQuery.fillWindow


ContentProvider组件数据更新的通知机制
1.MainActivity.onCreate
2.ContentResolver.registerContentObserver
1.getContentService().registerContentObserver(uri,notifyForDescendents,observer.getContentObserver())
3.ContentResolver.getContentService
1.第一次获取从ServiceManager中获取ContentService代理对象,并保存在sContentService中
4.ContentObserver.getContentObserver
1.Transport mTransport是其ContentObserver的内部类,作为中介用于处理外界与ContentObserver交互
mContentObserver = contentObserver;
5.ContentService.registerContentObserver//ContentService内部使用一棵树来保存注册者
1.ObserverNode mRootNode = new ObserverNode("");
2.mRootNode.addObserverLocked()
6.ObserverNode.addObserverLocked()
ObserverNode{
String mName;
ArrayList<ObserverNode> mChildren= new ArrayList<ObserverNode>();
ArrayList<ObserverEntry> mObservers= new ArrayList<ObserverEntry>();
1.将观察者封装成ObserverEntry,然后将观察者观察相同数据的ObserverEntry添加到ObserverNode中
countUriSegments(Uri uri)获取URI路径长度 getUriSegment(Uri uri,int index)获取第index路径的名称

}

发送数据更新通知
1.Provider.insert
1.生成新的Uri newUri = ContentUris.withAppendedId(uri,id);
2.ContentResolver.notifyChange
3.ContentService.notifyChange
4.ObserNode.collectObserversLocked
1.循环遍历ContentService查找对应的注册者,遍历注册者树,匹配一级与二级,同时如果是观察者触发的事件,则不给其通知

5.Transport.onChange
6.ContentObserver.dispatchChange
1.判断ContentObserver的mHandler是否为空
if(mHandler==null){
onChange(selfChange);
}else{
mHandler.post(new NotificationRunnable(selfChange))
}
7.NotificationRunnable.run
8.ArticleObserver.onChange



Zygote进程的启动脚本
1.init进程启动(在内核加载完成后),启动过程中读取脚本文件init.rc
2.将Zygote以服务的形式启动,然后启动System进程
3.创建Zygote没别的名称为"zygote"的Socket(用于与其他进程通信,主要与ActivityManagerService),然后得到
设备文件/dev/socket/zygote


Zygote进程的启动过程(在Zygote进程中加载的应用程序文件为system/bin/app_process)
1.app_process.main
1.AppRuntime runtime 虚拟机
2.runtime.start("com.android.internal.os.ZygoteInit",startSystemServer)//第二个参数为true表明需要启动System进程

2.AndroidRuntime.start(AppRuntime继承自AndroidRuntime)
1.创建虚拟机实例
2.调用startReg在虚拟机实例中注册一系列JNI方法
3.com.android.internal.os.ZygoteInit.main
3.ZygoteInit.main
1.registerZygoteSocket创建Server端的Socket
2.startSystemServer()启动System进程
3.runSelectLoopMode()/runForkMode();
4.ZygoteInit.registerZygoteSocket
ZygoteInit{
LocalServerSocket sServerSocket
sServerSocket = new LocalServerSocket()//创建Socket

}
5.ZygoteInit.startSystemServer
1.Zygote.forkSystemServer();创建Android系统的System进程
2.handleSystemServerProcess启动System进程
6.ZygoteInit.runSelectLoopMode
ArrayList<FileDescriptro> fds = new ArrayList();
ArrayList<ZygoteConnectio> peers = new ArrayList();
1.创建大小为4的Socket文件描述符数组FileDescriptor[] fdArray,表示Zygote最多能同时处理4个Socket链接
2.无限循环等待处理其他进程请求Zygote创建新的应用程序进程


System进程的启动过程
1.ZygoteInit.handleSystemServerProcess
1.closeServerSocket()因为System进程是从Zygote进程复制而来,同时就含有Zygote创建的Socket,而System不需要,则关闭

2.RuntimeInit.zygoteInit
1.commonInit()设置System进程的时区和键盘布局等通用信息
2.zygoteInitNative()在System进程中启动一个Binder线程池
3.invokeStaticMain();-->SystemServer.main
3.SystemServer.main
4.SystemServer.init1()JNI
1.启动C++服务(包含SurfaceFlinger与系统UI相关的服务,SensorService传感服务)
2.GrimReaper grim创建接收ServiceManager的死亡通知接收者,当ServiceManager死亡后,System进程会自杀,
因为没有ServiceManager,运行在System进程中的系统服务无法工作
5.SystemServer.init2
1.创建Thread thr = new ServerThread线程
2.thr.start();
6.ServerThread.run
1.Looper.prepare创建Looper
启动ActivityManagerService ,PackageManagerService ,ContentService,WindowManagerService等服务,并注册到Service Manager
1.ActivityManagerService 启动
1.ActivityManagerService.main
1.AThread thr = new AThread();
在此线程中创建了ActivityManagerService 注册到ServiceManager名称是"activity"
thr.start();
2.PackageManagerService启动 PackageManagerService.main
1.创建PackageManagerService并添加到ServiceManager 注册到ServiceManager名称"pakage"
3.PackageManagerService启动后,ServerThread 调用ActivityManagerService.setSystemProcess将其自己注册到ServiceManager
4.ContentService 启动
1.创建ContentService实例,并添加到ServiceManager 注册到ServiceManager名称"content"
5.WindowManagerService的启动
1.WindowManagerService.main
1.创建WMThread thr = new WMThread()
在此线程中创建WindowManagerService
thr.start
2.添加WindowManagerService到ServiceManager 注册到ServiceManager名称"window"
3.Looper.loop();

Android应用程序进程的启动过程
1.ActivityManagerService.startProcessLocekd
2.Process.start并且指定应用程序进程入口函数ActivityThread.main
1.判断系统是否支持Binder进程间通信机制 true startViaZygote()请求Zygote创建应用程序进程,false创建一个线程模拟应用程序进程


3.Process.startViaZygote
1.将要创建的应用程序进程启动参数保存在一个字符串列表 ArrayList<String> argsForZygote中
2.zygoteSendArgsAndGetPid(argsForZygote)

4.Process.zygoteSendArgsAndGetPid
1.openZygoteSocketIfNeeded()创建连接Zygote进程的LocalSocket sZygoteSocket对象
2.将要创建的应用程序进程启动参数列表写入到LocalSocket中,然后传递给Zygote,Zygote根据参数创建进程,然后返回进程的PID给ActivityManagerService

5.ZygoteInit.runSelectLoopMode
1.获取到创建应用程序进程请求后,调用ZygoteConnection的runOnce
6.ZygoteConnection.runOnce
1.获取传入的参数,保存在Arguments parsedArgs
2. pid = Zygote.forkAndSpecialize()创建一个子进程
3.判断pid==0 true则ZygoteConnection.handleChildProc启动该进程
7.ZygoteConnection.handleChildProc
1.根据传入的参数--runtime-init调用RuntimeInit.zygoteInit在新创建的应用进程初始化运行时库,并启动一个Binder线程池
8.RuntimeInit.zygoteInit
1.commonInit()设置System进程的时区和键盘布局等通用信息
2.zygoteInitNative()在进程中启动一个Binder线程池
3.invokeStaticMain();-->ActivityThread.main

Binder线程池的启动过程
1.RuntimeInit.zygoteInitNative
1.调用C++层的com_android_internal_os_RuntimeInit_zygoteInit
2.AppRuntime.onZygoteInit
1.判断是否支持Binder进程间通信机制, true ProcessState.startThreadPool启动Binder线程池(每一个支持Binder进程间通信机制的进程内部都有唯一一个ProcessState对象)
3.ProcessState.startThreadPool
1.成员变量 mThreadPoolState 默认为false 启动Binder池后为true,目的防止重复启动Binder池


消息循环的创建过程
1.RuntimeInit.invokeStaticMain
1.创建应用程序进程后加载ActivityThread 并将其入口函数main封装成Method m,然后将m以及传入的参数封装成 异常抛出 throw new ZygoteInit。MethodAndArgsCaller(m,argv)


2.系统沿用调用链异常被ZygoteInit的main函数捕获 
public static void main(String argv[]){
try{

}catch(MethodAndArgsCaller caller){
caller.run();
}

}
3.MethodAndArgsCaller.run
1.Method mMethod-->ActivityThread.main
2.String[] mArgs; 传入的参数

4.ActivityThread.main

Android应用程序的消息处理机制 
1.Looper
mQueue :MessageQueue
prepare();
prepareMainLopper();
Loop();

2.MessageQueue
mPtr :int  指向了C++层NativeMessageQueue的地址值
mMessages: Message
nativeInit();
nativePollOnce();
enqueueMessage();
nativeWake();

3.C++ NativeMessageQueue
mLooper: Looper
pollOnce();
wake();

4.C++ Looper
mWakeReadPipedFd:int 管道的读端文件描述符
mWakeWritePipedFd :int 管道的写端文件描述符
pollOnce();
wake();

1.创建Looper对象
2.在Looper对象内部创建一个MessageQueue对象
1.在创建MessageQueue对象的构造函数中调用nativeInitJNI方法
1.调用C++层的android_os_MessageQueue_nativeInit (JNIEnv* env,jobject obj)
1.NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();//创建native层的MessageQueue
1.创建NativeMessageQueue同时 判断Looper ==NULL创建C++层的Looper mLooper并将其保存在NativeMessageQueue成员变量mLooper
1.在创建C++层Looper时创建管道 int result = pipe(wakeFds)
mWakeReadPipedFd = wakeFds[0];//保存管道的读端文件符
mWakeWritePipedFd = wakeFds[1]//保存管道的写端文件符
2.mEpollFd = epoll_create(EPOLL_SIZE_HINT);//创建 epoll实例用于监听文件描述符的读写,
2.调用C++层Looper.setForThread将它与当前线程关联起来
2.android_os_MessageQueue_setNativeMessageQueue(env,obj,nativeMessageQueue)//与java层MessageQueue相关联
1.setIntField(messageQueueObj,gMessageQueueClassInfo.mPtr,..)
结构体static struct{
jclass clazz;指向Java层的MessageQueue
jfieldID mPtr; 指向了Java层的MessageQueue成员mPtr

}gMessageQueueClassInfo
消息循环过程
1.Looper.loop
Looper me = me.mQueue
Message queue = me.mQueue

1.while(true){
Message msg = queue.next();
}
2.MessageQueue.next
int pendingIdleHandlerCount =-1;//空闲消息处理器的个数
public static interface IdleHandler{//用于Looper所在线程空闲时,处理消息的Handler
boolean queueIdle();
}
使用:
1.向MessageQueue注册 addIdleHandler 保存在MessageQueue的mIdleHandlers中集合
2.取消注册 removeIdleHandler
3.在Looper线程将要休眠前判断MessageQueue中的注册的IdleHandler的数量,然后将mIdleHandler转换数组,
遍历数组,分别调用IdleHandler的boolean keep = idler.queueIdle(),如果keep为false则该idler会从mIdleHandler集合中移除

int nextPollTimeoutMillis = 0;//下次线程休眠时间,值为0表示即使消息队列中无消息,当前线程也不能休眠 值-1,要无限休眠
for(;;){
if(nextPollTimeoutMillis!=0){Binder{.flushPendingCommands}
nativePollOnce(mPtr,nextPollTimeoutMills)//未休眠,则处理正在等待的Binder进程间通信请求
sychronized(this){
final long now = SystemClock.uptimeMillis();
final Message msg = mMessages;
if(msg!=null){
final long when = msg.when;
if(now>=when){//表示现在的时间已经超出消息指定的处理需要立马执行
mMessages = msg.next;
msg.next = null;
return msg;
}else{
nextPollTimeoutMillis = (int)Math.min(when-now,Integer.MAX_VALUE);
}else{
nextPollTimeoutMillis = -1;
}

}
nextPollTimeoutMillis=0;
}
}


3.MessageQueue.nativePollOnce//JNI方法
4.NativeMessageQueue.pollOnce
5.C++ Looper.pollOnce
1.for循环,判断是否有要处理的消息
for(;;){
if(result!=0){
return result;
}
result = pollInner(timeoutMillis)
}


6.C++ Looper.pollnner
1.当其他线程使用handler向消息队列中发送后,会向当前线程关联的管道写入一个新的数据,目的是唤醒当前线程
7.C++ Looper.awoken
1.读出其他线程写入的数据,清空管道旧数据,而不关心数据是什么,因为目的只是为了唤醒当前线程


线程消息发送过程
· 1.Handler.sendMessage (创建Handler默认在其构造函数中获取当前线程的Looper MessageQueue)
1.将消息绑定到当前的Handler
2.MessageQueue.enqueueMessage
1.根据时间when循环变量消息队列,找到合适位置插入
2.并判断是否需要唤醒线程
3. MessageQueue.nativeWake
4.C++ NativeMessageQueue.wake
5.C++ Looper.wake
1.利用Looper中的mWakeWritePipeFd描述管道的写端文件描述符,调用函数write("w"),即向管道写入数据
线程消息处理过程
1.Looper.loop
1.判断Handler即msg.target是否为空,为空则退出消息Loop循环,否则分发事件Handler.dispatchMessage
2.Handler.dispatchMessage
{
if(msg.callback!=null){//runnable{}
hanldeCallback(msg)
}else{
if(mCallback!=null){//Callback接口
if(mCallback.handleMessage(msg)){return;}
}
handleMessage(msg)
}
}


final Callback mCallback
3.Handler.handleMessage


Android键盘原理
WindowManagerService{
1.InputManager mInputManager
InputManager{
1.start();
NativeInputManager{//JNI
1InputManager mInputManager
2.setInputWindows();
3.start();
InputManager{//Native
1InputDispatcher mDispatcher
InputDispatcher{
1Looper mLooper
Looper{
1.pollOnce();
2.wake();
}
2.InputWindow mFocusedWindow
3.dispatchOnce()
4.notifyKey();
5.setInputWindows();
6.NativeInputManager mPolicy
}

2.InputReader mReader
InputReader{
1.EventHub mEventHub
EventHub{
getEvent();
}
2.loopOnce();
}

3.start();
}

}
2setInputWindows();



}
}

InputManager的创建过程

1.WMThread.run
1.创建WindowManagerService s = new WidowManagerService()
1.在s的构造函数中 创建InputManager mInputManager = new InputManager(Context cxt,WidowManagerService widowManagerService)
1.在mInputManager的构造函数中调用其函数 init();
2.mInputManager.start();启动InputManager
2.InputManager.init()
1.InputManager.nativeInit在C++层创建一个NativeInputManager
3.InputManager.nativeInit//JNI方法
1.首先检查gNativeInputManager==null true则创建new NativeInputManager()
NativeInputManager
InputManager mInputManager
1.在其构造函数中首先创建了EventHub eventHub = new EventHub()对象,然后以EventHub为参数创建C++层的InputManager mInputManager
InputManager
1.创建mDispatcher = new InputDispatcher()以及mReader = new InputReader
2.initialize()

4.InputManager.initialize();
1.分别以mDispatcher mReader为参数分别创建 mReaderThread = new InputReaderThead(mReader); mDispatcherThread = new InputDispatcherThread(mDispatcher)两个线程
InputManager启动
1.InputManager.start();
2.InputManager.nativeStart
3.InputManager.start();//C++层
4.分别调用mReaderThread.run  mDispatcherThread.run run函数内回创建一个线程,并且以threadLoop函数为线程入口

启动InputDispatcher //负责分发键盘事件给获取焦点的窗口


1.InputDispatcherThread.threadLoop;
2.InputDispatcher.dispatchOnce 
1.NativeInputManager mPolicy  keyRepeatTimeout =  mPolicty->getKeyRepeatTimeout();//获取用户持续按下键盘键(即:“重复键盘事件”)能够响应的时间(纳秒)
keyRepeatDelay = mPolicy->getKeyRepeatDely//如果是重复键盘时间,分发相同的键盘事件给系统的间隔的时间(纳秒)
2.调用InputDispatcher(keyRepeatTimeout,keyRepeatDelay,&nextWakeTime)//用于检查系统是否新的键盘事件需要分发,参数3是如果没有需要分发的事件
则当前线程需要休眠的时间
3.调用runCommandsLockedInterruptible()检查InputDispatcher中是否有一些缓存命令未执行,有则执行,而且当前线程也不能休眠,因为执行缓存命令期间,可能有
键盘事件需要分发
4.转换nextWakeupTime为相对时间,并转换为毫秒
5.Looper->loopOnce
3.Looper->loopOnce使线程休眠
启动InputReader//负责监听键盘事件的发生,然后唤醒InputDispatcher分发事件
1.InputReaderThead.threadLoop
2.InputReader.loopOnce
RawEvent rawEvent
1.mEventHub->getEvent(& rawEvent)//获取键盘事件并保存在rawEvent
2.Process(&rawEvent)
3.EventHub.getEvent
EventHub{
boolean mOpened监听键盘事件前,首先打开系统的输入设备(内建的键盘设备ID恒为0),打开后为 true
mFDs打开系统的输入设备后获取的文件描述符
mFDCount 文件描述符的大小
mDeevices打开的输入设备可以有多个,比如系统的获取搜狗的
getEvent{
1.判断是否打开系统的输入设备 false 则openPlatformInput打开
2.将IO输入事件保存在缓冲区mInputBufferData
3.循环遍历mInputBufferData getEvent一次只能处理一个IO输入事件,因此记录下一个要处理事件在数组mInputBufferData位置
4.获取的事件封装成结构体 RawEvent outEvent

5.检查其他设备是否也有IO事件
6.所有设备都没有IO事件则休眠
}
}
4.EventHub.openPlatformInput
Andoid应用程序线程的消息循环模型


Andorid应用程序的安装和显示的过程:
首先系统通过PackageManagerService扫描应用程序所在的目录,(系统每次启动都会重新安装一边系统中的应用程序)
1.解析应用程序的AndroidManifest.xml文件,
2.为应用程序分配Linux用户ID(目的是可以在系统中获取合适的运行时权限)和Linux用户组ID(目的是可以在系统中获取更多的资源访问权限)
3.启动Home应用程序Laucher
4.Laucher请求PackageManagerService获取应用程序的信息封装成快捷图标
应用程序的安装:
1.packageManagerService.main//创建PackageManagerService实例,并添加到ServiceManger
PackageManagerService{
Settings mSettings = new Settings() //管理应用程序的安装的信息


}
















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值