目錄
一、UI卡頓/掉幀
二、內存泄漏(Memory Leak)
三、ANR(Application Not Responding)
四、列表滑動卡頓(RecyclerView/ListView)
五、冷啟動耗時過長
六、內存抖動(Memory Churn)
七、網絡與電量優化
八、存儲與數據庫優化
1.?問題根源
2.?優化策略
九、APK體積與安裝優化
1.?優化策略
十、?性能分析工具鏈
1.?核心工具
2.?最佳實踐
一、UI卡頓/掉幀
場景:列表滾動、復雜動畫、頻繁UI更新時出現卡頓。
原因:
-
主線程阻塞:網絡請求、文件讀寫、復雜計算等耗時操作占用主線程。
-
布局復雜度高:多層嵌套導致測量/布局時間過長。
-
過度繪制(Overdraw):同一像素區域被多次繪制,浪費GPU資源,導致GPU負載高。
-
頻繁GC:內存抖動引發垃圾回收,導致界面凍結。
優化策略與實現:
-
異步處理:
viewModelScope.launch(Dispatchers.IO) {// 執行耗時操作val data = fetchData()withContext(Dispatchers.Main) {updateUI(data)} }
-
使用
Kotlin協程
、RxJava
或AsyncTask
將耗時操作移至子線程。
-
-
布局優化:
-
使用
ConstraintLayout
替代多層嵌套的LinearLayout
或RelativeLayout
,減少布局層級。 -
通過
Android Studio Layout Inspector?
分析布局性能,移除冗余視圖。 -
使用?
ViewStub?
延遲加載不常用視圖。? -
<ViewStub android:id="@+id/stub_ads"android:layout="@layout/ads"android:inflatedId="@+id/ads_container" />
動態加載時機:
findViewById<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:
class 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()
中及時解除監聽或注銷廣播:
@Override protected void onDestroy() {sensorManager.unregisterListener(this);LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);super.onDestroy(); }
-
-
工具檢測:
-
使用
LeakCanary
自動檢測內存泄漏,并顯示引用鏈。 -
LeakCanary集成:
dependencies {debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12' }
-
通過
Android Profiler
分析內存堆轉儲(Heap Dump)。
-
三、ANR(Application Not Responding)
場景:
-
主線程阻塞超過5秒:如密集計算、同步IO操作。
-
BroadcastReceiver超時:前臺10秒、后臺60秒未完成
onReceive()
。
原因:
-
主線程執行文件讀寫、數據庫查詢或網絡請求。
-
同步鎖競爭導致主線程等待。
優化策略與實現:
-
主線程IO檢測:
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().penaltyLog() // 僅記錄不崩潰.build() )
-
異步化處理:
-
使用
Room
數據庫的異步查詢(返回LiveData
或Flow
)。 -
網絡請求使用
Retrofit + Coroutines
或WorkManager
。
-
-
避免主線程阻塞:
-
將耗時邏輯移至
IntentService
或WorkManager
。
val workRequest = OneTimeWorkRequestBuilder<DataSyncWorker>().build() WorkManager.getInstance(context).enqueue(workRequest)
-
四、列表滑動卡頓(RecyclerView/ListView)
場景:列表滑動時出現卡頓或白屏。
原因:
-
onBindViewHolder
中執行耗時操作(如圖片加載、復雜計算)。 -
未正確使用
ViewHolder
復用機制。 -
布局過于復雜。
優化策略與實現:
-
ViewHolder優化:
-
使用
RecyclerView.setHasFixedSize(true)
避免重復測量。 -
在
onCreateViewHolder
中初始化視圖,避免在onBindViewHolder
中頻繁調用findViewById
。
-
-
異步加載圖片:
-
使用
Glide
實現圖片異步加載與緩存。
Glide.with(context).load(imageUrl).placeholder(R.drawable.placeholder).into(imageView)
-
-
分頁加載:
-
使用
Paging 3
庫實現分頁加載,減少一次性加載數據量。
-
五、冷啟動耗時過長
場景:應用首次啟動或冷啟動時黑屏/白屏時間過長。
原因:
-
Application
或MainActivity
初始化任務過多。 -
主題中未設置啟動窗口(Splash Screen)。
-
首屏Activity布局渲染慢。
優化策略與實現:
-
延遲非核心初始化:
class MyApp : Application() {override fun onCreate() {super.onCreate()loadSplashResources() // 核心初始化Handler().postDelayed({ initAnalytics() }, 2000) // 延遲非關鍵任務} }
-
啟動主題優化:
-
設置
windowBackground
為啟動圖,避免白屏:
<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緩存配置:
val client = OkHttpClient.Builder().cache(Cache(File(context.cacheDir, "http_cache"), 10 * 1024 * 1024).build()
-
JobScheduler管理任務:
JobInfo 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異步查詢:
@Dao interface UserDao {@Query("SELECT * FROM user")fun getAll(): Flow<List<User>> // 自動異步 }
-
SharedPreferences批量寫入:
prefs.edit().putString("key1", "value1").putInt("key2", 100).apply() // 異步提交
九、APK體積與安裝優化
1.?優化策略
-
代碼混淆與資源壓縮:
android {buildTypes {release {minifyEnabled trueshrinkResources trueproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}} }
-
WebP替代PNG/JPG:
cwebp -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
靜態代碼分析工具檢查潛在問題。
-
推薦博文:
1. 《Android Glide 深度解析:工作原理、LRU 緩存機制與最佳實踐》
2.?《RxJava 深度解析:工作原理、核心操作符與高效實踐指南》
3.?《Android 平臺架構&系統啟動流程詳解》
4.?《OkHttp:工作原理 & 攔截器鏈深度解析》