当前位置:网站首页>Startup process analysis of APP performance optimization
Startup process analysis of APP performance optimization
2022-06-23 23:52:00 【Yanwenjing】
1.Android Analysis of system startup process
- BootLoader Start the kernel and init process ;
- init The process split out of a daemon , Such as Android Debug Damon,USB Damon, These daemons handle some hardware related interfaces ;
- init The process starts a Zygote process Zygote The process initialized the first VM, And preloaded Framework And some common resources .
zygote The process will open a Socket Interface , To listen for requests . Once the request is received ,Zygote Will be preloaded based on its own VM To hatch a new VM, And create a new process . - start-up Zygote after ,init The process will start Runtime process .Zygote Will hatch a super management process -System Server.System Server Will start all the core services of the system , Such as Activity Manager Service And hardware related Service.
- This is the first time to start it App process -Home Process .
Android The system has been started , Some core services have also been started , Then start Launcher application .
2.App Analysis of the start-up process of virtual reality
App When the process is created ?
When an application calls a page in another application , If the target process does not exist , A new process is created and started .
Application Start process
Look at the flow chart first

- Click on the desktop Icon Or click in the foreground application to jump to another application
- And then call StartActivity(Intent intent) Method ;
This method will eventually pass Binder IPC Method call ActivityManagerService, Abbreviated here AMS. - AMS The following is done :
- It will eventually pass PackageManager Of resolveIntent() Method to collect this Intent Object pointing information ( There will be many kinds of , Method call ).
- adopt grantUriPermissionLocked() Method to verify whether the user has sufficient permissions to call the target Activity;
- Inquire about ProcessRecord Whether there is
If it doesn't exist ,AMS A new process will be created to instantiate the target Activity.
Next, let's say App Process creation process .
App Process creation
- call startProcessLocked() Method to create a new process through the above Socket The channel passes parameters to Zygote process ,Zygote The process incubates itself , And call ZygoteInit.main() Method to instantiate ActivityThread object , And finally return to the new process pid.
- ActivityThread In turn, calls Looper.prepare() and Looper.loop() Method to start the message loop .
At this time, the process has been created , But how to communicate with the application itself Application To connect ?
Application The binding of
- call ActivityThread Medium bindApplication() Method to send a BIND_APPLICATION To the message queue .
- adopt handleBindApplication() Method to process the previous binding message ;
- call makeApplication() Method to load Application Of class Into memory .
Here are some source code fragments
ActivityThread.java
sendMessage(H.BIND_APPLICATION, data);
@Override
public final void bindApplication(String processName, ApplicationInfo appInfo,
ProviderInfoList providerList, 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, long[] disabledCompatChanges,
SharedMemory serializedSystemFontMap) {
if (services != null) {
if (false) {
// Test code to make sure the app could see the passed-in services.
for (Object oname : services.keySet()) {
if (services.get(oname) == null) {
continue; // AM just passed in a null service.
}
String name = (String) oname;
// See b/79378449 about the following exemption.
switch (name) {
case "package":
case Context.WINDOW_SERVICE:
continue;
}
if (ServiceManager.getService(name) == null) {
Log.wtf(TAG, "Service " + name + " should be accessible by this app");
}
}
}
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}
setCoreSettings(coreSettings);
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providerList.getList();
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;
data.disabledCompatChanges = disabledCompatChanges;
data.mSerializedSystemFontMap = serializedSystemFontMap;
sendMessage(H.BIND_APPLICATION, data);
}handleMessage(msg)
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);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
...
}handleBindApplication(data)
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
...
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);
// 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);
}
}
...
}
...
}Pay attention to the data.info.makeApplication(data.restrictedBackupMode, null) and installContentProviders(app, data.providers)
data.info The type is LoadedApk
LoadedApk.java
@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 {
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 (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;
}among mApplicationInfo.className by App Self defined Application, If it is empty , It will use the default appClass = "android.app.Application",initializeJavaContextClassLoader() Is the logical call to initialize the class loader , You can also continue to track its logic , You can find sharedUserId After setting to the same , Can share the logic of a virtual machine
app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext) This is the time , You can see it's in Instrumentation Chinese vs Application Instantiation
Look at some excerpts of the code
ActivityThread.java
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
...
// Restore instance state
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, r.persistentState);
...
// Call postOnCreate()
mInstrumentation.callActivityOnPostCreate(activity, r.state, r.persistentState);
...
mInstrumentation.callActivityOnNewIntent(r.activity, intent);
...
mInstrumentation.callActivityOnPause(r.activity);
...
mInstrumentation.callActivityOnDestroy(r.activity);
...
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
...
mInstrumentation.callApplicationOnCreate(app);
among :callActivityOnCreate,callApplicationOnCreate,newActivity,callActivityOnNewIntent Wait in ActivityThread Pass in class Instrumentation Yes application and activity In all life cycle calls , Will call first Instrumentation The corresponding method of , To realize the corresponding functions ,Instrumentation There are more relevant methods in the class .
Continue to enter Instrumentation.java
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}Here is the Application Class creation timing
Application.java
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
} Finally found the one we are most familiar with attachBaseContext Method .
Let's look again ContentProvider Of onCreate opportunity , Let's go back to the above ActivityThread.java Of publishContentProviders Method , You can see that there is a
installContentProviders Method is executed before , Check out the method
ActivityThread.java
@UnsupportedAppUsage
private void installContentProviders(
Context context, List<ProviderInfo> providers) {
final ArrayList<ContentProviderHolder> results = new ArrayList<>();
for (ProviderInfo cpi : providers) {
if (DEBUG_PROVIDER) {
StringBuilder buf = new StringBuilder(128);
buf.append("Pub ");
buf.append(cpi.authority);
buf.append(": ");
buf.append(cpi.name);
Log.i(TAG, buf.toString());
}
ContentProviderHolder cph = installProvider(context, null, cpi,
false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
if (cph != null) {
cph.noReleaseNeeded = true;
results.add(cph);
}
}
try {
ActivityManager.getService().publishContentProviders(
getApplicationThread(), results);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
private IActivityManager.ContentProviderHolder installProvider(Context context,IActivityManager.ContentProviderHolder holder, ProviderInfo info,boolean noisy, boolean noReleaseNeeded, boolean stable) {
...
final java.lang.ClassLoader cl = c.getClassLoader();
localProvider = (ContentProvider)cl.
loadClass(info.name).newInstance();
provider = localProvider.getIContentProvider();
if (provider == null) {
Slog.e(TAG, "Failed to instantiate class " +
info.name + " from sourceDir " +
info.applicationInfo.sourceDir);
return null;
}
if (DEBUG_PROVIDER) Slog.v(
TAG, "Instantiating local provider " + info.name);
// XXX Need to create the correct context for this provider.
localProvider.attachInfo(c, info);
...
}From here ClassLoader Load in ContentProvider Class instance , And call attachInfo Method
Let's see ContentProvider.java
private void attachInfo(Context context, ProviderInfo info, boolean testing) {
...
ContentProvider.this.onCreate();
...
}Briefly summarize the above startup process :
- ActivityThread.attath()
- AMS.attachApplication()
- ActivityThread.handleBindApplication()
- Application.attachBaseContext()
- ActivityThread.installContentProviders
- ContentProvider.onCreate()
- AMS.publishContentProviders()
- Application.onCreate()
So for App Start optimization , What we can intervene is from Application.attachBaseContext()、ContentProvider.onCreate()、Application.onCreate() Start with three aspects .
边栏推荐
- Graph theory (nearest common ancestor LCA)
- 网站ssl证书
- 依赖倒置原则
- Thinking (86): master-slave realization idea
- Detailed explanation of index invalidation caused by MySQL
- Application of acrel-3000web power management system in Duba Expressway
- 一个人竟然撸了一个网易云音乐云村
- Image segmentation - data annotation
- Docker Deployment redis
- How to achieve energy-saving and reasonable lighting control in order to achieve the "double carbon" goal
猜你喜欢

Digital property management has become a trend. How can traditional property companies achieve digital butterfly change through transformation?

ORB_ Slam3 environment setup and demo demonstration

B2B transaction management system of electronic components industry: improve the data-based driving ability and promote the growth of enterprise sales performance

Acrel-3000WEB电能管理系统在都巴高速的应用

高仿書旗小說 Flutter 版,學起來

IDEA 自动生成单元测试,效率倍增!

EF Core中的三类事务(SaveChanges、DbContextTransaction、TransactionScope)
![The input parameter is object, but it was passed as [object object] because it needs to be converted to JSON format](/img/8c/b1535e03900d71b075f73f80030064.png)
The input parameter is object, but it was passed as [object object] because it needs to be converted to JSON format

How to ensure reliable power supply of Expressway

数据库中索引原理及填充因子
随机推荐
为实现“双碳”目标,应如何实现节能、合理的照明管控
高仿斗鱼 APP
不同物体使用同一材质,有不同的表现
Stm32-------adc (voltage detection)
Generative countermeasure networks (Gans) and variants
Notepad++实用功能分享(正则行尾行首替换常用方法、文本比对功能等)
Inftnews | where should the future of the creator economy go in the Web3 world?
The group procurement management system of daily chemical supplies industry changes the traditional procurement mode and reduces the procurement cost
【 GBASE的那些事儿】系列直播活动第02期《GBase 8s高可用技术及案例分析法》
2018/GAN:Self-Attention Generative Adversarial Networks自我注意生成对抗网络
6. STM32 - serial port data transceiver Foundation
Chrome plug-in features and case analysis of actual combat scenarios
不容错过 | 华为内部资料--成功的项目管理PPT(123页)
Why can't the netherworld fortress machine be remotely connected to the server? What are the ways to solve such problems?
IDEA 自动生成单元测试,效率倍增!
思考(八十七):协议加密与压缩
Server2022 activation
One person even broke up a Netease cloud music Cloud Village
ACM. Hj89 24 point operation ●●●
7、STM32——LCD