《Android开发艺术探索》第九章四大组件的工作过程小结

来源:互联网 发布:e店宝官方下载3.0 mac 编辑:程序博客网 时间:2024/05/22 04:51

1. 运行状态

1)除了BroadcastReceiver以外,其他三种必须在AndroidManifest中注册,ContentProvider的调用不需要Intent;

2)Activity通过显示或者隐式Intent启动,有四种启动模式,通过finish方法结束,主要作用是展示界面和用户交互;

3)Service用于在后台执行计算任务,有启动和绑定两种状态,启动状态不需要和外界交互,后台计算仍需要在自线程中完成;绑定状态可以方便和外界通信;停止Service需要调用stopService和unBindService。当多次绑定同一个Service时,Service的onBind只会执行一次,除非Service被终止了。

4)BroadcastReceiver可以静态或者动态注册,动态注册用Context.registerReceiver(),不适合用来执行耗时操作;

5)ContentProvider用于向其他应用共享数据,内部实现了增删改查操作,需要处理好线程同步;


2. Activity的启动过程

1)startActivityForResult,调用mInstrumentation.execStartActivity和mMainThread.sendActivityResult,前者调用了AMS.startActivity,之后进入ActivityStack.resumeTopActivitiesLocked,让当前resume的Activity进入到pause状态,之后调用realStartActivityLocked启动新的Activity,由ApplicationThread.scheduleLaunchActivity启动。ApplicationThread完成了大量和Activity以及Service启动停止相关的操作;ApplicationThread发消息给主线程,调用主线程的handleLaunchActivity。内部调用performLaunchActivity和handleResumeActivity。

2)performLaunchActivity:从ActivityClientRecord取得启动的Activity的组件信息,通过Instrumentation的newActivity使用类加载器创建Activity,通过LoadedApk的makeApplication创建Application,创建ContextImpl并通过Activity的attach完成数据初始化。

3)调用mInstrumentation.callActivityOnCreate调用onCreate。


3. Service的启动过程

1)Service的启动状态用于执行后台计算,绑定状态用于和其他组件交互;

2)ContextImpl中的startService,调用AMS中的startService,AMS通过ActiveServices管理Service,内部调用app.thread.scheduleCreateService创建Service并调用其onCreate,再通过sendServiceArgsLocked来调用Service的onStartCommand等方法;

3)scheduleCreateService会调用客户端的handleCreateService,通过类加载器创建Service实例,创建Application并调用其onCreate方法,创建ContextImpl并通过Service的attach建立二者的联系,最后调用Service的onCreate方法,并将它存到mServices的map中;


4. Service的绑定过程

1)调用ContextImpl的bindServiceCommon方法:首先将客户端的ServiceConnection对象转化为ServiceDispatcher.InnerConnection对象用来跨进程。当Service和客户端建立连接后,系统会通过InnerConnection来调用ServiceConnection中的onServiceConnected方法,这个过程可能是跨进程的。

2)接着调用AMS的bindService,最终会调用到realStartServiceLocked,和启动Service的过程类似;

3)启动后AMS会调用app.thread的scheduleBindService方法;

4)在客户端的handleBindService中,首先根据Service的token取出Service对象,然后调用Service的onBind方法得到服务端的IBinder;(原则上Service的onBind方法被调用以后,Service就处于绑定状态了,但onBind方法是Service的方法,这个时候客户端并不知道已经成功连接Service了,所以还必须由调用客户端的ServiceConnection中的onServiceConnected)

5)客户端调用AMS的publishService方法,之后通过ConnectionRecord的ServiceDispatcher.InnerConnection,调用connected(ComponentName, IBinder service),最终调用到客户端的mConnection.onServiceConnected(name, service);


5. BroadcastReceiver的工作过程

1)使用方法:定义广播接收者,只要继承BroadcastReceiver并重写onReceive,收到Intent;在AndroidManifest中静态注册广播接收者加入<intent-filter>,在代码中注册registerReceiver。通过sendBroadcast发送广播;

2)静态广播注册是由PMS解析AndroidManifest完成的;

3)动态广播的注册:从(LoadedApk)mPackageInfo中获取IIntentReceiver对象,再调用AMS发送广播注册对象。IIntentReceiver的具体实现是LoadedApk.ReceiverDispatcher.InnerReceiver,ReceiverDispatcher内部同时保存了BroadcastReceiver和InnerReceiver,这样接收到广播时,ReceiverDispatcher可以很方便的调用BroadcastReceiver的onReceive方法;AMS中会把InnerReceiver和IntentFilter存储起来,完成注册;

4)发送过程:从ContextImpl的sendBroadcast开始,调用AMS的broadcastIntent,会根据intent-filter查找出匹配的广播接收者并经过一些列过滤,最终将满足条件的广播接收者添加到BroadcastQueue中,接着BroadcastQueue就会将广播发送给相应的广播接收者;BroadcastQueue的mParallelBroadcasts中保存着无序广播,遍历它将其中的广播发送给所有接收者,具体调用了performReceiveLocked,其中又调用了app.thread.scheduleRegisteredReceiver(IIntentReceiver, intent, resultCode, ...)。在客户端中调用InnerReceiver的performReceive,又会调用LoadedApk.ReceiverDispatched的performReceive方法,通过发消息切到主线程中,最后调用receiver.onReceive(mContext, intent)。


6. ContentProvider的工作过程

1)当ContentProvider所在的进程启动时,ContentProvider会同时启动并被发布到AWS中,这时ContentProvider的onCreate要先于Application的onCreate执行。当一个应用启动时,入口方法为ActivityThread的main方法,在这个静态方法中创建ActivityThread实例并创建主线程的消息队列,然后调用ActivityThread的attach方法远程调用AMS的attachApplication方法,并将ApplicationThread提供给AMS,AMS会调用ApplicationThread的handleBindApplication,在客户端创建Application并加载ContentProvider,然后再调用Application的onCreate。

2)因为ContentProvider的android:multiprocess默认为false,所以它是单例的。

3)访问它通常需要ContentResolver,如果此时ContentProvider未创建,则创建它所在的进程和ContentProvider;

4)调用query方法,首先尝试获得IContentProvider,ActivityThread查找是否已经存在目标ContentProvider了,如果CP没启动,则调用AMS让CP启动,最后再通过installProvider修改引用计数;

5)在新进程中ActivityThread的handleBindApplication完成了Application的创建以及ContentProvider的创建:首先遍历当前进程的ProviderInfo的列表并一一调用installProvider方法通过类加载器启动它们,调用CP的attachInfo方法(内部调用了onCreate),接着将启动的CP发布到AMS中,AMS会把它们存储在ProviderMap中;最后调用Application的onCreate方法。

6)其他应用通过AMS获得IContentProvider,而它的实现类是ContentProvider.Transport,再调用query方法;




0 0