[アンドロイド]は、アプリケーションの起動に関連するトピックについて話をする-5.1サービスの原則を

研究内容:

  • サービスを開始するさまざまな方法は何ですか?
  • スタートアップキープロセス中のサービスは何?
  • 参加者を必要とするサービスは次のように通信処理を開始しますか?

サービスは、原則を開始します

STARTSERVICEサービスを開始します。

@Override
public ComponentName startService(Intent service) {
  return startServiceCommon(service, mUser);
}

ComponentName startServiceCommon(Intent service, ...){
  ComponentName cn = ActivityManagerNative.getDefault()
    .startService(mMainThread.getApplicationThread(), service, ...);
  return cn;
}

AMSのプロセス:

ComponentName startService(IApplicationThread caller, Intent service, ...){
  ComponentName res = mServices.startServiceLocked(caller, service, ...);
  return res;
}

意図クエリサービスレコードオブジェクト:
ターゲットServiceRecoreにAMSサービス、端末対応の各アプリケーション

ComponentName startServiceLocked(Intent service, ...){
  ServiceLookupResult res = retrieveServiceLocked(service, ...);
  ServiceRecord r = res.record;
  ...
  //查到ServiceRecord之后new了一个StartItem并加到pendingStart里面,
  //为后面调用onStartCommand准备
  r.pendingStart.add(new ServiceRecord.StartItem(r, ...));
  ...
  return startServiceInnerLocked(smap, service, r, ...);
}

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ...){
  bringUpServiceLocked(r, service.getFlags(), callerFg, false);
}

final String bringUpServiceLocked(ServiceRecord r, ...){
  if(r.app != null && r.app.thread != null) {
    //如果Service已经启动了,就调用下面这个函数,
    //它将触发应用端的onStartCommand
    sendServiceArgsLocked(r, ...);
    return null;
  }
  //Service还没启动的情况:
  ProcessRecord app = mAm.getProcessRecordLocked(procName, ...);
  if(app != null && app.thread != null){
    //如果Service所在的进程已经启动了,真正启动Service
    //r.app就是在下面这个函数中设置的
    realStartServiceLocked(r, app, execInFg);
    return null;
  }
  //Service所在进程没有启动或者虽然已经启动但还没就绪的情况:
  if(app == null){
    //app进程还没启动,启动进程
    app = mAm.startProcessLocked(procName, ...);
  }
  if(!mPendingServices.contains(r)){
    //把ServiceRecord加到pending列表里面,等待进程启动后再处理
    mPendingServices.add(r);
  }
  ...
}

プロセスのフローチャートが開始しました:
ここに画像を挿入説明

  • AMSは、ソケットを介してプロセスを開始する要求を開始した受精卵
  • 受精卵プロセスは、要求の受信後に開始されます
  • バインダーアプリケーションプロセスは、AMSへの呼び出しのattachApplicationを開始し、彼自身のバインダーオブジェクトが(でも準備ができている場合、このアプリケーションのためのAMSのために登録した後)AMSに登録されています
  • アプリケーション・プロセスapplicationThreadを通じてサインアップアプリケーション側へbindApplicationコールを開始し、メインアプリケーションの初期化アプリケーション(AMSコンポーネントを保留扱うことができる起こった後に、この手順)

AMS処理機能のattachApplicationの:

boolean attachApplicationLocked(IApplicationThread thread, ...) {
  ...
  mServices.attachApplicationLocked(app, processName);
  ...
  return true;
}
//处理pending的Service
boolean attachApplicationLocked(ProcessRecord proc, ...){
  for(int i = 0; i < mPendingServices.size(); i++){
    sr = mPendingServices.get(i);
    ...
    mPendingServices.remove(i--);
    //对每一个pending的service调用realStartServiceLocked函数真正启动service
    realStartServiceLocked(sr, proc, ...);
  }
  ...
}

void realStartServiceLocked(ServiceRecord r, ProcessRecord app, ...){
  r.app = app;
  ...
  //向应用端发起IPC调用,应用收到后就会创建Service,执行应用里的onCreate回调
  //参数r其实是一个binder对象: final class ServiceRecord extends Binder{}
  //这是要存在应用端的,应用端有一个用来保存service对象的map,这里的r就是key
  app.thread.scheduleCreateService(r, r.serviceInfo, ...);
  ...
  //触发应用端Service的onStartCommand
  sendServiceArgsLocked(r, ...);
}

AMSアプリケーション側で対処する方法はCreateServicd要求で構成されています。

