App启动流程分析

当你在手机上安装一个app应用后,只要点击手机桌面上的app图标就可以开启这个应用,虽然这个操作很简单,但你知道它的实现原理吗?如果你是一位纯应用的app应用开发者,可能你根本不会去了解它是怎么实现的,因为你关注的只是app。如果你比较熟悉了,此博文略过哈。今天我们就一起来学习下app是如何在安卓系统中启动起来的?

一、初步分析

    我们的app应用安装在手机后在手机桌面上会有一个图标,这个图标就是app的启动图标。其实手机桌面,稍微对framework层代码有过接触的人都知道,它对应的就是Lanucher模块,说明启动app应用的起始点就是在Launcher。至于Launcher,它的代码量有点多,这里就不一一介绍了,这不是此博文的重点。Java代码有个类方法入口:public static void main(String [] args); 我们的app启动也有个类方法入口,那就是ActivityThread类,它里面也有个:

public static void main(String[] args)

这跟java入口方法一模一样,接下来我们一起分析下:

二、ActivityThread类

    我们先把main方法的代码贴一下:

public static void main(String[] args) {
    SamplingProfilerIntegration.start();
    CloseGuard.setEnabled(false);
    Environment.initForCurrentUser();
    EventLogger.setReporter(newActivityThread.EventLoggingReporter(null));
    Security.addProvider(newAndroidKeyStoreProvider());
   Process.setArgV0("<pre-initialized>");
    Looper.prepareMainLooper();
    ActivityThread thread = newActivityThread();
    thread.attach(false);
    if(sMainThreadHandler == null) {
        sMainThreadHandler =thread.getHandler();
    }
    AsyncTask.init();
    Looper.loop();
    throw new RuntimeException("Mainthread loop unexpectedly exited");
}

这句代码Looper.prepareMainLooper();可以看出为什么在主线程创建Handler不用调用Looper.prepare();方法,因为它默认已经调用了。接着往下走,ActivityThread thread = new ActivityThread();它实例化了一个ActivityThread对象,然后调用thread.attach(false);这句代码是关键,我们进入attach方法:

private void attach(boolean system) {
    sCurrentActivityThread = this;
    this.mSystemThread = system;
    if(!system) {
       ViewRootImpl.addFirstDrawHandler(new Runnable() {
            public void run() {
               ActivityThread.this.ensureJitEnabled();
            }
        });
       DdmHandleAppName.setAppName("<pre-initialized>",UserHandle.myUserId());
       RuntimeInit.setApplicationObject(this.mAppThread.asBinder());
        IActivityManager e =ActivityManagerNative.getDefault();

        try {
            e.attachApplication(this.mAppThread);
        } catch (RemoteException var5) {
            ;
        }
    } else {
       DdmHandleAppName.setAppName("system_process",UserHandle.myUserId());

        try {
            this.mInstrumentation = newInstrumentation();
            ContextImpl e1 =ContextImpl.createAppContext(this, this.getSystemContext().mPackageInfo);
            Application app =Instrumentation.newApplication(Application.class, e1);
           this.mAllApplications.add(app);
            this.mInitialApplication =app;
            app.onCreate();
        } catch (Exception var4) {
            throw newRuntimeException("Unable to instantiate Application():" +var4.toString(), var4);
        }
    }

    DropBox.setReporter(newActivityThread.DropBoxReporter());
    ViewRootImpl.addConfigCallback(newComponentCallbacks2() {
        public voidonConfigurationChanged(Configuration newConfig) {
           synchronized(ActivityThread.this.mResourcesManager) {
               if(ActivityThread.this.mResourcesManager.applyConfigurationToResourcesLocked(newConfig,(CompatibilityInfo)null) && (ActivityThread.this.mPendingConfiguration== null ||ActivityThread.this.mPendingConfiguration.isOtherSeqNewer(newConfig))) {
                   ActivityThread.this.mPendingConfiguration = newConfig;
                   ActivityThread.this.sendMessage(118, newConfig);
                }

            }
        }

        public void onLowMemory() {
        }

        public void onTrimMemory(intlevel) {
        }
    });
}

