1, Code Analysis
Take the GitHub app that was written earlier as an example.
Because this app integrates services such as bugly, Push, feedback and so on, application's oncreate has many third-party platform initialization work ...
Public class githubapplication extends multidexapplication { @Override Public void onCreate() {Super. OnCreate ();//init logger.Applog.init ();//Init crash helperCrashhelper.init ( This);//init PushPushplatform.init ( This);//init FeedbackFeedbackplatform.init ( This);//init ShareShareplatform.init ( This);//init Drawer image LoaderDrawerimageloader.init (NewAbstractdrawerimageloader () {@Override Public void Set(ImageView ImageView, Uri Uri, drawable placeholder) {imageloader.loadwithcircle (githubapplication). This, Uri, ImageView); } }); }}
Current cold start effect:
You can see the white screen for a long time at startup.
2, TraceView.
Next we combine our theoretical knowledge, and the introduction of the TraceView tool, to analyze the application OnCreate time-consuming.
At the beginning and end of the OnCreate, I hit trace.
Debug.startMethodTracing("GithubApp");...Debug.stopMethodTracing();
Running the program will generate a "githubapp.trace" file on the SDcard.
Note: You need to add write storage permissions to the program:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Export it to local via ADB pull
adb pull /sdcard/GithubApp.trace ~/temp
Advertising: The many uses of the ADB can refer to my other article
Open DDMS Profiling trace file
Analyzing Trace files
- Click on "Real Time/call" in the method area below, and follow the method of each call time-consuming descending row.
- Time-consuming over 500ms is noteworthy.
- Look at the method name on the left, you can see the time-consuming large is the number of platforms we use the initialization method, especially bugly, also loaded native Lib, with ZipFile operation.
- By clicking on each method, you can see its parent method (called it) and all its child methods (which it calls).
- When the method is clicked, the execution timeline of the above method flashes, and the execution thread and relative duration of the method can be seen.
3, adjust application oncreate and try again
Now that we know what's going to take a long time, we may as well adjust the oncreate implementation of the application, in general we can put these initializations in a separate thread to handle, in order to facilitate future management, Here I use a initializeservice intentservice to do the initialization work.
Clearly, Intentservice is different from service, it is working in a background thread.
The Initializeservice.java code is as follows:
Packagecom. Anly. Githubapp. Compz. Service;Import Android. App. Intentservice;Import Android. Content. Context;Import Android. Content. Intent;Import Android. Graphics. drawable. Drawable;Import Android. NET. Uri;Import Android. Widgets. ImageView;Importcom. Anly. Githubapp. Common. Wrapper. Applog;Importcom. Anly. Githubapp. Common. Wrapper. Crashhelper;Importcom. Anly. Githubapp. Common. Wrapper. Feedbackplatform;Importcom. Anly. Githubapp. Common. Wrapper. Imageloader;Importcom. Anly. Githubapp. Common. Wrapper. Pushplatform;Importcom. Anly. Githubapp. Common. Wrapper. Shareplatform;Importcom. Mikepenz. Materialdrawer. Util. Abstractdrawerimageloader;Importcom. Mikepenz. Materialdrawer. Util. Drawerimageloader;/** * Created by Mingjun on 16/8/25. * *public class InitializeService extends Intentservice {private static final String action_init_when_app_create ="Com.anly.githubapp.service.action.INIT";Public InitializeService () {Super ("InitializeService");public static void Start (context context) {Intent Intent = new Intent (context, InitializeService. Class);Intent. Setaction(action_init_when_app_create);Context. StartService(Intent);} @Override protected void Onhandleintent (Intent Intent) {if (Intent! = null) {final String acti On = Intent. Getaction();if (action_init_when_app_create. Equals(action)) {Performinit ();}}} private void Performinit () {Applog. D("Performinit begin:"+ System. Currenttimemillis());init Drawer Image Loader Drawerimageloader. Init(New Abstractdrawerimageloader () {@Override public voidSet(ImageView ImageView, Uri Uri, drawable placeholder) {Imageloader. Loadwithcircle(Getapplicationcontext (), Uri, ImageView);} });Init Crash Helper Crashhelper. Init(This. Getapplicationcontext());InitPushPushplatform. Init(This. Getapplicationcontext());Init Feedback Feedbackplatform. Init(This. Getapplication());Init Share Shareplatform. Init(This. Getapplicationcontext());Applog. D("Performinit End:"+ System. Currenttimemillis());}}
Githubapplication's oncreate changed to:
publicclass GithubApplication extends MultiDexApplication { @Override publicvoidonCreate() { super.onCreate(); // init logger. AppLog.init(); InitializeService.start(this); }}
Look at the effect now:
Can see a lot of promotion, and then there is a little flaw, that is, when you get up there will be a white screen, if the phone is slow, the white screen will last for a period of time, not too friendly.
So is there any way to optimize it?
4. Get a placeholder for our application window.
The latest Android material design has this advice. We recommend that we use a placeholder UI to display to the user until the app has finished loading.
How do you do it?
Add Background to Window
As in section 3rd, when the app is not fully up, the screen will always display a blank window (typically a black screen or a white screen, depending on the app theme).
The theoretical basis of the previous article, said that the blank window is related to the theme, then we can start with the theme of the first screen? Just have a windowbackground theme attribute, let's add a theme to the splash interface, with the background we want to show.
To do a logo_splash background:
<?xml version= "1.0" encoding= "Utf-8"?><layer-list xmlns:android="Http://schemas.android.com/apk/res/android"> <!--bottom white --- <item android:drawable="@color/white" /> <!--top-level Logo center -- <item> <bitmapandroid:gravity="center"android:src="@drawable/ic_github " /> </Item></layer-list>
Get a theme:
<style name="SplashTheme" parent="AppTheme"> <item name="android:windowBackground">@drawable/logo_splash</item></style>
Use an activity that does not render the layout as a splash screen
Write a logosplashactivity that doesn't do anything.
Public class logosplashactivity extends baseactivity { @Override protected void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);//Note that there is no setcontentview, simply to jump to the corresponding activity. //To reduce the first screen rendering if(Apppref.isfirstrunning ( This) {Introduceactivity.launch ( This); }Else{Mainactivity.launch ( This); } finish (); }}
Set it as the splash screen in Androidmanifest.xml and add the theme:
<activityandroid:name=". Ui.module.main.LogoSplashActivity"android: Screenorientation="Portrait"android:theme="@style/splashtheme"> <intent-filter> <action android:name="Android.intent.action.MAIN"/> <category android:name="Android.intent.category.LAUNCHER"/> </intent-filter></activity>
5, the final effect
Let's take a look at the final effect:
Compared to before, presented to the user is no longer a white screen, with the logo, of course, this background to show what, we can customize according to the actual situation.
This optimization is very friendly for some application where initialization work cannot be moved to sub-threading. Can avoid the long time our app renders to the User a blank window.
6, conclusion
As usual, summarize.
This time on the app launch optimization, wrote two articles. Write so much, or want to convey the next person to do the idea of technology, but also a personal experience review, a catalyst.
The actual scenario may be far more complex than this, providing a more analytical idea in this way ~ Welcome to expand
Sentimental, or summed up the article related to it:
- Don't do too many things in application's oncreate.
- The first screen activity is as simple as possible.
- Use tool analysis.
- Read more official documents, many of which seem irrelevant, and are actually related, such as using the solution in the material design document this time.
The full source of this article, please visit GitHub
App optimization to increase your app startup Speed Instance Challenge