private void handleCreateService(CreateServiceData data){
  //先拿到loadedApk
  LoadedApk packageInfo = getPackageInfoNoCheck(...);
  //加载Service类,并通过newInstance调用其构造函数,从而获得Service对象
  Service service = (Service)cl.loadClass(data.info.name).newInstance();
  //给这个Service创建一个Context对象
  ContextImpl context = ContextImpl.createAppContext(this, ...);
  //获取Application,这个application是在应用启动的时候创建的
  Application app = packageInfo.makeApplication(flase, ...);
  //给service赋予上下文
  service.attach(context, this, ...);
  //执行Service的生命周期
  service.onCreate();
  mServices.put(data.token, service);
  ...
}

mServices是一个map:
ArrayMap<IBinder, Service>
private final void sendServiceArgsLocked(ServiceRecord r, ){
  while(r.pendingStarts.size() > 0){
    //取出每一个pending的startItem
    StartItem si = r.pendingStarts.remove(0);
    ...
    //向应用端发起IPC调用
    r.app.thread.scheduleServiceArgs(r, ...);
  }
}

AMSは、サービスのアプリケーション側をonStartCommandトリガーされる方法

AMSは、(R、...)r.app.thread.scheduleServiceArgsを呼び出した後に、取引のアプリケーション側:

public final void scheduleServiceArgs(IBinder token, ...) {
  //封装了一个ServiceArgsData对象
  ServiceArgsData s = new ServiceArgsData();
  ...
  //丢到应用的主线程去处理
  sendMessage(H.SERVICE_ARGS, s);
}

//应用端主线程的处理:
private void handleServiceArgs(ServiceArgsData data) {
  //首先从mServices中把Service对象取出来。mService是一个map,其中:
  //key就是AMS中的ServiceRecord的对象
  //value就是应用端的Service对象
  //data.token就是AMS中的ServiceRecord对象
  Service s = mServices.get(data.token);
  if(s != null){
    ...
    //调用Service的onStartCommand
    s.onStartCommand(data.args, data.flags, data.startId);
    ...
  }
}

概要サービスの起動プロセス:

ここに画像を挿入説明
AMSの終わり:

  • サービスのルックには開始されません:あなたは直接コマンドを送信するために開始する場合は、アプリケーション側で実行onStartCommandので()
  • サービスが開始されない場合は、起動しませんでした過程でそれを見るために:あなたはすでに開始している場合は、サービスの開始に行き、そして他のonStartCommandサービスがコマンドを送信するために後の再スタートを実行することを許可
  • プロセスが起動しない場合、プロセスが起動するサービスを開始するなど、ブートプロセスに行ってきました

アプリケーション終了:

  • サービスオブジェクトを作成します。
  • そして、文脈を与えます
  • 最後の呼び出しライフサイクルのonCreate()

サービスがbindServiceで始まります

サービス開始は、別の状況があります:bindService時間BIND_AUTO_CREATEマークを持参します

int bindServiceLocked(IApplicationThread caller, ...){
  ...
  if((flags & Context.BIND_AUTO_CREATE) != 0){
    //如果带上BIND_AUTO_CREATE标记
    bringUpServiceLocked(s, ...);
  }
  ...
}

binderServiceとSTARTSERVICE違い:

  • binderService onStartCommand機能は、アプリケーション側をトリガしません。
  • 無binderServiceのでキューServiceRecordはmPendingStartを追加しました

サービスの原則について話を開始します。リターン

  • サービスを開始するには、いくつかの方法がありますか?
    A)STARTSERVICE
    BIND_AUTO_CREATE bindServiceとB)
  • メインサービスの起動プロセスは何?
    a)はAMSの終わり:
    1)サービスを見ては起動しない:アプリケーション側がonStartCommand行うので、あなたは直接コマンドを送信するために開始した場合は()
    サービスが開始されない場合は、プロセスでそれを見るために、)2が起動しませんでした:あなたはすでに、あなたを開始している場合など、サービスの開始後、起動した後、送信コマンドがonStartCommand実行を許可するサービス
    プロセスが起動するサービスを開始のようなプロセスは、プロセスを開始するために行くに起動しない場合)、次に3を

B)アプリケーション側:
1)サービスオブジェクトを作成
2)、次いでコンテキストを与える
3)最後に(ライフサイクルのonCreateコール)

  • 以下のような参加者、通信プロセスサービスの起動プロセス?
    a)は、次の図を参照して:ここに画像を挿入説明
公開された119元の記事 ウォン称賛28 ビュー10万+

おすすめ

転載: blog.csdn.net/menghaocheng/article/details/104595958