# 性能优化最佳实践 性能优化是Android应用开发的重要环节,直接影响用户体验和应用质量。本文档介绍Android应用性能优化的最佳实践。 ## 目录 - [性能优化策略](#性能优化策略) - [启动优化实践](#启动优化实践) - [内存优化实践](#内存优化实践) - [布局优化实践](#布局优化实践) - [网络优化实践](#网络优化实践) - [性能监控](#性能监控) --- ## 性能优化策略 ### 1. 性能优化原则 #### 测量优先 ```kotlin // ✅ 好的做法:先测量,再优化 class PerformanceMonitor { fun measureTime(block: () -> Unit): Long { val startTime = System.currentTimeMillis() block() return System.currentTimeMillis() - startTime } fun measureMemory(block: () -> Unit): Long { val runtime = Runtime.getRuntime() val beforeMemory = runtime.totalMemory() - runtime.freeMemory() block() val afterMemory = runtime.totalMemory() - runtime.freeMemory() return afterMemory - beforeMemory } } // 使用 val monitor = PerformanceMonitor() val time = monitor.measureTime { // 执行代码 } Log.d("Performance", "执行时间: ${time}ms") ``` #### 优化关键路径 ```kotlin // 识别关键路径并优化 class AppInitializer { fun initialize() { // 关键路径:必须立即初始化 initCriticalComponents() // 非关键路径:可以延迟初始化 Handler(Looper.getMainLooper()).postDelayed({ initNonCriticalComponents() }, 100) } } ``` ### 2. 性能指标 #### 关键指标 ```kotlin // 启动时间 class StartupTimeTracker { private var appStartTime: Long = 0 fun onAppStart() { appStartTime = System.currentTimeMillis() } fun onFirstFrame() { val startupTime = System.currentTimeMillis() - appStartTime Log.d("Performance", "启动时间: ${startupTime}ms") } } // 内存使用 class MemoryTracker { fun getMemoryUsage(): MemoryInfo { val runtime = Runtime.getRuntime() val totalMemory = runtime.totalMemory() val freeMemory = runtime.freeMemory() val usedMemory = totalMemory - freeMemory return MemoryInfo( total = totalMemory, used = usedMemory, free = freeMemory ) } } ``` --- ## 启动优化实践 ### 1. Application优化 #### 延迟初始化 ```kotlin // ✅ 好的做法:延迟初始化非关键组件 class MyApplication : Application() { override fun onCreate() { super.onCreate() // 关键初始化:必须立即执行 initCriticalComponents() // 非关键初始化:延迟执行 initNonCriticalComponentsAsync() } private fun initCriticalComponents() { // 初始化关键组件 CrashReporting.init(this) } private fun initNonCriticalComponentsAsync() { // 使用后台线程初始化 Thread { // 初始化非关键组件 Analytics.init(this) ImageLoader.init(this) }.start() } } ``` #### 使用App Startup ```kotlin // 使用App Startup统一管理初始化 class MyInitializer : Initializer { override fun create(context: Context) { // 初始化组件 Analytics.init(context) } override fun dependencies(): List>> { // 定义依赖关系 return listOf(OtherInitializer::class.java) } } // 在AndroidManifest.xml中注册 // // // ``` ### 2. 首屏优化 #### 减少首屏布局复杂度 ```xml ``` #### 使用ViewStub延迟加载 ```xml ``` ```kotlin // 在需要时加载 class MainActivity : AppCompatActivity() { private lateinit var viewStub: ViewStub override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) viewStub = findViewById(R.id.viewStub) // 延迟加载 button.setOnClickListener { if (viewStub.parent != null) { viewStub.inflate() } } } } ``` ### 3. 启动时间测量 #### 使用Trace API ```kotlin // 使用Trace API标记启动流程 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { Trace.beginSection("MainActivity.onCreate") super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Trace.beginSection("initViews") initViews() Trace.endSection() Trace.beginSection("loadData") loadData() Trace.endSection() Trace.endSection() } } // 使用Systrace分析 // python systrace.py -t 10 -o trace.html sched freq idle am wm gfx view binder_driver hal dalvik camera input res ``` --- ## 内存优化实践 ### 1. 内存泄漏预防 #### 避免静态引用 ```kotlin // ❌ 不好的做法:静态引用Context object AppContext { var context: Context? = null // 可能导致内存泄漏 } // ✅ 好的做法:使用Application Context object AppContext { fun getContext(): Context { return MyApplication.instance } } ``` #### 正确处理生命周期 ```kotlin // ✅ 好的做法:正确处理生命周期 class MainActivity : AppCompatActivity() { private var handler: Handler? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 使用静态内部类+WeakReference handler = MyHandler(this) } override fun onDestroy() { super.onDestroy() handler?.removeCallbacksAndMessages(null) handler = null } private class MyHandler(activity: MainActivity) : Handler(Looper.getMainLooper()) { private val activityRef = WeakReference(activity) override fun handleMessage(msg: Message) { activityRef.get()?.let { // 处理消息 } } } } ``` ### 2. 内存使用优化 #### 使用对象池 ```kotlin // 对象池:复用对象,减少GC class ObjectPool(private val factory: () -> T, private val maxSize: Int = 10) { private val pool = mutableListOf() fun acquire(): T { return if (pool.isNotEmpty()) { pool.removeAt(pool.size - 1) } else { factory() } } fun release(obj: T) { if (pool.size < maxSize) { pool.add(obj) } } } // 使用 val viewPool = ObjectPool({ View(context) }) val view = viewPool.acquire() // 使用view viewPool.release(view) ``` #### 优化图片加载 ```kotlin // 使用Glide等图片加载库 Glide.with(context) .load(imageUrl) .placeholder(R.drawable.placeholder) .error(R.drawable.error) .override(800, 600) // 指定尺寸 .into(imageView) // 使用WebP格式 // WebP格式比PNG/JPG更小,加载更快 // 使用图片压缩 fun compressBitmap(bitmap: Bitmap, quality: Int = 80): ByteArray { val stream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.WEBP, quality, stream) return stream.toByteArray() } ``` ### 3. 内存监控 #### 使用LeakCanary ```gradle // build.gradle dependencies { debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12' } ``` ```kotlin // 自动检测内存泄漏 // LeakCanary会自动检测并报告内存泄漏 ``` #### 手动内存分析 ```kotlin // 获取内存信息 class MemoryAnalyzer { fun getMemoryInfo(): String { val runtime = Runtime.getRuntime() val maxMemory = runtime.maxMemory() val totalMemory = runtime.totalMemory() val freeMemory = runtime.freeMemory() val usedMemory = totalMemory - freeMemory return """ Max Memory: ${maxMemory / 1024 / 1024}MB Total Memory: ${totalMemory / 1024 / 1024}MB Used Memory: ${usedMemory / 1024 / 1024}MB Free Memory: ${freeMemory / 1024 / 1024}MB """.trimIndent() } fun dumpHeap(): File { val heapDumpFile = File(cacheDir, "heap_dump.hprof") Debug.dumpHprofData(heapDumpFile.absolutePath) return heapDumpFile } } ``` --- ## 布局优化实践 ### 1. 减少布局层级 #### 使用ConstraintLayout ```xml ``` ### 2. 避免过度绘制 #### 减少背景绘制 ```xml ``` #### 使用clipToPadding ```xml ``` ### 3. RecyclerView优化 #### ViewHolder复用 ```kotlin // ✅ 好的做法:正确实现ViewHolder class UserAdapter : RecyclerView.Adapter() { class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val nameTextView: TextView = itemView.findViewById(R.id.name) val emailTextView: TextView = itemView.findViewById(R.id.email) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(parent.context) .inflate(R.layout.item_user, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { val user = users[position] holder.nameTextView.text = user.name holder.emailTextView.text = user.email } } ``` #### 使用DiffUtil ```kotlin // 使用DiffUtil优化列表更新 class UserDiffCallback( private val oldList: List, private val newList: List ) : DiffUtil.Callback() { override fun getOldListSize() = oldList.size override fun getNewListSize() = newList.size override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { return oldList[oldItemPosition].id == newList[newItemPosition].id } override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { return oldList[oldItemPosition] == newList[newItemPosition] } } // 使用 val diffResult = DiffUtil.calculateDiff(UserDiffCallback(oldList, newList)) adapter.users = newList diffResult.dispatchUpdatesTo(adapter) ``` --- ## 网络优化实践 ### 1. 请求优化 #### 请求合并 ```kotlin // ✅ 好的做法:合并请求 class ApiService { @GET("users") suspend fun getUsers(@Query("ids") ids: String): List // 一次请求获取多个用户,而不是多次请求 } // ❌ 不好的做法:多次请求 // for (id in userIds) { // apiService.getUser(id) // } ``` #### 使用缓存 ```kotlin // 使用OkHttp缓存 val client = OkHttpClient.Builder() .cache(Cache(cacheDir, 10 * 1024 * 1024)) // 10MB缓存 .build() // 使用Retrofit缓存 @Headers("Cache-Control: max-age=3600") @GET("users/{id}") suspend fun getUser(@Path("id") id: String): User ``` ### 2. 数据压缩 #### 使用Gzip ```kotlin // 服务器端启用Gzip压缩 // 客户端自动处理Gzip响应 // OkHttp自动支持Gzip解压 ``` #### 数据格式优化 ```kotlin // 使用Protobuf替代JSON // Protobuf更小、更快 data class User( val id: String, val name: String, val email: String ) // 转换为Protobuf val userProto = UserProto.newBuilder() .setId(user.id) .setName(user.name) .setEmail(user.email) .build() ``` ### 3. 网络监控 #### 监控网络请求 ```kotlin // 使用OkHttp Interceptor监控 class NetworkMonitorInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() val startTime = System.currentTimeMillis() val response = chain.proceed(request) val duration = System.currentTimeMillis() - startTime Log.d("Network", "${request.url} - ${duration}ms") return response } } val client = OkHttpClient.Builder() .addInterceptor(NetworkMonitorInterceptor()) .build() ``` --- ## 性能监控 ### 1. 性能指标收集 #### 使用Firebase Performance ```gradle // build.gradle dependencies { implementation 'com.google.firebase:firebase-perf-ktx:20.4.1' } ``` ```kotlin // 监控自定义性能指标 val trace = FirebasePerformance.getInstance().newTrace("load_user_data") trace.start() // 执行操作 loadUserData() trace.stop() ``` #### 自定义性能监控 ```kotlin class PerformanceTracker { private val metrics = mutableMapOf() fun startTrace(name: String) { metrics[name] = System.currentTimeMillis() } fun endTrace(name: String) { val startTime = metrics[name] if (startTime != null) { val duration = System.currentTimeMillis() - startTime Log.d("Performance", "$name: ${duration}ms") metrics.remove(name) } } } // 使用 val tracker = PerformanceTracker() tracker.startTrace("load_data") // 执行操作 tracker.endTrace("load_data") ``` ### 2. 性能分析工具 #### 使用Android Profiler ```kotlin // Android Studio Profiler可以监控: // - CPU使用率 // - 内存使用情况 // - 网络请求 // - 电量消耗 ``` #### 使用Systrace ```bash # 使用Systrace分析性能 python systrace.py -t 10 -o trace.html sched freq idle am wm gfx view binder_driver hal dalvik camera input res # 在代码中标记 Trace.beginSection("my_section") // 执行代码 Trace.endSection() ``` #### 使用Perfetto ```kotlin // Perfetto是更强大的性能分析工具 // 可以分析: // - CPU调度 // - 内存分配 // - 文件I/O // - 网络活动 ``` --- ## 总结 性能优化是一个持续的过程,需要: 1. **测量优先**:先测量性能,找出瓶颈 2. **优化关键路径**:优先优化影响用户体验的关键路径 3. **启动优化**:减少启动时间,提升用户体验 4. **内存优化**:避免内存泄漏,优化内存使用 5. **布局优化**:减少布局层级,避免过度绘制 6. **网络优化**:优化网络请求,使用缓存 7. **性能监控**:持续监控性能指标,及时发现问题 通过遵循这些最佳实践,可以显著提升应用的性能和用户体验。