目录
[二、内存泄漏(Memory Leak)](#二、内存泄漏(Memory Leak))
[三、ANR(Application Not Responding)](#三、ANR(Application Not Responding))
四、列表滑动卡顿(RecyclerView/ListView)
[六、内存抖动(Memory Churn)](#六、内存抖动(Memory Churn))
[1. 问题根源](#1. 问题根源)
[2. 优化策略](#2. 优化策略)
[1. 优化策略](#1. 优化策略)
[十、 性能分析工具链](#十、 性能分析工具链)
[1. 核心工具](#1. 核心工具)
[2. 最佳实践](#2. 最佳实践)
一、UI卡顿/掉帧
场景 :列表滚动、复杂动画、频繁UI更新时出现卡顿。
原因:
-
主线程阻塞:网络请求、文件读写、复杂计算等耗时操作占用主线程。
-
布局复杂度高:多层嵌套导致测量/布局时间过长。
-
过度绘制(Overdraw):同一像素区域被多次绘制,浪费GPU资源,导致GPU负载高。
-
频繁GC:内存抖动引发垃圾回收,导致界面冻结。
优化策略与实现:
-
异步处理:
javaviewModelScope.launch(Dispatchers.IO) { // 执行耗时操作 val data = fetchData() withContext(Dispatchers.Main) { updateUI(data) } }
- 使用Kotlin
协程
、RxJava
或**AsyncTask
**将耗时操作移至子线程。
- 使用Kotlin
-
布局优化:
-
使用**
ConstraintLayout
**替代多层嵌套的LinearLayout
或RelativeLayout
,减少布局层级。 -
通过
Android Studio
Layout Inspector 分析布局性能,移除冗余视图。 -
使用 ViewStub延迟加载不常用视图。
XML<ViewStub android:id="@+id/stub_ads" android:layout="@layout/ads" android:inflatedId="@+id/ads_container" />
动态加载时机:
KotlinfindViewById<ViewStub>(R.id.stub_ads).inflate()
-
-
减少过度绘制:
-
开启开发者选项中的GPU过度绘制调试,将过度绘制层级控制在2层以内。
-
移除不必要的**
background
**属性。
-
-
渲染优化
-
避免在**
onDraw
**中创建对象,优先复用。 -
启用硬件加速(Android 4.0+默认开启)。
-
二、内存泄漏(Memory Leak)
场景 :Activity/Fragment销毁后仍被持有引用,导致无法回收。
原因:
-
长生命周期对象持有Context:如单例、静态变量引用Activity。
-
未释放资源 :未正确注销监听器或广播接收器,**
Cursor
**未关闭。 -
匿名内部类隐式引用:Handler、Runnable等持有外部类实例。
优化策略与实现:
-
引用管理:
-
使用**
WeakReference
**或SoftReference
替代强引用。 -
弱引用Handler:
Kotlinclass SafeHandler(activity: Activity) : Handler(Looper.getMainLooper()) { private val weakRef = WeakReference(activity) override fun handleMessage(msg: Message) { weakRef.get()?.handleMessage(msg) } }
-
避免静态Context :单例中传递**
ApplicationContext
**而非Activity Context。 -
在onDestroy
()
中及时解除监听或注销广播:
java@Override protected void onDestroy() { sensorManager.unregisterListener(this); LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver); super.onDestroy(); }
-
-
工具检测:
-
使用**
LeakCanary
**自动检测内存泄漏,并显示引用链。 -
LeakCanary集成:
Groovydependencies { debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12' }
-
通过Android Profile
r
分析内存堆转储(Heap Dump)。
-
三、ANR(Application Not Responding)
场景:
-
主线程阻塞超过5秒:如密集计算、同步IO操作。
-
BroadcastReceiver超时 :前台10秒、后台60秒未完成
onReceive()
。
原因:
-
主线程执行文件读写、数据库查询或网络请求。
-
同步锁竞争导致主线程等待。
优化策略与实现:
-
主线程IO检测:
KotlinStrictMode.setThreadPolicy( StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .penaltyLog() // 仅记录不崩溃 .build() )
-
异步化处理:
-
使用
Room
数据库的异步查询(返回LiveData
或Flow
)。 -
网络请求使用
Retrofit + Coroutines
或WorkManager
。
-
-
避免主线程阻塞:
- 将耗时逻辑移至**
IntentService
**或WorkManager
。
javaval workRequest = OneTimeWorkRequestBuilder<DataSyncWorker>().build() WorkManager.getInstance(context).enqueue(workRequest)
- 将耗时逻辑移至**
四、列表滑动卡顿(RecyclerView/ListView)
场景 :列表滑动时出现卡顿或白屏。
原因:
-
onBindViewHolder
中执行耗时操作(如图片加载、复杂计算)。 -
未正确使用
ViewHolder
复用机制。 -
布局过于复杂。
优化策略与实现:
-
ViewHolder优化:
-
使用
RecyclerView.setHasFixedSize(true)
避免重复测量。 -
在
onCreateViewHolder
中初始化视图,避免在onBindViewHolder
中频繁调用findViewById
。
-
-
异步加载图片:
- 使用
Glide
实现图片异步加载与缓存。
javaGlide.with(context) .load(imageUrl) .placeholder(R.drawable.placeholder) .into(imageView)
- 使用
-
分页加载:
- 使用
Paging 3
库实现分页加载,减少一次性加载数据量。
- 使用
五、冷启动耗时过长
场景 :应用首次启动或冷启动时黑屏/白屏时间过长。
原因:
-
**
Application
或MainActivity
**初始化任务过多。 -
主题中未设置启动窗口(Splash Screen)。
-
首屏Activity布局渲染慢。
优化策略与实现:
-
延迟非核心初始化:
Kotlinclass MyApp : Application() { override fun onCreate() { super.onCreate() loadSplashResources() // 核心初始化 Handler().postDelayed({ initAnalytics() }, 2000) // 延迟非关键任务 } }
-
启动主题优化:
- 设置**
windowBackground
**为启动图,避免白屏:
XML<style name="LaunchTheme" parent="Theme.Material3.Light.NoActionBar"> <item name="android:windowBackground">@drawable/splash_background</item> </style>
- 设置**
六、内存抖动(Memory Churn)
场景 :频繁GC导致界面卡顿。
原因:
- 在循环中频繁创建临时对象(如字符串拼接、Bitmap解码)。
优化策略与实现:
-
对象复用:
- 使用
对象池
(如Message.obtain()
)或RecyclerViewPool
复用对象。
- 使用
-
避免临时对象:
-
使用
StringBuilder
替代字符串拼接。 -
预加载或缓存
Bitmap
资源。
-
七、网络与电量优化
1. 问题根源
-
频繁网络请求:未合理使用缓存或批量请求。
-
传感器滥用:GPS或传感器在后台持续运行。
2. 优化策略
-
OkHttp缓存配置:
Kotlinval client = OkHttpClient.Builder() .cache(Cache(File(context.cacheDir, "http_cache"), 10 * 1024 * 1024) .build()
-
JobScheduler管理任务:
javaJobInfo job = new JobInfo.Builder(1, new ComponentName(this, MyJobService.class)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setPeriodic(15 * 60 * 1000) .build(); JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE); scheduler.schedule(job);
八、存储与数据库优化
1. 问题根源
-
主线程数据库操作:导致UI卡顿或ANR。
-
低效SQL查询:未添加索引或全表扫描。
2. 优化策略
-
Room异步查询:
Kotlin@Dao interface UserDao { @Query("SELECT * FROM user") fun getAll(): Flow<List<User>> // 自动异步 }
-
SharedPreferences批量写入:
javaprefs.edit() .putString("key1", "value1") .putInt("key2", 100) .apply() // 异步提交
九、APK体积与安装优化
1. 优化策略
-
代码混淆与资源压缩:
Groovyandroid { buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } }
-
WebP替代PNG/JPG:
bashcwebp -q 80 input.png -o output.webp
十、 性能分析工具链
1. 核心工具
工具 | 适用场景 | 关键操作步骤 |
---|---|---|
Android Profiler | 实时监控CPU、内存、网络 | 点击Profiler → 选择进程 → 查看实时数据 |
Systrace | 分析系统级性能瓶颈(如UI线程阻塞) | 运行命令生成trace → 浏览器打开分析 |
Perfetto | 更细粒度的线程与系统事件跟踪 | 捕获Trace文件 → 上传至 ui.perfetto.dev 分析 |
Layout Inspector | 检查视图层级与布局性能 | Tools → Layout Inspector → 选择进程 → 查看视图树 |
2. 最佳实践
-
优先级排序:先解决ANR与内存泄漏,再优化UI渲染和启动时间。
-
持续监控:集成Firebase Performance Monitoring或Android Vitals,长期跟踪性能指标。
-
代码规范 :遵循Google的性能优化指南,避免常见反模式。
-
编码规范:
-
避免在
onDraw()
中创建对象。 -
使用
Lint
静态代码分析工具检查潜在问题。
-
推荐博文: