Android Studio直接运行影响启动性能

Android Studio直接运行影响启动性能

之前eclipse时代,测试空应用启动性能时,都是直接在IDE中启动,这样修改起来方便。
到了Android Studio时代,这个习惯被我保持下来了。
结果就被Instant Run功能给小小坑了一下。

从性能日志上看,发现空应用在handleBindApplication的时候,在MTK6753芯片上费时60多毫秒,展讯9832芯片上超过100毫秒。
而空应用,既没有Application的onCreate,又没有installProvider之类的,要花这么长时间很奇怪。

后来打印了一下backtrace,原来是这样的:

01-01 01:25:42.280 W/ContextWrapper(12427):     at android.content.ContextWrapper.attachBaseContext(ContextWrapper.java:67)
01-01 01:25:42.280 W/ContextWrapper(12427):     at com.android.tools.fd.runtime.BootstrapApplication.attachBaseContext(BootstrapApplication.java:244)
01-01 01:25:42.280 W/ContextWrapper(12427):     at android.app.Application.attach(Application.java:188)
01-01 01:25:42.280 W/ContextWrapper(12427):     at android.app.Instrumentation.newApplication(Instrumentation.java:1021)
01-01 01:25:42.280 W/ContextWrapper(12427):     at android.app.Instrumentation.newApplication(Instrumentation.java:1003)
01-01 01:25:42.280 W/ContextWrapper(12427):     at android.app.LoadedApk.makeApplication(LoadedApk.java:586)
01-01 01:25:42.280 W/ContextWrapper(12427):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5054)
01-01 01:25:42.280 W/ContextWrapper(12427):     at android.app.ActivityThread.-wrap1(ActivityThread.java)
01-01 01:25:42.280 W/ContextWrapper(12427):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1564)
01-01 01:25:42.280 W/ContextWrapper(12427):     at android.os.Handler.dispatchMessage(Handler.java:111)
01-01 01:25:42.280 W/ContextWrapper(12427):     at android.os.Looper.loop(Looper.java:205)
01-01 01:25:42.280 W/ContextWrapper(12427):     at android.app.ActivityThread.main(ActivityThread.java:5865)
01-01 01:25:42.280 W/ContextWrapper(12427):     at java.lang.reflect.Method.invoke(Native Method)
01-01 01:25:42.280 W/ContextWrapper(12427):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
01-01 01:25:42.280 W/ContextWrapper(12427):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:734)

原来InstantRun的时候,安装的应用的Application是com.android.tools.fd.runtime.BootstrapApplication,这个Application重载了attachBaseContext,正是这个重载的方法耗费了这么长的时间。
Application的attach方法是个hide的方法:

183    /**
184     * @hide
185     */
186    /* package */ final void attach(Context context) {
187        attachBaseContext(context);
188        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
189    }
```

attach会调用到当前Application的attachBaseContext,正常的attachBaseContext方法是这样的:
比如ContextThemeWrapper的attachBaseContext,就是对基类的调用:

50 @Override
51 protected void attachBaseContext(Context newBase) {
52 super.attachBaseContext(newBase);
53 }

而ContextWrapper的attachBaseContext是这样的:

65 protected void attachBaseContext(Context base) {
66 if (mBase != null) {
67 throw new IllegalStateException("Base context already set");
68 }
69 mBase = base;
70 }

所以,没有重载的普通类,在attachBaseContext这一步几乎不花时间。

## 解决方案
上一篇:Unity报错:Read only asset Packages/com.xxxxx.xxx.xxxx/Editor/VSCodeDiscovery.cs.IPGSD has no meta


下一篇:android 退出程序 结束线程