Android深入四大组件(一)应用程序启动过程(前篇)

activity_cover-1024x576_副本.png

前言

在此前的文章中,我讲过了Android系统启动流程和Android应用进程启动过程,这一篇顺理成章来学习Android 7.0的应用程序的启动过程。分析应用程序的启动过程其实就是分析根Activity的启动过程。

1.Launcher请求ActivityManageService

在 Android系统启动流程(四)Launcher启动过程与系统启动流程这篇文章我讲过Launcher启动后会将已安装应用程序的快捷图标显示到界面上,当我们点击应用程序的快捷图标时就会调用Launcher的startActivitySafely方法,如下所示。
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

public boolean startActivitySafely(View v, Intent intent, Object tag) {
    ...
      try {
          success = startActivity(v, intent, tag);
      } catch (ActivityNotFoundException e) {
          Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
          Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
      }
      return success;
  }

startActivitySafely函数中主要就是调用了startActivity函数:
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

private boolean startActivity(View v, Intent intent, Object tag) {
       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//1
       try {
         ...
           if (user == null || user.equals(UserHandleCompat.myUserHandle())) {
               StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
               try {            
                   StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
                           .penaltyLog().build());
                   startActivity(intent, optsBundle);//2
               } finally {
                   StrictMode.setVmPolicy(oldPolicy);
               }
           } else {
               launcherApps.startActivityForProfile(intent.getComponent(), user,
                       intent.getSourceBounds(), optsBundle);
           }
           return true;
       } catch (SecurityException e) {      
         ...
       }
       return false;
   }

在注释1处设置Flag为Intent.FLAG_ACTIVITY_NEW_TASK,这样根Activity会在新的任务栈中启动。在注释2处调用了startActivity函数:
frameworks/base/core/java/android/app/Activity.java

Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
}

startActivity会调用startActivityForResult函数,其中第二个参数为-1,表示Launcher不需要知道Activity启动的结果,startActivityForResult函数的代码如下所示。
frameworks/base/core/java/android/app/Activity.java

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
           @Nullable Bundle options) {
       if (mParent == null) {
           Instrumentation.ActivityResult ar =
               mInstrumentation.execStartActivity(
                   this, mMainThread.getApplicationThread(), mToken, this,
                   intent, requestCode, options);
        ...
       } else {
        ...
       }
   }

mParent是Activity类型的,表示当前Activity的父类。因为目前根Activity还没有创建出来,因此,mParent == null成立。接着调用Instrumentation的execStartActivity方法,Instrumentation主要用来监控应用程序和系统的交互,execStartActivity方法的代码如下所示。
frameworks/base/core/java/android/app/Instrumentation.java

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
      ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

首先会调用ActivityManagerNative的getDefault来获取ActivityManageService(以后简称为AMS)的代理对象,接着调用它的startActivity方法。首先我们先来查看ActivityManagerNative的getDefault方法做了什么:
frameworks/base/core/java/android/app/ActivityManagerNative.java

  static public IActivityManager getDefault() {
        return gDefault.get();
    }

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");//1
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);//2
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
}

getDefault方法调用了gDefault的get方法,我们接着往下看,gDefault 是一个Singleton类。注释1处得到名为”activity”的Service引用,也就是IBinder类型的ActivityManagerService的引用。接着在注释2处将它封装成ActivityManagerProxy(以后简称为AMP)类型对象,并将它保存到gDefault中,此后调用ActivityManagerNative的getDefault方法就会直接获得AMS的代理AMP对象。
回到Instrumentation类的execStartActivity方法中,从上面得知就是调用AMP的startActivity,其中AMP是ActivityManagerNative的内部类,代码如下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
           String resolvedType, IBinder resultTo, String resultWho, int requestCode,
           int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
       Parcel data = Parcel.obtain();
       Parcel reply = Parcel.obtain();
       data.writeInterfaceToken(IActivityManager.descriptor);
       data.writeStrongBinder(caller != null ? caller.asBinder() : null);
       data.writeString(callingPackage);
       intent.writeToParcel(data, 0);
       data.writeString(resolvedType);
       data.writeStrongBinder(resultTo);
       data.writeString(resultWho);
       data.writeInt(requestCode);
       data.writeInt(startFlags);
       if (profilerInfo != null) {
           data.writeInt(1);
           profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
       } else {
           data.writeInt(0);
       }
       if (options != null) {
           data.writeInt(1);
           options.writeToParcel(data, 0);
       } else {
           data.writeInt(0);
       }
       mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);//1
       reply.readException();
       int result = reply.readInt();
       reply.recycle();
       data.recycle();
       return result;
   }

首先会将传入的参数写入到Parcel类型的data中。在注释1处通过IBinder类型对象mRemote向AMS发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。那么服务端AMS就会从Binder线程池中读取我们客户端发来的数据,最终会调用ActivityManagerNative的onTransact方法中执行,如下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java

@Override
   public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
           throws RemoteException {
       switch (code) {
       case START_ACTIVITY_TRANSACTION:
       {
   ...
           int result = startActivity(app, callingPackage, intent, resolvedType,
                   resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
           reply.writeNoException();
           reply.writeInt(result);
           return true;
       }
   }

onTransact中会调用AMS的startActivity方法,如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override
 public final int startActivity(IApplicationThread caller, String callingPackage,
         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
         int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
     return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
             resultWho, requestCode, startFlags, profilerInfo, bOptions,
             UserHandle.getCallingUserId());
 }

为了便于理解,给出Launcher到AMS调用过程的时序图。

友情链接:万达娱乐主管QQ  万达主管QQ  万达主管QQ  万达娱乐招商  万达娱乐  万达娱乐开户  万达登录  万达娱乐  万达招商  万达娱乐开户