美文网首页
Application的创建

Application的创建

作者: 风月寒 | 来源:发表于2020-12-15 11:49 被阅读0次

应用程序的开始可以说就是从ActivityThread.java中的main()方法开始的

public static void main(String[] args) {
        

        Looper.prepareMainLooper();
        ...
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);
        ...
    }

而 应用程序与AMS相关联就是在attach()中。

private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ...
            final IActivityManager mgr = ActivityManager.getService();//1
            try {
                mgr.attachApplication(mAppThread, startSeq);//2
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            // Watch for getting close to heap limit.
            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    if (!mSomeActivitiesChanged) {
                        return;
                    }
                    Runtime runtime = Runtime.getRuntime();
                    long dalvikMax = runtime.maxMemory();
                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                    if (dalvikUsed > ((3*dalvikMax)/4)) {
                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                                + " total=" + (runtime.totalMemory()/1024)
                                + " used=" + (dalvikUsed/1024));
                        mSomeActivitiesChanged = false;
                        try {
                            ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                    }
                }
            });
        } else {
            ...
        };
        
    }

有上面可知,在attach()传入的是false,则会走if里面。

 @UnsupportedAppUsage
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    @UnsupportedAppUsage
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

从上面可以知道,在1处拿到的是ActivityManager的一个代理类,实现了IActivityManager接口,表明用于具体的功能。

public interface IActivityManager extends IInterface {}

public static com.example.aidl.MessageSender asInterface(android.os.IBinder obj)
    {
      if ((obj==null)) {
        return null;
      }
      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (((iin!=null)&&(iin instanceof com.example.aidl.MessageSender))) {
        return ((com.example.aidl.MessageSender)iin);
      }
      return new com.example.aidl.MessageSender.Stub.Proxy(obj);
    }

由上面可知,如果在同一个进程,当前对象,如果不在同一个进程则返回其代理类。

获得IActivityManager实例之后,将会执行它的attachApplication(mAppThread,startSeq)方法。该方法会传入一个mAppThread参数。

mAppThread是ApplicationThread的实例,而ApplicationThread是ActivityThread的内部类。

private class ApplicationThread extends IApplicationThread.Stub {}

在Binder通信中,有两类角色,一类的基类是IBinder,用于通信,一类是IInterface,用于具体的功能。 在Binder的跨进程通信中,本地进程是真实对象,其他进程是代理对象。 Stub具有双重身份即是IBinder的真实实现也是IInterface的真实实现,IBinder的代理实现是BinderProxy,IInterface的代理实现是Stub.Proxy。 获取到IBinder对象后,使用Stub中的static方法asInterface中,入参IBinder,在本地进程中是就是Stub对象,在其他进程中是BinderProxy,通过queryLocalInterface来区分进程,如果是本地进程,由于Stub具有双重角色,所以直接返回的是Stub对象;如果是其他进程,那么需要创建IInterface的代理对象也就是Stub.Proxy,构造参数是BinderProxy对象。 在拿到IInterface的真实对象或代理对象之后,调用某个具体的功能方法invoke时,如果是真实对象Stub,那么直接进行处理;如果是Stub.Proxy功能代理对象,那么会使用它持有的BinderProxy对象去调用,在BinderProxy对象中,通过native方法触发真实Binder即Stub里的真实方法,完成一次通信。

传递给attachApplication()参数的是ApplicationThread类型的Binder对象,它主要的作用是用来进行进程间的通信。

public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 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方法。

public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {      
    …      
    private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {      
    //创建app对象      
    ProcessRecord app;          
    if (pid != MY_PID && pid >= 0) {              
        synchronized (mPidsSelfLocked) {                  
            app = mPidsSelfLocked.get(pid);              
        }              
    } else {              
        app = null;          
    }     
     …      
    //优化odex文件      
    ensurePackageDexOpt(app.instrumentationInfo != null =? app.instrumentationInfo.packageName                      : 
app.info.packageName);     
     …      
    thread.bindApplication(processName, appInfo, providers,                      
    app.instrumentationClass, profileFile, profileFd, profileAutoStop,                      
    app.instrumentationArguments, app.instrumentationWatcher,                      
    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,                      isRestrictedBackupMode || !normalMode, app.persistent,                      new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),                      
    mCoreSettingsObserver.getCoreSettingsLocked());  //4            
    updateLruProcessLocked(app, false, null);      
   
}

在这会调用thread.bindApplication(),这个thread是bindler对象,相当于跨进程调用ApplicationThread的bindApplication()。

public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, AutofillOptions autofillOptions,
                ContentCaptureOptions contentCaptureOptions) {
                ...
            setCoreSettings(coreSettings);

            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providers;
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            data.buildSerial = buildSerial;
            data.autofillOptions = autofillOptions;
            data.contentCaptureOptions = contentCaptureOptions;
            sendMessage(H.BIND_APPLICATION, data);
        }

上面的通信都是在Binder线程池里操作,会通过Handler转到主线程来进行后续的操作。

 public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);//5
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

继续会走handleBindApplication(),在这个方法里面会创建Application.

private void handleBindApplication(AppBindData data) {
        ...
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        updateLocaleListFromAppContext(appContext,
                mResourcesManager.getConfiguration().getLocales());

        ...
        Application app;
        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
        final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
        try {
            // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
            app = data.info.makeApplication(data.restrictedBackupMode, null);//6

            // Propagate autofill compat state
            app.setAutofillOptions(data.autofillOptions);

            // Propagate Content Capture options
            app.setContentCaptureOptions(data.contentCaptureOptions);

            mInitialApplication = app;

            // don't bring up providers in restricted mode; they may depend on the
            // app's custom Application class
            if (!data.restrictedBackupMode) {
                if (!ArrayUtils.isEmpty(data.providers)) {
                    installContentProviders(app, data.providers);
                }
            }

            // Do this after providers, since instrumentation tests generally start their
            // test thread at this point, and we don't want that racing.
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);//7
            }
            catch (Exception e) {
                throw new RuntimeException(
                    "Exception thrown in onCreate() of "
                    + data.instrumentationName + ": " + e.toString(), e);
            }
            try {
                mInstrumentation.callApplicationOnCreate(app);//8
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                      "Unable to create application " + app.getClass().getName()
                      + ": " + e.toString(), e);
                }
            }
        } finally {
            // If the app targets < O-MR1, or doesn't change the thread policy
            // during startup, clobber the policy to maintain behavior of b/36951662
            if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1
                    || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {
                StrictMode.setThreadPolicy(savedPolicy);
            }
        }

    }

从6可知,会调用makeApplication()创建application。

@UnsupportedAppUsage
    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

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

        Application app = null;

        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);//9
            appContext.setOuterContext(app);
        } catch (Exception e) {
            
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);//10
            } catch (Exception e) {
                if (!instrumentation.onException(app, e)) {
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
        }

        return app;
    }

有9可知,调用newApplication(),先是通过反射创建Application实例,然后将context与Application关联起来。

public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context);
        return app;
    }
    
public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
            @NonNull String className)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Application) cl.loadClass(className).newInstance();
    }

在10中,如果instrumentation != null,则会调用instrumentation.callApplicationOnCreate(app);这里面其实什么都没做,只是回调了下application的onCreate方法。

这样application就创建出来了。

相关文章

网友评论

      本文标题:Application的创建

      本文链接:https://www.haomeiwen.com/subject/xvtwgktx.html