App 启动速度优化系列:如何用一个placeholderUI来做初始化工作

1 , 代码分析因为App集成了Bugly, Push, Feedback等服务, 所以Application的onCreate有很多第三方平台的初始化工作
public class GithubApplication extends MultiDexApplication {@Overridepublic 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(new AbstractDrawerImageLoader() {@Overridepublic void set(ImageView imageView, Uri uri, Drawable placeholder) {ImageLoader.loadWithCircle(GithubApplication.this, uri, imageView);}});}}2 , 调整Application onCreate再试知道了哪些地方耗时长, 我们不妨调整下Application的onCreate实现, 一般来说我们可以将这些初始化放在一个单独的线程中处理, 为了方便今后管理, 这里我用了一个InitializeService的IntentService来做初始化工作
明确一点, IntentService不同于Service, 它是工作在后台线程的
InitializeService.JAVA代码如下:
package com.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.widget.ImageView;import com.anly.githubapp.common.wrapper.AppLog;import com.anly.githubapp.common.wrapper.CrashHelper;import com.anly.githubapp.common.wrapper.FeedbackPlatform;import com.anly.githubapp.common.wrapper.ImageLoader;import com.anly.githubapp.common.wrapper.PushPlatform;import com.anly.githubapp.common.wrapper.SharePlatform;import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader;import com.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);}@Overrideprotected void onHandleIntent(Intent intent) {if (intent != null) {final String action = intent.getAction();if (ACTION_INIT_WHEN_APP_CREATE.equals(action)) {performInit();}}}private void performInit() {AppLog.d("performInit begin:" + System.currentTimeMillis());// init Drawer image loaderDrawerImageLoader.init(new AbstractDrawerImageLoader() {@Overridepublic void set(ImageView imageView, Uri uri, Drawable placeholder) {ImageLoader.loadWithCircle(getApplicationContext(), uri, imageView);}});// init crash helperCrashHelper.init(this.getApplicationContext());// init PushPushPlatform.init(this.getApplicationContext());// init FeedbackFeedbackPlatform.init(this.getApplication());// init ShareSharePlatform.init(this.getApplicationContext());AppLog.d("performInit end:" + System.currentTimeMillis());}}GithubApplication的onCreate改成:
public class GithubApplication extends MultiDexApplication {@Overridepublic void onCreate() {super.onCreate();// init logger.AppLog.init();InitializeService.start(this);}}3 , 给我们的应用窗口弄一个PlaceHolderAndroid最新的Material Design 建议我们使用一个placeholder UI来展示给用户直至App加载完毕
怎么做呢?
1>:给Window加上背景当App没有完全起来时, 屏幕会一直显示一块空白的窗口(一般来说是黑屏或者白屏, 根据App主题)
这个空白的窗口展示跟主题相关, 那么我们是不是可以从首屏的主题入手呢? 恰好有一个windowBackground的主题属性, 我们来给Splash界面加上一个主题, 带上我们想要展示的背景 。
做一个logo_splash的背景:
<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android"><!-- 底层白色 --><item android:drawable="@color/white" /><!-- 顶层Logo居中 --><item><bitmapandroid:gravity="center"android:src=https://www.isolves.com/it/cxkf/ydd/APP/2022-07-13/"@drawable/ic_github" />做一个主题:
<style name="SplashTheme" parent="AppTheme"><item name="android:windowBackground">@drawable/logo_splash</item></style>2>:将一个什么也不渲染布局的Activity作为启动屏写一个什么都不做的LogoSplashActivity
public class LogoSplashActivity extends BaseActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 注意, 这里并没有setContentView, 单纯只是用来跳转到相应的Activity.// 目的是减少首屏渲染if (AppPref.isFirstRunning(this)) {IntroduceActivity.launch(this);}else {MainActivity.launch(this);}finish();}}


推荐阅读