因为App集成了Bugly, Push, Feedback等服务, 所以Application的onCreate有很多第三方平台的初始化工作
public class GithubApplication extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
// init logger.
AppLog.init();
// init crash helper
CrashHelper.init(this);
// init Push
PushPlatform.init(this);
// init Feedback
FeedbackPlatform.init(this);
// init Share
SharePlatform.init(this);
// init Drawer image loader
DrawerImageLoader.init(new AbstractDrawerImageLoader() {
@Override
public void set(ImageView imageView, Uri uri, Drawable placeholder) {
ImageLoader.loadWithCircle(GithubApplication.this, uri, imageView);
}
});
}
}
知道了哪些地方耗时长, 我们不妨调整下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);
}
@Override
protected 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 loader
DrawerImageLoader.init(new AbstractDrawerImageLoader() {
@Override
public void set(ImageView imageView, Uri uri, Drawable placeholder) {
ImageLoader.loadWithCircle(getApplicationContext(), uri, imageView);
}
});
// init crash helper
CrashHelper.init(this.getApplicationContext());
// init Push
PushPlatform.init(this.getApplicationContext());
// init Feedback
FeedbackPlatform.init(this.getApplication());
// init Share
SharePlatform.init(this.getApplicationContext());
AppLog.d("performInit end:" + System.currentTimeMillis());
}
}
GithubApplication的onCreate改成:
public class GithubApplication extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
// init logger.
AppLog.init();
InitializeService.start(this);
}
}
Android最新的Material Design 建议我们使用一个placeholder UI来展示给用户直至App加载完毕
怎么做呢?
当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>
<bitmap
android:gravity="center"
android:src="@drawable/ic_github" />
</item>
</layer-list>
做一个主题:
<style name="SplashTheme" parent="AppTheme">
<item name="android:windowBackground">@drawable/logo_splash</item>
</style>
写一个什么都不做的LogoSplashActivity
public class LogoSplashActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 注意, 这里并没有setContentView, 单纯只是用来跳转到相应的Activity.
// 目的是减少首屏渲染
if (AppPref.isFirstRunning(this)) {
IntroduceActivity.launch(this);
}
else {
MainActivity.launch(this);
}
finish();
}
}
在AndroidManifest.xml中设置其为启动屏, 并加上主题:
<activity
android: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>
这种优化,对于有些Application内的初始化工作不能移到子线程做的情况, 是非常友好的;可以避免我们的App长时间的呈现给用户一个空白的窗口
有需要文中完整代码的同学 可以 私信发送 “底层源码” 即可 免费获取
现在私信还可以获得 更多《Android 学习笔记+源码解析+面试视频》
最后我想说:
对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们
技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面
Android 架构师之路还很漫长,与君共勉