方法里分应用app和系统app,我们这里只分析应用的app,有兴趣的同学可以自己去研究哈。

IActivityManager e =ActivityManagerNative.getDefault(); 创建IActivityManager e对象,这个对象是通过ActivityManagerNative类里的getDefault方法获取的,我们进入到ActivityManagerNative类:

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

这里通过gDefault的get()方法返回IActivityManager对象,再来看下gDefault是何方神圣。我们找到代码:

private static finalSingleton<IActivityManager> gDefault = new Singleton() {
    protected IActivityManager create() {
        IBinder b = ServiceManager.getService("activity");
        IActivityManager am =ActivityManagerNative.asInterface(b);
        return am;
    }
};

这里利用了Binder机制来创建IActivityManager,其中ServiceManager其实它的实现就是ActivityManagerService,以下简称AMS,它是android系统一种重要的服务。我们回到上面的attach()方法:

IActivityManager e =ActivityManagerNative.getDefault();
try {
    e.attachApplication(this.mAppThread);
} catch (RemoteException var5) {
    ;
}

获取到IActivityManager对象后,调用了e.attachApplication(this.mAppThread);方法,IActivityManager的attachApplication方法也是在AMS中实现的,我们进入AMS中的这个方法:

@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid =Binder.getCallingPid();
        final long origId =Binder.clearCallingIdentity();
        attachApplicationLocked(thread,callingPid);
       Binder.restoreCallingIdentity(origId);
    }
}

attachApplication方法中又调用了attachApplicationLocked(thread,callingPid);再进入这个方法瞧一睢:

private final booleanattachApplicationLocked(IApplicationThread thread,
        int pid) {
 …………
    // See if the top visible activity iswaiting to run in this process...
    if (normalMode) {
        try {
            if(mStackSupervisor.attachApplicationLocked(app, mHeadless)) {
                didSomething = true;
            }
        } catch (Exception e) {
            badApp = true;
        }
    }

    // Find any services that should berunning in this process...
    if (!badApp) {
        try {
            didSomething |=mServices.attachApplicationLocked(app, processName);
        } catch (Exception e) {
            badApp = true;
        }
    }
…………
    return true;
}

我们简化了attachApplicationLocked代码,如上图。从上面代码我们很容易看出它又调用了mStackSupervisor.attachApplicationLocked(app, mHeadless);这个mStackSupervisor是何方神圣呢?继续追踪代码,发现它是ActivityStackSupervisor对象,然后我们进入ActivityStackSupervisor类找到对应的attachApplicationLocked方法,代码如下:

booleanattachApplicationLocked(ProcessRecord app, boolean headless) throws Exception {
    boolean didSomething = false;
    final String processName =app.processName;
    for (int stackNdx = mStacks.size() -1; stackNdx >= 0; --stackNdx) {
        final ActivityStack stack =mStacks.get(stackNdx);
        if (!isFrontStack(stack)) {
            continue;
        }
        ActivityRecord hr =stack.topRunningActivityLocked(null);
        if (hr != null) {
            if (hr.app == null &&app.uid == hr.info.applicationInfo.uid
                    &&processName.equals(hr.processName)) {
                try {
                    if (headless) {
                        Slog.e(TAG,"Starting activities not supported on headless device: "
                                + hr);
                    } else if(realStartActivityLocked(hr, app, true, true)) {
                        didSomething =true;
                    }
                } catch (Exception e) {
                    Slog.w(TAG,"Exception in new application when starting activity "
                          +hr.intent.getComponent().flattenToShortString(), e);
                    throw e;
                }
            }
        }
    }
    if (!didSomething) {
       ensureActivitiesVisibleLocked(null, 0);
    }
    return didSomething;
}

