赞
踩
冷启动是应用程序启动的默认方式。当用户首次启动应用程序时,或者系统彻底杀死了应用程序进程后再次启动应用程序时,会经历冷启动。在冷启动过程中,系统需要创建一个新的进程,并初始化所有必要的资源。这包括加载应用程序的代码、数据,以及初始化应用程序的环境。冷启动的时间相对较长,因为系统需要执行一系列初始化操作。用户能感受到明显的等待时间,这段时间从点击应用图标到看到应用程序主界面出现。
在冷启动开始时,系统有以下三项任务:
系统一创建应用进程,应用进程就负责后续阶段:
温启动是指应用程序已经在后台运行,但由于系统资源紧张等原因被系统终止。当用户再次启动应用程序时,系统会重新加载应用程序。与冷启动相比,温启动不需要重新创建进程,因此启动时间较短。
热启动是指应用程序处于前台运行状态,用户通过返回键或应用程序内部的逻辑退到后台,然后又重新显示到前台。在这种情况下,应用程序的进程仍然在运行,所以不需要进行任何初始化操作。热启动是最快的启动方式,因为系统只需要恢复应用程序的前台状态。
TraceView 是 Android SDK 中提供的性能分析工具,它可以帮助开发者分析应用程序的方法调用和线程活动。TraceView 专注于应用程序的内部行为,提供了方法执行时间、调用次数、CPU 使用率等详细信息。它通常用于分析应用程序的特定部分或特定场景。
public class BaseApp extends Application {
@Override
public void onCreate() {
super.onCreate();
// TraceView开始
Debug.startMethodTracing("myTrace001");
initRefresh();
initTitleBar();
initToast();
initActivites();
// TraceView结束
Debug.stopMethodTracing();
}
}
运行程序后生成文件:/sdcard/Android/data/com.example.android_performance_optimization/files/myTrace001.trace
将 trace 文件到处,用 AndroidStudio的 Profiler 工具打开,可以清楚看到各个方法的执行时间:
Systrace 是 Android SDK 中提供的另一个性能分析工具,它提供了系统级别的跟踪信息,包括内核调度、硬件I/O、进程/线程调度等。Systrace 专注于整个 Android 系统的行为,帮助开发者了解系统资源的使用情况和潜在的瓶颈。
https://blog.csdn.net/Donald_Zhuang/article/details/118771191
https://blog.csdn.net/jdsjlzx/article/details/134179374
public class BaseApp extends Application {
@Override
public void onCreate() {
super.onCreate();
// Systrace开始
Trace.beginSection("myTrace002");
initRefresh();
initTitleBar();
initToast();
initActivites();
// Systrace结束
Trace.endSection();
}
}
先执行命令:python D:\dev\AndroidSDK\platform-tools\systrace\systrace.py -t 10 -o mytrace.html -a com.example.android_performance_optimization sched freq idle am wm gfx view binder_driver hal dalvik camera input res
然后运行程序,大概10秒后会生成 mytrace.html
文件。
打开 html 文件过滤相关信息后可以看到 Wall Duration 耗时:
性能消耗:
适用范围:
这里使用第三方框架:https://github.com/FlyJingFish/AndroidAOP
添加依赖库:
implementation 'io.github.FlyJingFish.AndroidAop:android-aop-core:1.8.8'
implementation 'io.github.FlyJingFish.AndroidAop:android-aop-annotation:1.8.8'
annotationProcessor 'io.github.FlyJingFish.AndroidAop:android-aop-processor:1.8.8'
定义注解:
@AndroidAopPointCut(CostTimePointcut.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CostTime {
}
定义切面类:
public class CostTimePointcut implements BasePointCut<CostTime> { @Nullable @Override public Object invoke(@NonNull ProceedJoinPoint proceedJoinPoint, @NonNull CostTime costTime) { long startTime = System.currentTimeMillis(); proceedJoinPoint.proceed(); // 继续执行原方法 long time = System.currentTimeMillis() - startTime; Class<?> targetClass = proceedJoinPoint.getTargetClass(); String className = targetClass.getName(); AopMethod targetMethod = proceedJoinPoint.getTargetMethod(); String methodName = targetMethod.getName(); String builder = className + "#" + methodName + " [" + time + "ms" + "] "; Log.e("CostTime", builder); return null; } }
使用AOP:
public class BaseApp extends Application { @CostTime @Override public void onCreate() { super.onCreate(); initRefresh(); initTitleBar(); initToast(); initActivites(); } @CostTime private void initActivites() { ActivityManager.getInstance().init(instance); } @CostTime private void initToast() { ToastUtils.init(instance, new ToastStyle()); ToastUtils.setDebugMode(AppConfig.isDebug()); ToastUtils.setInterceptor(new ToastLogInterceptor()); } @CostTime private void initTitleBar() { TitleBar.setDefaultStyle(new TitleBarStyle()); } @CostTime private void initRefresh() { SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() { @Override public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { layout.setPrimaryColorsId(R.color.black, android.R.color.white);//全局设置主题颜色 return new ClassicsHeader(context); } }); SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() { @Override public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) { return new ClassicsFooter(context).setDrawableSize(20); } }); } }
输出:
com.example.android_performance_optimization.BaseApp#initRefresh [1ms]
com.example.android_performance_optimization.BaseApp#initTitleBar [0ms]
com.example.android_performance_optimization.BaseApp#initToast [0ms]
com.example.android_performance_optimization.BaseApp#initActivites [1ms]
com.example.android_performance_optimization.BaseApp#onCreate [2ms]
在启动时提供一个简洁的初始界面给用户,增强用户体验。
定义主题:
<style name="SplashTheme" parent="AppTheme">
<!-- 设置背景图-->
<item name="android:windowBackground">@drawable/shape_splash</item>
<!-- 取消标题栏-->
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<!-- 设置window不透明-->
<item name="android:windowIsTranslucent">false</item>
<!-- 禁用窗口的预览动画-->
<item name="android:windowDisablePreview">true</item>
<!-- 取消遮盖-->
<item name="android:windowContentOverlay">@null</item>
<!-- 全屏-->
<item name="android:windowFullscreen">true</item>
</style>
配置AndroidManifest.xml:
<activity
android:name=".SplashActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
这里使用第三方框架:https://github.com/aiceking/AppStartFaster
添加依赖库:
implementation 'com.github.aiceking:AppStartFaster:2.2.0'
public class BaseApp extends Application { private static BaseApp instance; public static BaseApp getInstance() { return instance; } @CostTime @Override public void onCreate() { super.onCreate(); instance = this; AppStartTaskDispatcher.create() .setShowLog(true) .addAppStartTask(new ActivityTask(instance)) .addAppStartTask(new ToastTask(instance)) .addAppStartTask(new TitleBarTask()) .addAppStartTask(new RefreshTask()) .start() .await(); } }
IdleHandler 是一个用于在主线程(UI 线程)空闲时执行任务的接口。
使用场景:
使用:
首先,你需要创建一个实现了IdleHandler
接口的类或使用匿名内部类。在queueIdle()
方法中定义你希望在空闲时执行的代码逻辑。该方法的返回值决定了IdleHandler的生命周期:
true
表示IdleHandler将继续保留在集合中,下次消息队列空闲时还会再次调用queueIdle()
。false
表示执行完毕后将从集合中移除,不再重复调用。定义延迟加载启动器:
public class DelayInitDispatcher { private DelayInitDispatcher() { } public static DelayInitDispatcher newInstance() { return new DelayInitDispatcher(); } private LinkedList<Task> mDelayTasks = new LinkedList<>(); private MessageQueue.IdleHandler mIdleHandler = new MessageQueue.IdleHandler() { @Override public boolean queueIdle() { if (mDelayTasks.size() > 0) { Task task = mDelayTasks.poll(); task.run(); } return !mDelayTasks.isEmpty(); } }; public DelayInitDispatcher addTask(Task task) { mDelayTasks.add(task); return this; } public void start() { Looper.myQueue().addIdleHandler(mIdleHandler); } }
定义Task接口:
public interface Task extends Runnable{
}
定义2个任务:
public class PreloadTask implements Task {
@Override
public void run() {
try {
Thread.sleep(1000L);
Log.e("TAG", "预加载数据");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public class ClearTask implements Task {
@Override
public void run() {
try {
Thread.sleep(2000L);
Log.e("TAG", "清理资源");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
使用:
DelayInitDispatcher.newInstance()
.addTask(new PreloadTask())
.addTask(new ClearTask())
.start();
https://blog.csdn.net/qq_14876133/article/details/119247723
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。