<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      android startService流程梳理筆記

      1、ContextWrapper.startService

        startService是Context的方法,Activity、Service都繼承自ContextWrapper,而ContextWrapper又繼承自Context,BroadcastReceiver的onReceive方法中有個參數(shù)是Context類型的,所以我們在Activity、Service、BroadcastReceiver中都可以調(diào)用startService方法,當在Activity等中調(diào)用startService時,首先會調(diào)用到ContextWrapper的startService方法:

      public ComponentName startService(Intent service) {
          return mBase.startService(service);
      }

      2、ContextImpl.startService

        mBase是ContextImpl的實例,從名字也可以看到ContextImpl也是Context的子類,從ContextWrapper的名字也可以看到,它只是Context的包裝類,其函數(shù)內(nèi)部的實現(xiàn)都是通過調(diào)用內(nèi)部ContextImpl類的實例mBase來完成實際請求,這被稱為裝飾者模式。

        ContextImpl的startService直接調(diào)用startServiceAsUser,在startServiceAsUser中調(diào)用ActivityManagerNative.getDefault().startService,ActivityManagerNative.getDefault()返回一個IActivityManager對象,典型的Binder通信。所以接下來會通過ActivityManagerProxy的startService經(jīng)由Binder調(diào)用到ActivityManagerService(繼承自ActivityManagerNative)的startService方法。

      public ComponentName startServiceAsUser(Intent service, UserHandle user) {
          try {
              service.setAllowFds(false);
              ComponentName cn = ActivityManagerNative.getDefault().startService(
                  mMainThread.getApplicationThread(), service,
                  service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
          ...
              return cn;
          } catch (RemoteException e) {
              return null;
          }
      }

      3、ActivityManagerService.startService與ActiveServices

        在ActivityManagerService的startService中,首先檢查Caller的合法性(PID、UID),然后調(diào)用ActiveServices的startServiceLocked方法(在舊版本中這個方法在ActivityManagerService中),在startServiceLocked中,首先通過retrieveServiceLocked檢索我們調(diào)用startService時傳入的Intent信息,將結(jié)果存入ServiceLookupResult.record中(ServiceRecord),緊接著調(diào)用ActiveServices的bringUpServiceLocked方法。

        在bringUpServiceLocked中調(diào)用ActivityManagerService的startProcessLocked獲得一個ProcessRecord對象并將其加入到mPendingServices隊列中。startServiceLocked、bringUpServiceLocked都是從ActivityManagerService中調(diào)用過來的,所以是一直運行在ActivityaManagerService進程中,再調(diào)用ActivityManagerService的方法就是直接調(diào)用,而不用通過IPC。

        ActivityManagerService中有兩個重載形式的startProcessLocked,首先進入?yún)?shù)多的那一個,通過newProcessRecordLocked獲得一個ProcessRecord對象,然后把這個對象作為參數(shù)調(diào)用另一個形式的startProcessLocked,在這個startProcessLocked中,調(diào)用Process.start創(chuàng)建一個新的進程,將返回的Process.ProcessStartResult對象、新進程的PID及獲得的ProcessRecord對象放入mPidSelfLocked列表中。

      final ProcessRecord startProcessLocked(String processName,
              ApplicationInfo info, boolean knownToBeDead, int intentFlags,
              String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated) {
          ...
          app = newProcessRecordLocked(null, info, processName, isolated);
          ...
          startProcessLocked(app, hostingType, hostingNameStr);
          return (app.pid != 0) ? app : null;
      }
      
      
      private final void startProcessLocked(ProcessRecord app,
              String hostingType, String hostingNameStr) {
          ...
          Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
                          app.processName, uid, uid, gids, debugFlags, mountExternal,
                          app.info.targetSdkVersion, null, null);
          ...
          synchronized (mPidsSelfLocked) {
              this.mPidsSelfLocked.put(startResult.pid, app);
              ...
          }
          ...
      }

      4、ActivityThread.main

        在Process.start中創(chuàng)建了一個進程,然后調(diào)用了ActivityThread的main函數(shù)。

      public static void main(String[] args) {
          ...
          Looper.prepareMainLooper();
          ActivityThread thread = new ActivityThread();
          thread.attach(false);
          if (sMainThreadHandler == null) {
              sMainThreadHandler = thread.getHandler();
          }
          ...
          Looper.loop();
          ...
      }

      5、ActivityManagerService.attachApplication

        在main中新建一個ActivityThread對象,并調(diào)用其attach方法,參數(shù)表示是否是系統(tǒng)進程。這里已經(jīng)是在新進程里了。在attach中,又調(diào)用了ActivityManagerNative.getDefault().attachApplication(mAppThread)。同樣,經(jīng)由Binder由ActivityManagerProxy到了ActivityManagerService的attachApplication方法,在attachApplication中直接調(diào)用attachApplicationLocked。

        在attachApplicationLocked中,通過新進程的PID獲得在第3步中放入mPidSelfLocked列表中的ProcessRecord對象,然后調(diào)用ActiveyServices的attachApplicationLocked方法,在這個方法中通過進程PID與進程名找到在第3步中放入mPendingServices中的ServiceRecord對象,再以這個找到的ServiceRecord對象與傳入的ProcessRecord對象為參數(shù)調(diào)用realStartServiceLocked,這個函數(shù)也在ActiveServices中。

      private final boolean attachApplicationLocked(IApplicationThread thread, nt pid) {
          ProcessRecord app;
          if (pid != MY_PID && pid >= 0) {
              synchronized (mPidsSelfLocked) {
                  app = mPidsSelfLocked.get(pid);
              }
          } else {
              app = null;
          }
          ...
          mServices.attachApplicationLocked(app, processName);
          ...
      }
      
      
      boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
          boolean didSomething = false;
          // Collect any services that are waiting for this process to come up.
          if (mPendingServices.size() > 0) {
              ServiceRecord sr = null;
              try {
                  for (int i=0; i<mPendingServices.size(); i++) {
                      sr = mPendingServices.get(i);
                      if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
                              || !processName.equals(sr.processName))) {
                          continue;
                      }
      
                      mPendingServices.remove(i);
                      i--;
                      realStartServiceLocked(sr, proc);
                      didSomething = true;
                  }
              } catch (Exception e) {
                  Slog.w(TAG, "Exception in new application when starting service "
                          + sr.shortName, e);
                  throw e;
              }
          }
          ...
      }

      6、ActiveServices.realStartServiceLocked

        在realStartServiceLocked中,取得傳入的ProcessRecord對象的IApplicationThread類型的成員變量thread,調(diào)用其scheduleCreateService方法,同ActivityManagerProxy一樣,調(diào)用的是ApplicationThreadProxy的scheduleCreateService,然后經(jīng)由Binder到ApplicationThread的scheduleCreateService(ApplicationThread是ActivityThread的私有內(nèi)部類)。

      7、ApplicationThread.scheduleCreateService與ActivityThread.handleCreateService

        在ApplicationThread的scheduleCreateService中調(diào)用了外部類ActivityThread的queueOrSendMessage方法,向H中sendMessage(H繼承自Handler),接下來肯定到了H的handleMessage,在handleMessage中走CREATE_SERVICE的switch case,調(diào)用外部類ActivityThread的handleCreateService方法。

        在handleCreateService通過JAVA的ClassLoader load加載要啟動的Service的類,并通過newInstance新建一個Service的實例,new ContextImpl,makeApplication并跟新建的Service實例attach,然后調(diào)用我們熟悉的Service的onCreate方法,至此Service啟動成功。

      private void handleCreateService(CreateServiceData data) {
          // If we are getting ready to gc after going to the background, well
          // we are back active so skip it.
          unscheduleGcIdler();
      
          LoadedApk packageInfo = getPackageInfoNoCheck(
                  data.info.applicationInfo, data.compatInfo);
      
          Service service = null;
          try {
              java.lang.ClassLoader cl = packageInfo.getClassLoader();
              service = (Service) cl.loadClass(data.info.name).newInstance();
          } catch (Exception e) {
              ...
          }
      
          try {
              if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
      
              ContextImpl context = new ContextImpl();
              context.init(packageInfo, null, this);
      
              Application app = packageInfo.makeApplication(false, mInstrumentation);
              context.setOuterContext(service);
              service.attach(context, this, data.info.name, data.token, app,
                          ActivityManagerNative.getDefault());
              // 調(diào)用Service的onCreate,即要啟動的Service的onCreate
              service.onCreate();
              mServices.put(data.token, service);
              try {
                  ActivityManagerNative.getDefault().serviceDoneExecuting(
                          data.token, 0, 0, 0);
              } catch (RemoteException e) {
                  // nothing to do.
              }
          } catch (Exception e) {
              ...
          }
      }

       

      總結(jié):

        1、調(diào)用ContextImpl的startService,通過Binder進入ActivityManagerService的進程執(zhí)行ActivityManagerService的startService方法。

        2、在startService過程中新建一個進程,在新建的進程中創(chuàng)建Looper,調(diào)用ActivityThread的attach方法,然后就又進入了ActivityManagerService的進程。

        3、獲取要在新進程啟動的服務(wù)的相關(guān)信息,在ActivityManagerService中通過ApplicationThreadProxy又進入Service進程,Service的進程啟起來,調(diào)用我們熟悉的Service的onCreate方法。

      posted @ 2013-05-24 11:50  AngelDevil  閱讀(11924)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久久精品2019中文字幕之3| 亚洲人成网站色7799| 欧美熟妇乱子伦XX视频| 成人区人妻精品一区二蜜臀| 国产精品尤物乱码一区二区| 亚洲av在线观看| 额敏县| 爆乳日韩尤物无码一区| 国产在线无码精品无码| 亚洲av色图一区二区三区| 国产精品久久香蕉免费播放| 人妻少妇偷人精品一区| 国产午夜精品久久精品电影| 少妇午夜啪爽嗷嗷叫视频| 阿瓦提县| 久久精品国产99麻豆蜜月| 2021国产精品视频网站| 宣城市| 国产精品老熟女一区二区| 亚洲综合一区国产精品| 亚洲欧美综合一区二区三区| 国产精品亚洲精品日韩已满十八小 | 九九热在线精品视频99| 在线观看视频一区二区三区| 国产AV影片麻豆精品传媒| 久青草精品视频在线观看| 欧美经典人人爽人人爽人人片| 一本精品99久久精品77| 一道本AV免费不卡播放| 欧美国产成人精品二区芒果视频 | 美女裸体18禁免费网站| 中文字幕av一区二区| 国产AV影片麻豆精品传媒| 久久综合九色综合久桃花| 亚洲熟妇色xxxxx亚洲| 欧美成人午夜在线观看视频| 亚洲顶级裸体av片| 国产在视频线在精品视频2020| 国产精品欧美福利久久| 国产熟女50岁一区二区| 亚洲色无码播放亚洲成av |