ActivityThread的handleBindApplication方法是Android应用程序启动过程中的一个重要方法。它负责处理应用程序绑定到ActivityThread的过程。具体来说,handleBindApplication方法执行以下操作:
-
创建Application对象:handleBindApplication方法首先通过LoadedApk.makeApplication方法创建Application对象。LoadedApk是应用程序的APK文件的表示,makeApplication方法会使用反射机制调用Application的构造函数创建Application对象。
-
绑定ApplicationThread:handleBindApplication方法会将ApplicationThread与Application对象进行绑定。ApplicationThread是一个Binder对象,它是应用程序与系统服务之间进行通信的桥梁。
-
执行Application的onCreate方法:handleBindApplication方法会调用Application对象的onCreate方法,这是应用程序启动过程中的第一个回调方法。开发者可以在onCreate方法中进行一些初始化操作,例如注册广播接收器、初始化数据库等。
下面从代码角度进行分析:
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler implements ActivityThreadInternal {
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
private void handleBindApplication(AppBindData data) {
// Register the UI Thread as a sensitive thread to the runtime.
VMRuntime.registerSensitiveThread();
// In the case the stack depth property exists, pass it down to the runtime.
String property = SystemProperties.get("debug.allocTracker.stackDepth");
if (property.length() != 0) {
VMDebug.setAllocTrackerStackDepth(Integer.parseInt(property));
}
if (data.trackAllocation) {
DdmVmInternal.setRecentAllocationsTrackingEnabled(true);
}
// Note when this process has started.
Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis(),
data.startRequestedElapsedTime, data.startRequestedUptime);
AppCompatCallbacks.install(data.disabledCompatChanges);
// Let libcore handle any compat changes after installing the list of compat changes.
AppSpecializationHooks.handleCompatChangesBeforeBindingApplication();
mBoundApplication = data;
mConfigurationController.setConfiguration(data.config);
mConfigurationController.setCompatConfiguration(data.config);
mConfiguration = mConfigurationController.getConfiguration();
mProfiler = new Profiler();
String agent = null;
if (data.initProfilerInfo != null) {
mProfiler.profileFile = data.initProfilerInfo.profileFile;
mProfiler.profileFd = data.initProfilerInfo.profileFd;
mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput;
if (data.initProfilerInfo.attachAgentDuringBind) {
agent = data.initProfilerInfo.agent;
}
}
// send up app name; do this *before* waiting for debugger
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName,
data.appInfo.packageName,
UserHandle.myUserId());
VMRuntime.setProcessPackageName(data.appInfo.packageName);
// Pass data directory path to ART. This is used for caching information and
// should be set before any application code is loaded.
VMRuntime.setProcessDataDirectory(data.appInfo.dataDir);
if (mProfiler.profileFd != null) {
mProfiler.startProfiling();
}
// If the app is Honeycomb MR1 or earlier, switch its AsyncTask
// implementation to use the pool executor. Normally, we use the
// serialized executor as the default. This has to happen in the
// main thread so the main looper is set right.
if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
// Let the util.*Array classes maintain "undefined" for apps targeting Pie or earlier.
UtilConfig.setThrowExceptionForUpperArrayOutOfBounds(
data.appInfo.targetSdkVersion >= Build.VERSION_CODES.Q);
Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
// Supply the targetSdkVersion to the UI rendering module, which may
// need it in cases where it does not have access to the appInfo.
android.graphics.Compatibility.setTargetSdkVersion(data.appInfo.targetSdkVersion);
/*
* Before spawning a new process, reset the time zone to be the system time zone.
* This needs to be done because the system time zone could have changed after the
* the spawning of this process. Without doing this this process would have the incorrect
* system time zone.
*/
TimeZone.setDefault(null);
/*
* Set the LocaleList. This may change once we create the App Context.
*/
LocaleList.setDefault(data.config.getLocales());
if (Typeface.ENABLE_LAZY_TYPEFACE_INITIALIZATION) {
try {
Typeface.setSystemFontMap(data.mSerializedSystemFontMap);
} catch (IOException | ErrnoException e) {
Slog.e(TAG, "Failed to parse serialized system font map");
Typeface.loadPreinstalledSystemFontMap();
}
}
synchronized (mResourcesManager) {
/*
* Update the system configuration since its preloaded and might not
* reflect configuration changes. The configuration object passed
* in AppBindData can be safely assumed to be up to date
*/
mResourcesManager.applyConfigurationToResources(data.config, data.compatInfo);
mCurDefaultDisplayDpi = data.config.densityDpi;
// This calls mResourcesManager so keep it within the synchronized block.
mConfigurationController.applyCompatConfiguration();
}
final boolean isSdkSandbox = data.sdkSandboxClientAppPackage != null;
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo, isSdkSandbox);
if (isSdkSandbox) {
data.info.setSdkSandboxStorage(data.sdkSandboxClientAppVolumeUuid,
data.sdkSandboxClientAppPackage);
}
if (agent != null) {
handleAttachAgent(agent, data.info);
}
/**
* Switch this process to density compatibility mode if needed.
*/
if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
== 0) {
mDensityCompatMode = true;
Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
}
mConfigurationController.updateDefaultDensity(data.config.densityDpi);
// mCoreSettings is only updated from the main thread, while this function is only called
// from main thread as well, so no need to lock here.
final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24);
Boolean is24Hr = null;
if (use24HourSetting != null) {
is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE;
}
// null : use locale default for 12/24 hour formatting,
// false : use 12 hour format,
// true : use 24 hour format.
DateFormat.set24HourTimePref(is24Hr);
updateDebugViewAttributeState();
StrictMode.initThreadDefaults(data.appInfo);
StrictMode.initVmDefaults(data.appInfo);
if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) {
// XXX should have option to change the port.
Debug.changeDebugPort(8100);
if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) {
Slog.w(TAG, "Application " + data.info.getPackageName()
+ " is waiting for the debugger on port 8100...");
IActivityManager mgr = ActivityManager.getService();
try {
mgr.showWaitingForDebugger(mAppThread, true);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
Debug.waitForDebugger();
try {
mgr.showWaitingForDebugger(mAppThread, false);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} else {
Slog.w(TAG, "Application " + data.info.getPackageName()
+ " can be debugged on port 8100...");
}
}
// Allow binder tracing, and application-generated systrace messages if we're profileable.
boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
boolean isAppProfileable = isAppDebuggable || data.appInfo.isProfileable();
Trace.setAppTracingAllowed(isAppProfileable);
if ((isAppProfileable || Build.IS_DEBUGGABLE) && data.enableBinderTracking) {
Binder.enableStackTracking();
}
// Initialize heap profiling.
if (isAppProfileable || Build.IS_DEBUGGABLE) {
nInitZygoteChildHeapProfiling();
}
// Allow renderer debugging features if we're debuggable.
HardwareRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE);
HardwareRenderer.setPackageName(data.appInfo.packageName);
// Pass the current context to HardwareRenderer
HardwareRenderer.setContextForInit(getSystemContext());
// Instrumentation info affects the class loader, so load it before
// setting up the app context.
final InstrumentationInfo ii;
if (data.instrumentationName != null) {
ii = prepareInstrumentation(data);
} else {
ii = null;
}
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
mConfigurationController.updateLocaleListFromAppContext(appContext);
// Initialize the default http proxy in this process.
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
try {
// In pre-boot mode (doing initial launch to collect password), not all system is up.
// This includes the connectivity service, so trying to obtain ConnectivityManager at
// that point would return null. Check whether the ConnectivityService is available, and
// avoid crashing with a NullPointerException if it is not.
final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (b != null) {
final ConnectivityManager cm =
appContext.getSystemService(ConnectivityManager.class);
Proxy.setHttpProxyConfiguration(cm.getDefaultProxy());
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
if (!Process.isIsolated()) {
final int oldMask = StrictMode.allowThreadDiskWritesMask();
try {
setupGraphicsSupport(appContext);
} finally {
StrictMode.setThreadPolicyMask(oldMask);
}
} else {
HardwareRenderer.setIsolatedProcess(true);
}
// Install the Network Security Config Provider. This must happen before the application
// code is loaded to prevent issues with instances of TLS objects being created before
// the provider is installed.
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "NetworkSecurityConfigProvider.install");
NetworkSecurityConfigProvider.install(appContext);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// For backward compatibility, TrafficStats needs static access to the application context.
// But for isolated apps which cannot access network related services, service discovery
// is restricted. Hence, calling this would result in NPE.
if (!Process.isIsolated()) {
TrafficStats.init(appContext);
}
// Continue loading instrumentation.
if (ii != null) {
initInstrumentation(ii, data, appContext);
} else {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
}
if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
} else {
// Small heap, clamp to the current growth limit and let the heap release
// pages after the growth limit to the non growth limit capacity. b/18387825
dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
}
// Allow disk access during application and provider setup. This could
// block processing ordered broadcasts, but later processing would
// probably end up doing the same disk access.
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.makeApplicationInner(data.restrictedBackupMode, null);
// Propagate autofill compat state
app.setAutofillOptions(data.autofillOptions);
// Propagate Content Capture options
app.setContentCaptureOptions(data.contentCaptureOptions);
sendMessage(H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK, data.appInfo.packageName);
mInitialApplication = app;
final boolean updateHttpProxy;
synchronized (this) {
updateHttpProxy = mUpdateHttpProxyOnBind;
// This synchronized block ensures that any subsequent call to updateHttpProxy()
// will see a non-null mInitialApplication.
}
if (updateHttpProxy) {
ActivityThread.updateHttpProxy(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);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
mInstrumentation.callApplicationOnCreate(app);
} 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);
}
}
// Preload fonts resources
FontsContract.setApplicationContextForResources(appContext);
if (!Process.isIsolated()) {
try {
final ApplicationInfo info =
getPackageManager().getApplicationInfo(
data.appInfo.packageName,
PackageManager.GET_META_DATA /*flags*/,
UserHandle.myUserId());
if (info.metaData != null) {
final int preloadedFontsResource = info.metaData.getInt(
ApplicationInfo.METADATA_PRELOADED_FONTS, 0);
if (preloadedFontsResource != 0) {
data.info.getResources().preloadFonts(preloadedFontsResource);
}
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}
上面方法主要处理如下:
1、通过new的方式创建Instrumentation,并调用其basicInit方法。
2、调用data.info(LoadedApk)的makeApplicationInner方法,创建Application对象。
3、调用mInstrumentation(Instrumentation)的onCreate方法。
4、调用mInstrumentation(Instrumentation)的callApplicationOnCreate方法。
下面分别进行分析:
new Instrumentation
通过new的方式创建Instrumentation,Instrumentation的构造方法如下:
//frameworks/base/core/java/android/app/Instrumentation.java
public class Instrumentation {
public Instrumentation() {
}
}
调用Instrumentation的basicInit方法:
//frameworks/base/core/java/android/app/Instrumentation.java
public class Instrumentation {
final void basicInit(ActivityThread thread) {
mThread = thread;
}
}
LoadedApk makeApplicationInner
调用data.info(LoadedApk)的makeApplicationInner方法,创建Application对象:
//frameworks/base/core/java/android/app/LoadedApk.java
public final class LoadedApk {
public Application makeApplicationInner(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
return makeApplicationInner(forceDefaultAppClass, instrumentation,
/* allowDuplicateInstances= */ false);
}
}
调用makeApplicationInner方法:
//frameworks/base/core/java/android/app/LoadedApk.java
public final class LoadedApk {
private Application makeApplicationInner(boolean forceDefaultAppClass,
Instrumentation instrumentation, boolean allowDuplicateInstances) {
if (mApplication != null) {
return mApplication;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
synchronized (sApplications) {
final Application cached = sApplications.get(mPackageName);
if (cached != null) {
// Looks like this is always happening for the system server, because
// the LoadedApk created in systemMain() -> attach() isn't cached properly?
if (!"android".equals(mPackageName)) {
Slog.wtfStack(TAG, "App instance already created for package=" + mPackageName
+ " instance=" + cached);
}
if (!allowDuplicateInstances) {
mApplication = cached;
return cached;
}
// Some apps intentionally call makeApplication() to create a new Application
// instance... Sigh...
}
}
Application app = null;
final String myProcessName = Process.myProcessName();
String appClass = mApplicationInfo.getCustomApplicationClassNameForProcess(
myProcessName);
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
final java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
// Rewrite the R 'constants' for all library apks.
SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers(
false, false);
for (int i = 0, n = packageIdentifiers.size(); i < n; i++) {
final int id = packageIdentifiers.keyAt(i);
if (id == 0x01 || id == 0x7f) {
continue;
}
rewriteRValues(cl, packageIdentifiers.valueAt(i), id);
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// The network security config needs to be aware of multiple
// applications in the same process to handle discrepancies
NetworkSecurityConfigProvider.handleNewApplication(appContext);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ " package " + mPackageName + ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (!allowDuplicateInstances) {
synchronized (sApplications) {
sApplications.put(mPackageName, app);
}
}
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} 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);
}
}
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return app;
}
}
上面方法主要处理如下:
1、调用ContextImpl的createAppContext方法,创建appContext(ContextImpl)。
2、调用mActivityThread.mInstrumentation(Instrumentation)的newApplication方法,创建Application对象。
3、调用instrumentation的callApplicationOnCreate方法。
下面分别进行分析:
ContextImpl createAppContext
调用ContextImpl的createAppContext方法,创建appContext(ContextImpl):
//frameworks/base/core/java/android/app/ContextImpl.java
class ContextImpl extends Context {
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
return createAppContext(mainThread, packageInfo, null);
}
}
调用createAppContext方法:
//frameworks/base/core/java/android/app/ContextImpl.java
class ContextImpl extends Context {
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
String opPackageName) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
ContextParams.EMPTY, null, null, null, null, null, 0, null, opPackageName);
context.setResources(packageInfo.getResources());
context.mContextType = isSystemOrSystemUI(context) ? CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI
: CONTEXT_TYPE_NON_UI;
return context;
}
}
以上方法主要处理如下:
1、通过new的方式创建ContextImpl对象。
2、调用context(ContextImpl)的setResources方法,设置context对应的Resources。
下面分别进行分析:
new ContextImpl
通过new的方式创建ContextImpl对象,ContextImpl的构造方法如下:
//frameworks/base/core/java/android/app/ContextImpl.java
class ContextImpl extends Context {
private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
@NonNull LoadedApk packageInfo, @NonNull ContextParams params,
@Nullable String attributionTag, @Nullable AttributionSource nextAttributionSource,
@Nullable String splitName, @Nullable IBinder token, @Nullable UserHandle user,
int flags, @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) {
mOuterContext = this;
// If creator didn't specify which storage to use, use the default
// location for application.
if ((flags & (Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE
| Context.CONTEXT_DEVICE_PROTECTED_STORAGE)) == 0) {
final File dataDir = packageInfo.getDataDirFile();
if (Objects.equals(dataDir, packageInfo.getCredentialProtectedDataDirFile())) {
flags |= Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
} else if (Objects.equals(dataDir, packageInfo.getDeviceProtectedDataDirFile())) {
flags |= Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
}
}
mMainThread = mainThread;
mToken = token;
mFlags = flags;
if (user == null) {
user = Process.myUserHandle();
}
mUser = user;
mPackageInfo = packageInfo;
mSplitName = splitName;
mClassLoader = classLoader;
mResourcesManager = ResourcesManager.getInstance();
String opPackageName;
if (container != null) {
mBasePackageName = container.mBasePackageName;
opPackageName = container.mOpPackageName;
setResources(container.mResources);
mDisplay = container.mDisplay;
mForceDisplayOverrideInResources = container.mForceDisplayOverrideInResources;
mIsConfigurationBasedContext = container.mIsConfigurationBasedContext;
mContextType = container.mContextType;
mContentCaptureOptions = container.mContentCaptureOptions;
mAutofillOptions = container.mAutofillOptions;
} else {
mBasePackageName = packageInfo.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo();
if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
// Special case: system components allow themselves to be loaded in to other
// processes. For purposes of app ops, we must then consider the context as
// belonging to the package of this process, not the system itself, otherwise
// the package+uid verifications in app ops will fail.
opPackageName = ActivityThread.currentPackageName();
} else {
opPackageName = mBasePackageName;
}
}
mOpPackageName = overrideOpPackageName != null ? overrideOpPackageName : opPackageName;
mParams = Objects.requireNonNull(params);
mAttributionSource = createAttributionSource(attributionTag, nextAttributionSource,
params.getRenouncedPermissions());
mContentResolver = new ApplicationContentResolver(this, mainThread);
}
}
ContextImpl setResources
调用context(ContextImpl)的setResources方法,设置context对应的Resources:
frameworks/base/core/java/android/app/ContextImpl.java
class ContextImpl extends Context {
void setResources(Resources r) {
if (r instanceof CompatResources) {
((CompatResources) r).setContext(this);
}
mResources = r;
}
}
Instrumentation newApplication
调用mActivityThread.mInstrumentation(Instrumentation)的newApplication方法,创建Application对象:
//frameworks/base/core/java/android/app/Instrumentation.java
public class Instrumentation {
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance(); 创建Application对象
app.attach(context);
return app;
}
}
Application attach
创建Application对象,调用其attach方法。
Instrumentation onCreate
调用mInstrumentation(Instrumentation)的onCreate方法:
//frameworks/base/core/java/android/app/Instrumentation.java
public class Instrumentation {
public void onCreate(Bundle arguments) {
}
}
Instrumentation callApplicationOnCreate
调用mInstrumentation(Instrumentation)的callApplicationOnCreate方法:
//frameworks/base/core/java/android/app/Instrumentation.java
public class Instrumentation {
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
}
Application onCreate
调用app(Application)的onCreate方法:
void onCreate():在应用程序启动时,在创建任何活动、服务或接收方对象(不包括内容提供程序)之前调用。
在其子类(应用程序实现)的onCreate会调用super.onCreate()方法。