attachApplicationLocked方法代码比较简单,但我们还是抓重点,我们会看到这个realStartActivityLocked(hr, app, true, true);真正的逻辑就在这里,我们继续追踪:

final boolean realStartActivityLocked(ActivityRecordr,
        ProcessRecord app, booleanandResume, boolean checkConfig)
        throws RemoteException {

…………
       app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
        app.thread.scheduleLaunchActivity(newIntent(r.intent), r.appToken,
               System.identityHashCode(r), r.info,
                newConfiguration(mService.mConfiguration), r.compat,
                app.repProcState,r.icicle, results, newIntents, !andResume,
                mService.isNextTransitionForward(),profileFile, profileFd,
                profileAutoStop);

        if((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
            // This may be a heavy-weightprocess!  Note that the package
            // manager will ensure thatonly activity can run in the main
            // process of the .apk, whichis the only thing that will be
            // considered heavy-weight.
            if(app.processName.equals(app.info.packageName)) {
                if (mService.mHeavyWeightProcess!= null
                        &&mService.mHeavyWeightProcess != app) {
                    Slog.w(TAG,"Starting new heavy weight process " + app
                            + " whenalready running "
                            + mService.mHeavyWeightProcess);
                }
               mService.mHeavyWeightProcess = app;
                Message msg =mService.mHandler.obtainMessage(
                       ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
                msg.obj = r;
               mService.mHandler.sendMessage(msg);
            }
        }
…………
    return true;
}

定位到核心代码app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),r.compat, app.repProcState, r.icicle, results, newIntents, !andResume,mService.isNextTransitionForward(), profileFile, profileFd, profileAutoStop);这里调用了app.thread的scheduleLaunchActivity方法,这里app.thread是啥呢?我们继续追踪,其实它就是ActivityThread,很高兴我们又回到了起始的地方,从哪里来回哪里去,哈哈,别开小差,继续看代码,我们找到了ActivityThread里的scheduleLaunchActivity方法,代码如下:

public final voidscheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfoinfo, Configuration curConfig, CompatibilityInfo compatInfo, int procState,Bundle state, List<ResultInfo> pendingResults, List<Intent>pendingNewIntents, boolean notResumed, boolean isForward, String profileName,ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
    this.updateProcessState(procState,false);
    ActivityThread.ActivityClientRecord r= new ActivityThread.ActivityClientRecord();
    r.token = token;
    r.ident = ident;
    r.intent = intent;
    r.activityInfo = info;
    r.compatInfo = compatInfo;
    r.state = state;
    r.pendingResults = pendingResults;
    r.pendingIntents = pendingNewIntents;
    r.startsNotResumed = notResumed;
    r.isForward = isForward;
    r.profileFile = profileName;
    r.profileFd = profileFd;
    r.autoStopProfiler =autoStopProfiler;
    this.updatePendingConfiguration(curConfig);
    ActivityThread.this.sendMessage(100,r);
}

我们看到最后一行代码:ActivityThread.this.sendMessage(100, r);这里发送了一个消息,我们继续追踪:

private void sendMessage(int what, Objectobj) {
    this.sendMessage(what, obj, 0, 0,false);
}

继续看sendMessage方法代码:

private void sendMessage(int what, Objectobj, int arg1, int arg2, boolean async) {
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if(async) {
        msg.setAsynchronous(true);
    }
    this.mH.sendMessage(msg);
}

最后一行代码是重点:this.mH.sendMessage(msg);我们找到接收的地方,直接上代码:

case 100:
    Trace.traceBegin(64L,"activityStart");
    data =(ActivityThread.ActivityClientRecord)msg.obj;
    data.packageInfo =ActivityThread.this.getPackageInfoNoCheck(data.activityInfo.applicationInfo,data.compatInfo);
   ActivityThread.this.handleLaunchActivity(data, (Intent)null);
    Trace.traceEnd(64L);
    break;

这里我们主要看ActivityThread.this.handleLaunchActivity(data, (Intent)null);这句代码,继续看代码:

