Android: Application, LoadedApk对象

android.app.Apolication

frameworks/base/core/java/android/app/Application.java
/**
 * Base class for maintaining global application state. You can provide your own
 * implementation by creating a subclass and specifying the fully-qualified name
 * of this subclass as the <code>"android:name"</code> attribute in your
 * AndroidManifest.xml's <code>&lt;application&gt;</code> tag. 
 * The Application class, or your subclass of the Application class, is instantiated before any
 * other class when the process for your application/package is created.
 */
//Appliation是提供对组件处理的入口如low memory等
public class Application extends ContextWrapper implements ComponentCallbacks2 {// memory manager lower
    private ArrayList<ComponentCallbacks> mComponentCallbacks =
            new ArrayList<ComponentCallbacks>();
    private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
            new ArrayList<ActivityLifecycleCallbacks>();
    private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null;
 

 //以mComponentCallbacks为例,register/unregister callback

    public void registerComponentCallbacks(ComponentCallbacks callback) {
        synchronized (mComponentCallbacks) {
            mComponentCallbacks.add(callback);
        }
    }

    public void unregisterComponentCallbacks(ComponentCallbacks callback) {
        synchronized (mComponentCallbacks) {
            mComponentCallbacks.remove(callback);
        }
    }
 

    //ArrayList -> Array

    private Object[] collectComponentCallbacks() {
        Object[] callbacks = null;
        synchronized (mComponentCallbacks) {
            if (mComponentCallbacks.size() > 0) {
                callbacks = mComponentCallbacks.toArray();
            }
        }
        return callbacks;
    }

 //当low memory发生时,调用register的callback

    @CallSuper
    public void onLowMemory() {
        Object[] callbacks = collectComponentCallbacks();
        if (callbacks != null) {
            for (int i=0; i<callbacks.length; i++) {
                ((ComponentCallbacks)callbacks[i]).onLowMemory();
            }
        }
    }
}

android.app.LoadedApk

frameworks/base/core/java/android/app/LoadedApk.java
//Local state maintained about a currently loaded .apk.
//apk文件在内存中的展现
public final class LoadedApk {
    static final String TAG = "LoadedApk";
    static final boolean DEBUG = false;

    private final ActivityThread mActivityThread;
    final String mPackageName;

    private ApplicationInfo mApplicationInfo;

    //文件,数据,库等的路径

    private String mAppDir;
    private String mResDir;
    private String[] mOverlayDirs;
    private String mDataDir;
    private String mLibDir;
    private File mDataDirFile;
    private File mDeviceProtectedDataDirFile;
    private File mCredentialProtectedDataDirFile;
    private final ClassLoader mBaseClassLoader;
}
 

ActivityThread attached的过程

 ActivityThread thread = new ActivityThread();
 thread.attach(false);

1]  ApplicationThread mAppThread = new ApplicationThread();

引入ApplicationThread 类

/**
 * System private API for communicating with the application.  This is given to
 * the activity manager by an application  when it starts up, for the activity
 * manager to tell the application about things it needs to do.
 */

    private class ApplicationThread extends IApplicationThread.Stub {// server端

  如接口实现scheduleCreateService

        public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;

            sendMessage(H.CREATE_SERVICE, s);
        }//由ActivityThread的HandleMessage进行处理

 

2. call into ActivityManagerService.attachApplication

    private void attach(boolean system) {

            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            }
 }

    public final void attachApplication(IApplicationThread thread) {//把IApplicationThread 传入server
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            attachApplicationLocked(thread, callingPid);
        }
    }

    private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
        // Find the application record that is being attached...  
        ProcessRecord app;
app = mPidsSelfLocked.get(pid);
        app.makeActive(thread, mProcessStats);
        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;

//ApplicationInfo的信息来着ProcessRecord
        ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
        app.compat = compatibilityInfoForPackageLocked(appInfo);
//bind Application
thread.bindApplication(processName, ...);
    }

3. 又通过IApplicationThread调回ActivityThread

        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) {

            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;
            sendMessage(H.BIND_APPLICATION, data);//HandleMessage处理
        }
HandleMessage:
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

   private void handleBindApplication(AppBindData data) {
//获得LoadApk
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);

        // Instrumentation info affects the class loader, so load it before
        // setting up the app context.
        final InstrumentationInfo ii;
        if (data.instrumentationName != null) {
            try {
                ii = new ApplicationPackageManager(null, getPackageManager())
                        .getInstrumentationInfo(data.instrumentationName, 0);
            } catch (PackageManager.NameNotFoundException e) {
                throw new RuntimeException(
                        "Unable to find instrumentation info for: " + data.instrumentationName);
            }

            mInstrumentationPackageName = ii.packageName;
            mInstrumentationAppDir = ii.sourceDir;
            mInstrumentationSplitAppDirs = ii.splitSourceDirs;
            mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
            mInstrumentedAppDir = data.info.getAppDir();
            mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
            mInstrumentedLibDir = data.info.getLibDir();
        }

// create Application context
        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
        updateLocaleListFromAppContext(appContext, mResourcesManager.getConfiguration().getLocales());

        mInstrumentation = new Instrumentation();
        Application app;
        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);
            mInitialApplication = app;
}
   }

    public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
            CompatibilityInfo compatInfo) {
        return getPackageInfo(ai, compatInfo, null, false, true, false);
    }
 

3.1 怎样获得LoadedApk

    private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
            ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
            boolean registerPackage) {
        final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
        synchronized (mResourcesManager) {
            WeakReference<LoadedApk> ref;
            if (differentUser) {
                // Caching not supported across users
                ref = null;
            } else if (includeCode) {
                ref = mPackages.get(aInfo.packageName);
            } else {
                ref = mResourcePackages.get(aInfo.packageName);
            }

            LoadedApk packageInfo = ref != null ? ref.get() : null;
  if (packageInfo == null){
                packageInfo = new LoadedApk();//创建LoadedApk对象
  }
return packageInfo;
    }
 

3.2 创建Application:based on class load, class name and appContext

    public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {

String appClass = mApplicationInfo.className;
        Application app = null;
        try {
   //create Application
   java.lang.ClassLoader cl = getClassLoader();
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
            appContext.setOuterContext(app);
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;
     }
 

3.2.1 Instrumentation.newApplication

frameworks/base/core/java/android/app/Instrumentation.java
    public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return newApplication(cl.loadClass(className), context);
    }

    static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }
 

3.2.2 attach application context

    /* package */ final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }

frameworks/base/core/java/android/content/ContextWrapper.java
    protected void attachBaseContext(Context base) {
        mBase = base;
    }

猜你喜欢

转载自blog.csdn.net/u011279649/article/details/81018857