专栏名称: 安卓开发精选
伯乐在线旗下账号,分享安卓应用相关内容,包括:安卓应用开发、设计和动态等。
目录
相关文章推荐
开发者全社区  ·  深圳公务员天也塌了 ·  18 小时前  
鸿洋  ·  Android×AI×鸿蒙生态周刊#2|跨端 ... ·  22 小时前  
开发者全社区  ·  年薪300万大厂程序员被女友晒工资单被裁,百 ... ·  23 小时前  
开发者全社区  ·  yc女同学的朋友圈 ·  3 天前  
51好读  ›  专栏  ›  安卓开发精选

Android Service的启动过程(下)

安卓开发精选  · 公众号  · android  · 2016-11-08 22:45

正文

(点击 上方公众号 ,可快速关注)


来源:伯乐在线专栏作者 - xuyinhuan

链接:http://android.jobbole.com/85150/

点击 → 了解如何加入专栏作者


接上文


首先获取到一个LoadedApk对象,在通过这个LoadedApk对象获取到一个类加载器,通过这个类加载器来创建Service。如下:


java . lang . ClassLoader cl = packageInfo . getClassLoader ();

service = ( Service ) cl . loadClass ( data . info . name ). newInstance ();


接着调用ContextImpl的createAppContext方法创建了一个ContextImpl对象。


之后再调用LoadedApk的makeApplication方法来创建Application,这个创建过程如下:


public Application makeApplication ( boolean forceDefaultAppClass ,

Instrumentation instrumentation ) {

if ( mApplication != null ) {

return mApplication ;

}

Application app = null ;

String appClass = mApplicationInfo . className ;

if ( forceDefaultAppClass || ( appClass == null )) {

appClass = "android.app.Application" ;

}

try {

java . lang . ClassLoader cl = getClassLoader ();

if ( ! mPackageName . equals ( "android" )) {

initializeJavaContextClassLoader ();

}

ContextImpl appContext = ContextImpl . createAppContext ( mActivityThread , this );

app = mActivityThread . mInstrumentation . newApplication (

cl , appClass , appContext );

appContext . setOuterContext ( app );

} catch ( Exception e ) {

if ( ! mActivityThread . mInstrumentation . onException ( app , e )) {

throw new RuntimeException (

"Unable to instantiate application " + appClass

+ ": " + e . toString (), e );

}

}

mActivityThread . mAllApplications . add ( app );

mApplication = app ;

if ( instrumentation != null ) {

try {

instrumentation . callApplicationOnCreate ( app );

} catch ( Exception e ) {

if ( ! instrumentation . onException ( app , e )) {

throw new RuntimeException (

"Unable to create application " + app . getClass (). getName ()

+ ": " + e . toString (), e );

}

}

}

// Rewrite the R 'constants' for all library apks.

SparseArray packageIdentifiers = getAssets ( mActivityThread )

. getAssignedPackageIdentifiers ();

final int N = packageIdentifiers . size ();

for ( int i = 0 ; i N ; i ++ ) {

final int id = packageIdentifiers . keyAt ( i );

if ( id == 0x01 || id == 0x7f ) {

continue ;

}

rewriteRValues ( getClassLoader (), packageIdentifiers . valueAt ( i ), id );

}

return app ;

}


当然Application是只有一个的,从上述代码中也可以看出。


在回来继续看handleCreateService方法,之后service调用了attach方法关联了ContextImpl和Application等


最后service回调了onCreate方法,


service . onCreate ();

mServices . put ( data . token , service );


并将这个service添加进了一个了列表进行管理。


至此service启动了起来,以上就是service的启动过程。


你可能还想要知道onStartCommand方法是怎么被回调的?可能细心的你发现了在ActiveServices的realStartServiceLocked方法中,那里还有一个sendServiceArgsLocked方法。是的,那个就是入口。


那么我们跟进sendServiceArgsLocked方法看看onStartCommand方法是怎么回调的。


private final void sendServiceArgsLocked ( ServiceRecord r , boolean execInFg ,

boolean oomAdjusted ) throws TransactionTooLargeException {

final int N = r . pendingStarts . size ();

//代码省略

try {

//代码省略

r . app . thread . scheduleServiceArgs ( r , si . taskRemoved , si . id , flags , si . intent );

} catch ( TransactionTooLargeException e ) {

if ( DEBUG_SERVICE ) Slog . v ( TAG_SERVICE , "Transaction too large: intent="

+ si . intent );

caughtException = e ;

} catch ( RemoteException e ) {

// Remote process gone...  we'll let the normal cleanup take care of this.

if ( DEBUG_SERVICE ) Slog . v ( TAG_SERVICE , "Crashed while sending args: " + r );

caughtException = e ;

}

//代码省略

}


可以看到onStartCommand方法回调过程和onCreate方法的是很相似的,都会转到app.thread。那么现在就跟进ApplicationThread的scheduleServiceArgs。

你也可能猜到了应该又是封装一些Service的信息,然后发送一个消息, handleMessage接收。是的,源码如下:


public final void scheduleServiceArgs ( IBinder token , boolean taskRemoved , int startId ,

int flags , Intent args ) {

ServiceArgsData s = new ServiceArgsData ();

s . token = token ;

s . taskRemoved = taskRemoved ;

s . startId = startId ;

s . flags = flags ;

s . args = args ;

sendMessage ( H . SERVICE_ARGS , s );

}


public void handleMessage ( Message msg ) {

//代码省略

case SERVICE_ARGS :

Trace . traceBegin ( Trace . TRACE_TAG_ACTIVITY_MANAGER , "serviceStart" );

handleServiceArgs (( ServiceArgsData ) msg . obj );

Trace . traceEnd ( Trace . TRACE_TAG_ACTIVITY_MANAGER );

break ;

//代码省略

}


咦,真的是这样。谜底应该就在handleServiceArgs方法了,那么赶紧瞧瞧,源码如下:


private void handleServiceArgs







请到「今天看啥」查看全文