大家好,今天给各位分享深入解析Android系统:源码揭秘四大组件(第一篇)的一些知识,其中也会对进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!
这几天分析了Activity和Service的启动流程,所以今天就写一下Service是如何启动的。我感觉这些启动过程并不复杂。不要被混乱的代码吓倒。虽然曲折重重,功能相继超载,就像走在迷宫里一样,但只要抓住主线,坚持读下去,很快就会找到出口。我想强调的是,在阅读系统源码的时候,至少要了解进程间通信,对binder机制要非常非常清楚。活页夹就是指南针,否则你会感到困惑。如果你强迫自己读书,你很容易就睡着了。如果想看Binder,就去Android源码分析RPC系列(一)---Binder原理。
服务开始后,让我们拍张照片感受一下。
这张图可以说明一个大概的流程,但是启动服务肯定没那么简单,不过我们先简单总结一下,逐步深入。启动服务有两种方法,startService()和binderService()。让我们看一下startService()。 startService是ContextWrapper中的一个方法。
ContextWrapper.java
@覆盖
公共组件名称startService(意向服务){
return mBase.startService(service);//这里的mBase指的是ContextImpl类
}ContextImpl.java
@覆盖
公共组件名称startService(意向服务){
warnIfCallingFromSystemProcess();
返回startServiceCommon(服务,mUser);
}private ComponentName startServiceCommon(意图服务, UserHandle 用户) {
尝试{
//检查意图
验证服务意图(服务);
.
ComponentName cn=ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver())、getOpPackageName()、user.getIdentifier());
.
返回cn;
} catch (RemoteException e) {
throw new RuntimeException("系统故障", e);
}
}验证完Intent后,调用ActivityManagerNative.getDefault(),获取一个IActivityManager对象,将启动Service的事情交给IActivityManager。我们看一下ActivityManagerNative的类定义
public Abstract class ActivityManagerNative extends Binder Implements IActivityManager 这个模式是不是很熟悉?它继承了Binder并实现了IActivityManager接口。这与我们为远程服务通信生成的AIDL生成的java文件非常相似。现在告诉你,这是为了远程服务通信做准备,但是一般我们都会自动使用这个类。 ActivityManagerNative 是由Google 的人编写的。一个完整的AID L有两部分,一是与服务器通信的Stub,二是与客户端通信的Proxy。 ActivityManagerNative 是一个存根。看了源码,发现ActivityManagerNative文件里有一个ActivityManagerProxy,所以也有一个和客户端通信的Proxy。我们先看一下IActivityManager是如何获取的。
ActivityManagerNative.java
静态公共IActivityManager getDefault() {
返回gDefault.get();
}私有静态最终SingletongDefault=new Singleton() {
受保护的IActivityManager create() {
//获取名为“activity”的服务。服务注册到ServiceManager进行统一管理。
IBinder b=ServiceManager.getService("activity");
如果(假){
Log.v("ActivityManager", "默认服务绑定器=" + b);
}
IActivityManager am=asInterface(b);
如果(假){
Log.v("ActivityManager", "默认服务=" + am);
}
上午返回;
}
};是单例设计模式,获取服务对象IBinder,将这个IBinder转换为IActivityManager并返回。该服务现在由IActivityManager 启动。
public ComponentName startService(IApplicationThread 调用者, Intent 服务,
StringsolvedType、StringcallingPackage、intuserId) 抛出RemoteException
{
包裹数据=Parcel.obtain();
包裹回复=Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller !=null ? caller.asBinder() : null);
service.writeToParcel(数据, 0);
data.writeString(resolvedType);
data.writeString(callingPackage);
data.writeInt(userId);
mRemote.transact(START_SERVICE_TRANSACTION, 数据, 回复, 0);
回复.readException();
ComponentName res=ComponentName.readFromParcel(reply);
数据.recycle();
回复.recycle();
返回资源;
}如上所述,ActivityManagerProxy作为binder通信的客户端,ActivityManagerNative作为binder通信的服务端。 mRemote.transact()是客户端发起的binder通信方法。由binder驱动,最终返回到binder服务器ActivityManagerNative的onTransact()方法。
@覆盖
public boolean onTransact(int code, 包裹数据, 包裹回复, int flags)
抛出远程异常{
…………
开关(代码){
案例START_SERVICE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b=data.readStrongBinder();
IApplicationThread app=ApplicationThreadNative.asInterface(b);
意图服务=Intent.CREATOR.createFromParcel(data);
字符串解析类型=data.readString();
String CallingPackage=data.readString();
int userId=data.readInt();
ComponentName cn=startService(应用程序、服务、resolvedType、callingPackage、userId);
回复.writeNoException();
ComponentName.writeToParcel(cn, 回复);
返回真;
}
}
…………
}ActivityManagerNative的真正实现是ActivityManagerService,所以binder通信服务器的ActivityManagerService,ActivityManagerProxy.startService()最终调用的是ActivityManagerService.startService()。请注意,这是跨进程的。 ActivityManagerService 是一个服务器端进程。查看ActivityManagerService中的startService方法。
ActivityManagerService.java
public ComponentName startService(IApplicationThread 调用者, Intent 服务,
字符串resolvedType,字符串callingPackage,int userId)
抛出TransactionTooLargeException {
.
同步(这个){
…………
ComponentName res=mServices.startServiceLocked(调用者, 服务,
已解析类型、callingPid、callingUid、callingPackage、userId);
Binder.restoreCallingIdentity(origId);
返回资源;
}
}ActivityManagerService并没有直接做这个工作,而是把这个任务交给了mService,mService是一个ActiveServices对象。早期的Android 版本中不存在此类。后来重构的时候,专门抽出了这个类来管理Service。
ActiveServices.java
ComponentName startServiceLocked(IApplicationThread 调用者, Intent 服务, String returnedType,
int CallingPid、int CallingUid、String CallingPackage、int UserId)
抛出TransactionTooLargeException {
…………
返回startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}startServiceInnerLocked调用bringUpServiceLocked(),bringUpServiceLocked()内部调用realStartServiceLocked()。让我们看一下realStartServiceLocked() 方法。
私有最终无效realStartServiceLocked(ServiceRecord r,
ProcessRecord 应用程序,布尔值execInFg) 抛出RemoteException {
…………
尝试{
…………
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
应用程序.repProcState);
r.postNotification();
创建=真;
} catch (DeadObjectException e) {
.
} 最后{
.
}
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
//如果服务处于启动状态,并且没有
//挂起的参数,然后伪造一个,这样它的onStartCommand() 就会
//被调用。
if (r.startRequested r.callStart r.pendingStarts.size()==0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
空,空));
}
//输入onStartCommand()
sendServiceArgsLocked(r, execInFg, true);
.
}这里的关键是
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app是运行Service的进程对应的ProcessRecord对象,代表一个应用程序进程。为了区分,一般我们都是朝一个方向沟通。客户端向服务器发送处理请求,服务器处理后返回。如果服务器向客户端发送“请求”怎么办?这里的线程是一个ApplicationThreadProxy对象,它是AMS端应用程序进程的AppliconThread对象的代理。 AMS 依靠它与应用程序进程进行通信。因此AMS和应用程序进程可以双向通信。
应用线程代理.java
公共最终无效scheduleCreateService(IBinder令牌,ServiceInfo信息,
CompatibilityInfo compatInfo, int processState) 抛出RemoteException {
包裹数据=Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(令牌);
info.writeToParcel(数据, 0);
compatInfo.writeToParcel(数据, 0);
data.writeInt(processState);
尝试{
mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
} catch (TransactionTooLargeException e) {
扔e;
}
数据.recycle();
}执行mRemote.transact后,ApplicationThreadNative的onTransact会被回调。这是宾德的惯例。
ApplicationThreadNative.java
public boolean onTransact(int code, 包裹数据, 包裹回复, int flags)
抛出远程异常{
开关(代码){
案例SCHEDULE_CREATE_SERVICE_TRANSACTION: {
data.enforceInterface(IApplicationThread.descriptor);
IBinder token=data.readStrongBinder();
ServiceInfo信息=ServiceInfo.CREATOR.createFromParcel(data);
CompatibilityInfo compatInfo=CompatibilityInfo.CREATOR.createFromParcel(data);
int processState=data.readInt();
ScheduleCreateService(令牌,信息,compatInfo,processState);
返回真;
}
.
}ScheduleCreateService 在内部调用。看上图可以知道scheduleCreateService属于ApplicatonThread。
应用线程.java
公共最终无效scheduleCreateService(IBinder令牌,
ServiceInfo 信息、CompatibilityInfo compatInfo、int processState) {
updateProcessState(进程状态,假);
CreateServiceData s=new CreateServiceData();
s.token=令牌;
s.info=信息;
s.compatInfo=compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}发送消息。这个消息由H类处理。H类是系统Hander,专门处理系统请求。比如一些Activity的生命周期都在里面。这个H对象是在应用程序进程的主线程中创建的,所以最终的结果是创建Service的消息传递到了主线程,所以Service运行在主线程中。
爪哇
私有类H 扩展Handler {
…………
公共无效handleMessage(消息msg){
if (DEBUG_MESSAGES) Slog.v(TAG, "handling: " + codeToString(msg.what));
开关(msg.what) {
案例CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}ActivityThread.java
私有无效handleCreateService(CreateServiceData数据){
…………
LoadedApk packageInfo=getPackageInfoNoCheck(
数据.info.applicationInfo、数据.compatInfo);
服务服务=空;
尝试{
//反射加载服务
java.lang.ClassLoader cl=packageInfo.getClassLoader();
service=(Service) cl.loadClass(data.info.name).newInstance();
} catch (异常e) {
…………
}
尝试{
if (localLOGV) Slog.v(TAG, "正在创建服务" + data.info.name);
//创建ContextImpl对象
ContextImpl 上下文=ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(服务);
//创建应用程序对象
应用程序应用程序=packageInfo.makeApplication(false, mInstrumentation);
service.attach(上下文,这个,data.info.name,data.token,应用程序,
ActivityManagerNative.getDefault());
//回调onCreate方法
service.onCreate();
mServices.put(data.token, 服务);
尝试{
//调用服务创建完成
ActivityManagerNative.getDefault().serviceDoneExecuting(
数据.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
//无事可做。
}
} catch (异常e) {
…………
}
此时Service的onCreate已经被回调了。那么onStartCommand()什么时候会回调呢?在realStartServiceLocked中,调用sendServiceArgsLocked(r, execInFg, true)。 sendServiceArgsLocked与上面类似,最后发送一条(SERVICE_ARGS)消息。
应用线程.java
公共最终无效scheduleServiceArgs(IBinder令牌,布尔taskRemoved,int startId,
int 标志,意图参数) {
ServiceArgsData s=new ServiceArgsData();
s.token=令牌;
s.taskRemoved=任务已删除;
s.startId=开始Id;
s.flags=标志;
s.args=args;
sendMessage(H.SERVICE_ARGS, s);
}ActivityThread.java
私有无效handleServiceArgs(ServiceArgsData数据){
Service s=mServices.get(data.token);
如果(s!=null){
尝试{
if (data.args !=null) {
data.args.setExtrasClassLoader(s.getClassLoader());
data.args.prepareToEnterProcess();
}
内部资源;
if (!data.taskRemoved) {
//onStartCommand回调
res=s.onStartCommand(data.args, data.flags, data.startId);
} 别的{
s.onTaskRemoved(data.args);
res=Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
尝试{
ActivityManagerNative.getDefault().serviceDoneExecuting(
数据.token、SERVICE_DONE_EXECUTING_START、数据.startId、res);
} catch (RemoteException e) {
//无事可做。
}
确保JitEnabled();
} catch (异常e) {
.
}
}
}Service的onCreate回调和onStartCommand的回调例程完全相同。朋友们可以亲自体验一下。 onCreate回调首先执行scheduleCreateService()方法,最后回调Service.onCreate(); onStartCommand 回调首先执行scheduleServiceArgs() 方法。最后回调Service.onStartCommand()。
总结一下:
IActivityManager 接口定义了AMS 向应用程序(本例中为Service)提供的各种API。 Activity可以使用这些API通过ActivityManagerProxy向AMS发出请求,因此它通过ActivityManagerProxy调用ActivityManagerProxy的startService方法,并在内部进行调用。 transact,然后会调用ActivityManagerNative中的onTransact()方法。在该方法中,将完成AMS与Activity的连接,并调用AMS的startService()方法。那么AMS Service所在的应用程序怎么样呢?例如scheduleCreateService。原来,ApplicationThreadProxy是Application进程的ApplicatonThread对象在AMS端的代理,AMS依靠它与应用进程进行通信。这是Activity 和AMS 之间的双向Binder连接。 Activity 使用IActivityManager 提供的APIActivityManagerService 发出执行操作的请求(在本例中为启动RemoteService)。 ActivityManagerService使用IApplicationThread提供的API来控制Activity所在的应用程序。
上面的分析就节省了很多内容。如果从进程的角度来看服务启动过程。
Process A进程:是指调用startService命令的进程,即启动服务的initiator进程。
system_server进程:系统进程是java Framework框架的核心载体,运行着大量的系统服务。比如这里提供了ApplicationThreadProxy和ActivityManagerService。这两个服务都在system_server 进程的不同线程中运行。
Zygote进程:是由init进程孵化出来的,用来创建Java层进程的母体。所有Java层进程都是由Zygote进程孵化的;
Remote Service进程:远程服务所在进程是Zygote进程孵化出来的进程,用于运行远程服务。主线程主要负责Activity/Service等组件的生命周期以及UI相关操作。另外,每个App进程中至少有两个Binder线程,ApplicationThread和ActivityManagerProxy。
Paste_Image.png启动流程:
OK,本文到此结束,希望对大家有所帮助。
【深入解析Android系统:源码揭秘四大组件(第一篇)】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
想深入了解Android手机是怎么工作的吗?这篇文章应该很不错!
有19位网友表示赞同!
我一直对Android的内部机制很好奇,学习它肯定很有收获!
有13位网友表示赞同!
四大组件是Android核心啊,看源码解析应该能明白它的运作方式。
有17位网友表示赞同!
感觉这篇文讲解很专业,可以让我更好地理解Android开发!
有8位网友表示赞同!
作为学习Android开发的朋友,一定要好好看看这本书!
有9位网友表示赞同!
Android源码分析一直都是一个很有挑战性的任务,期待这篇文章的分享!
有12位网友表示赞同!
希望作者能详细解释四大组件之间的相互关系!
有10位网友表示赞同!
阅读源码确实可以让编程思路更加清晰。
有15位网友表示赞同!
学习Android开发不能少了解源码!
有10位网友表示赞同!
这个系列文章应该非常有用,可以帮助我更深入地掌握Android!
有9位网友表示赞同!
想要成为优秀的Android开发者,源码分析是必不可少的!
有5位网友表示赞同!
这篇文章会让我想知道四大组件的应用场景有哪些?
有10位网友表示赞同!
期待学习到更多关于Android框架的知识!
有5位网友表示赞同!
安卓开发越来越流行了,这篇源码解析应该很有用!
有15位网友表示赞同!
我一直想了解Android系统的架构设计,这篇文章很有帮助。
有13位网友表示赞同!
从源码出发去理解Android,是一种很好的学习方法!
有10位网友表示赞同!
看篇文章的同时,可以试着跟着代码动手操作!
有18位网友表示赞同!
希望作者能分享更多关于Android开发的经验!
有10位网友表示赞同!
学习Android开发是一件很有乐趣的事情!
有7位网友表示赞同!
期待后续的文章内容!
有19位网友表示赞同!