性能优化系列
常见android性能优化总结
文章目录
前言
本人一家之言,仅供参考
提示:以下是本篇文章正文内容,下面案例可供参考
一、启动黑白屏优化
启动方式优化
1. 冷启动
- 加载并启动APP
- 启动后立即为该APP显示一个空白启动窗口
- 创建APP进程(创建应用程序对象)
- 启动主线程,创建主Activity
- 加载布局,绘制
2. 热启动
- 热启动中,系统所有工作是将Activity带到前台
- 如果应用的所有Activity都驻留在内存中,则应用可以无须重复对象初始化,布局扩充和呈现
3. 温启动
温启动涵盖在冷启动期间发生的操作的一些子集,同时它的开销比热启动多
获取启动时间方式
1. log工具
ActivityTaskManager: Displayed com.example.testdemo/.MainActivity: +3s341ms
2. 命令
adb shell am start -W com.example.testdemo/.SplashActivity
D:\code\android studio code\testdemo>adb shell am start -W com.example.testdemo/.SplashActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.testdemo/.SplashActivity }
Status: ok
LaunchState: COLD
Activity: com.example.testdemo/.SplashActivity
TotalTime: 384
WaitTime: 394
Complete
D:\code\android studio code\testdemo>adb shell am start -W com.example.testdemo/.SplashActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.testdemo/.SplashActivity }
Warning: Activity not started, its current task has been brought to the front
Status: ok
LaunchState: HOT
Activity: com.example.testdemo/.SplashActivity
TotalTime: 120 所有activity的启动时间
WaitTime: 123 所有时间,ams启动activity的总时间
Complete
3. 手动获取
SplashActivity.java
//跳转到MainActivity
Intent intent = new Intent();
intent.setClass(this, MainActivity.class);
startActivity(intent);
LauncherTime.java
package com.example.testdemo;
import android.util.Log;
public class LauncherTime {
public static long startTime;
public static void logStart() {
startTime = System.currentTimeMillis();
}
public static void logEnd() {
Log.d("time", "launcher time: " + (System.currentTimeMillis() - startTime));
}
}
MainActivity.java
package com.example.testdemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Theme_AppCompat);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViews();
}
private void findViews() {
//调用跟布局开始绘制的时间
final View view = findViewById(R.id.root);
view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
LauncherTime.logEnd("Tag3");
view.getViewTreeObserver().removeOnPreDrawListener(this);
return false;
}
});
}
@Override
protected void onResume() {
super.onResume();
//调用onResume之后ui才会显示在手机上
LauncherTime.logEnd("Tag1");
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//首帧开始绘制的时候回调
LauncherTime.logEnd("Tag2");
}
}
MyApplication.java
package com.example.testdemo;
import android.app.Application;
import android.content.Context;
import java.util.concurrent.ExecutorService;
public class MyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
LauncherTime.logStart();//开始
super.attachBaseContext(base);
}
protected Context context;
public static Application application;
ExecutorService executorService;
@Override
public void onCreate() {
super.onCreate();
}
}
结果:
2021-04-03 16:13:32.085 15692-15692/com.example.testdemo D/Tag1: launcher time: 414
2021-04-03 16:13:32.114 15692-15692/com.example.testdemo D/Tag3: launcher time: 443
2021-04-03 16:13:32.300 15692-15692/com.example.testdemo D/Tag2: launcher time: 629
4. TraceView工具
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
//方法耗时统计
Debug.startMethodTracing("Launcher");
coreSize = Runtime.getRuntime().availableProcessors();//cpu 核数
executorService = Executors.newFixedThreadPool(Math.max(2, Math.min(coreSize - 1, 4)));
a();
application = this;
context = this.getApplicationContext();
Debug.stopMethodTracing();
}
traceview 文件截图(待补充)
Total(us) % Self(us) % Children(us) %
总共耗时 自身耗时main方法 孩子耗时
a 98%
启动优化 减少时间
- 有些资源懒加载,异步加载
- 初始化的资源和UI线程有关,不能放到子线程中
如果应用必须要在主线程3s
- 资源拆分 (时间、空间)
启动白屏优化
代码如下(示例):
<!--plan1: 直接取消预览窗体或设置为透明,缺点:同样让用户感觉卡顿-->
<!--<item name="android:windowDisablePreview">true</item>
<item name="android:windowIsTranslucent">true</item>-->
<!--plan2: 直接设置主题背景-->
<!--<item name="android:windowBackground">@mipmap/ic_launcher</item>-->
<!--plan2: 设置单个启动页主题背景-->
<style name="Theme.AppCompat.Launcher1">
<item name="android:windowBackground">@mipmap/ic_launcher</item>
</style>
<activity
android:name=".MainActivity"
android:theme="@style/Theme.AppCompat.Launcher1">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--plan2: 设置单个启动页主题背景-->
<style name="Theme.AppCompat.Launcher1">
<item name="android:windowBackground">@mipmap/ic_launcher</item>
</style>
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Theme_AppCompat);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
网易云音乐闪屏页
代码如下(示例):
SplashActivity.java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
}
activity.splash.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="30dp"
android:background="@mipmap/ic_launcher">
</ImageView>
</RelativeLayout>
theme.xml
<!--plan3: 终极版本-->
<style name="Theme.AppCompat.Launcher2">
<item name="windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowBackground">@drawable/splash_preview</item>
</style>
splash_preview.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--启动页红色背景-->
<item android:drawable="@color/red_bg"></item>
<item android:top="30dp">
<bitmap
android:gravity="top"
android:src="@drawable/ic_launcher_round"></bitmap>
</item>
</layer-list>
AndroidManifest.xml
<activity
android:name=".SplashActivity"
android:theme="@style/Theme.AppCompat.Launcher2