private void handleLaunchActivity(ActivityThread.ActivityClientRecordr, Intent customIntent) {
    this.unscheduleGcIdler();
    if(r.profileFd != null) {
       this.mProfiler.setProfiler(r.profileFile, r.profileFd);
        this.mProfiler.startProfiling();
        this.mProfiler.autoStopProfiler =r.autoStopProfiler;
    }
   this.handleConfigurationChanged((Configuration)null,(CompatibilityInfo)null);
    Activity a =this.performLaunchActivity(r, customIntent);
    if(a == null) {
        try {
            ActivityManagerNative.getDefault().finishActivity(r.token,0, (Intent)null);
        } catch (RemoteException var6) {
            ;
        }
    } else {
        r.createdConfig = newConfiguration(this.mConfiguration);
        Bundle ex = r.state;
        this.handleResumeActivity(r.token,false, r.isForward, !r.activity.mFinished && !r.startsNotResumed);
        if(!r.activity.mFinished&& r.startsNotResumed) {
            try {
                r.activity.mCalled =false;
               this.mInstrumentation.callActivityOnPause(r.activity);
                if(r.isPreHoneycomb()) {
                    r.state = ex;
                }

                if(!r.activity.mCalled) {
                    throw newSuperNotCalledException("Activity " + r.intent.getComponent().toShortString()+ " did not call through to super.onPause()");
                }
            } catch(SuperNotCalledException var7) {
                throw var7;
            } catch (Exception var8) {
               if(!this.mInstrumentation.onException(r.activity, var8)) {
                    throw newRuntimeException("Unable to pause activity " +r.intent.getComponent().toShortString() + ": " + var8.toString(),var8);
                }
            }

            r.paused = true;
        }
    }

}

我们找到这行代码:Activity a = this.performLaunchActivity(r, customIntent);这里又调用了performLaunchActivity(r,customIntent);方法,其代码如下:

private ActivityperformLaunchActivity(ActivityThread.ActivityClientRecord r, IntentcustomIntent) {
    ActivityInfo aInfo = r.activityInfo;
   if(r.packageInfo == null) {
        r.packageInfo =this.getPackageInfo((ApplicationInfo)aInfo.applicationInfo, r.compatInfo, 1);
    }

    ComponentName component =r.intent.getComponent();
    if(component == null) {
        component = r.intent.resolveActivity(this.mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }

    if(r.activityInfo.targetActivity !=null) {
        component = newComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity);
    }

    Activity activity = null;

    try {
        ClassLoader e =r.packageInfo.getClassLoader();
        activity =this.mInstrumentation.newActivity(e, component.getClassName(), r.intent);
       StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(e);
        if(r.state != null) {
            r.state.setClassLoader(e);
        }
    } catch (Exception var13) {
       if(!this.mInstrumentation.onException(activity, var13)) {
            throw new RuntimeException("Unableto instantiate activity " + component + ": " + var13.toString(),var13);
        }
    }

    try {
        Application e1 =r.packageInfo.makeApplication(false, this.mInstrumentation);
        if(activity != null) {
            Context appContext =this.createBaseContextForActivity(r, activity);
            CharSequence title =r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = newConfiguration(this.mCompatConfiguration);
            activity.attach(appContext,this, this.getInstrumentation(), r.token, r.ident, e1, r.intent,r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances,config);
            if(customIntent != null) {
                activity.mIntent =customIntent;
            }

           r.lastNonConfigurationInstances = null;
            activity.mStartedActivity =false;
            int theme =r.activityInfo.getThemeResource();
            if(theme != 0) {
                activity.setTheme(theme);
            }

            activity.mCalled = false;
           this.mInstrumentation.callActivityOnCreate(activity, r.state);
            if(!activity.mCalled) {
                throw newSuperNotCalledException("Activity " +r.intent.getComponent().toShortString() + " did not call through tosuper.onCreate()");
            }

            r.activity = activity;
            r.stopped = true;
            if(!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }

            if(!r.activity.mFinished&& r.state != null) {
               this.mInstrumentation.callActivityOnRestoreInstanceState(activity,r.state);
            }

            if(!r.activity.mFinished) {
                activity.mCalled = false;
               this.mInstrumentation.callActivityOnPostCreate(activity, r.state);
                if(!activity.mCalled) {
                    throw newSuperNotCalledException("Activity " +r.intent.getComponent().toShortString() + " did not call through tosuper.onPostCreate()");
                }
            }
        }

        r.paused = true;
        this.mActivities.put(r.token, r);
    } catch (SuperNotCalledExceptionvar11) {
        throw var11;
    } catch (Exception var12) {
        if(!this.mInstrumentation.onException(activity,var12)) {
            throw newRuntimeException("Unable to start activity " + component + ":" + var12.toString(), var12);
        }
    }

    return activity;
}

我们找到其中的关键代码:

try {
    ClassLoader e = r.packageInfo.getClassLoader();
    activity = this.mInstrumentation.newActivity(e, component.getClassName(), r.intent);
    StrictMode.incrementExpectedActivityCount(activity.getClass());
    r.intent.setExtrasClassLoader(e);
    if(r.state != null) {
        r.state.setClassLoader(e);
    }
} catch (Exception var13) {
    if(!this.mInstrumentation.onException(activity, var13)) {
        throw new RuntimeException("Unable to instantiate activity " + component + ": " + var13.toString(), var13);
    }
}

这里的关键代码是:

activity = this.mInstrumentation.newActivity(e, component.getClassName(), r.intent);

从代码中可以看出它调用了mInstrumentation的newActivity(e, component.getClassName(), r.intent);方法,其代码如下:

public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Activity)cl.loadClass(className).newInstance();
}

它返回了一个实例对象,其他的什么也没做,我们回到ActivityThread的performLaunchActivity方法,继续往下跟踪代码,发现有一行代码:

this.mInstrumentation.callActivityOnCreate(activity, r.state);

到这里你是否看到了一点点希望之光,这跟Activity的生命周期方法onCreate方法很像,接着再看callActivityOnCreate代码:

public void callActivityOnCreate(Activity activity, Bundle icicle) {
    Object var3;
    int N;
    int i;
    if(this.mWaitingActivities != null) {
        var3 = this.mSync;
        synchronized(this.mSync) {
            N = this.mWaitingActivities.size();

            for(i = 0; i < N; ++i) {
                Instrumentation.ActivityWaiter am = (Instrumentation.ActivityWaiter)this.mWaitingActivities.get(i);
                Intent intent = am.intent;
                if(intent.filterEquals(activity.getIntent())) {
                    am.activity = activity;
                    this.mMessageQueue.addIdleHandler(new Instrumentation.ActivityGoing(am));
                }
            }
        }
    }

    activity.performCreate(icicle);
    if(this.mActivityMonitors != null) {
        var3 = this.mSync;
        synchronized(this.mSync) {
            N = this.mActivityMonitors.size();

            for(i = 0; i < N; ++i) {
                Instrumentation.ActivityMonitor var12 = (Instrumentation.ActivityMonitor)this.mActivityMonitors.get(i);
                var12.match(activity, activity, activity.getIntent());
            }
        }
    }

}

从方法代码里我们看出有这样一行代码activity.performCreate(icicle);这里调用了performCreate方法,performCreate方法代码如下:

final void performCreate(Bundle icicle) {
    this.onCreate(icicle);
    this.mVisibleFromClient = !this.mWindow.getWindowStyle().getBoolean(10, false);
    this.mFragments.dispatchActivityCreated();
}

this.onCreate(icicle);这个就是我们要找的方法了,它就是回调activity的onCreate生命周期方法。

   app启动流程就分析到这了,不好的地方请大家批评指正。

猜你喜欢

转载自blog.csdn.net/wufeiqing/article/details/80143086