# 性能优化最佳实践

性能优化是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<Unit> {
    override fun create(context: Context) {
        // 初始化组件
        Analytics.init(context)
    }
    
    override fun dependencies(): List<Class<out Initializer<*>>> {
        // 定义依赖关系
        return listOf(OtherInitializer::class.java)
    }
}

// 在AndroidManifest.xml中注册
// <provider
//     android:name="androidx.startup.InitializationProvider"
//     android:authorities="${applicationId}.androidx-startup"
//     android:exported="false"
//     tools:node="merge">
//     <meta-data
//         android:name="com.example.MyInitializer"
//         android:value="androidx.startup" />
// </provider>
```

### 2. 首屏优化

#### 减少首屏布局复杂度

```xml
<!-- ✅ 好的做法：简化首屏布局 -->
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <!-- 只显示关键内容 -->
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="欢迎"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

<!-- ❌ 不好的做法：首屏包含过多内容 -->
```

#### 使用ViewStub延迟加载

```xml
<!-- 使用ViewStub延迟加载非关键视图 -->
<ViewStub
    android:id="@+id/viewStub"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout="@layout/expensive_view"/>
```

```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<T>(private val factory: () -> T, private val maxSize: Int = 10) {
    private val pool = mutableListOf<T>()
    
    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
<!-- ✅ 好的做法：使用ConstraintLayout减少层级 -->
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="标题"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
    
    <TextView
        android:id="@+id/subtitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="副标题"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/title"/>
</androidx.constraintlayout.widget.ConstraintLayout>

<!-- ❌ 不好的做法：嵌套过多 -->
<LinearLayout>
    <LinearLayout>
        <TextView/>
    </LinearLayout>
</LinearLayout>
```

### 2. 避免过度绘制

#### 减少背景绘制

```xml
<!-- ✅ 好的做法：移除不必要的背景 -->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white">
    <!-- 子视图不需要再设置背景 -->
</LinearLayout>

<!-- ❌ 不好的做法：多层背景 -->
<LinearLayout android:background="@color/background1">
    <LinearLayout android:background="@color/background2">
        <!-- 导致过度绘制 -->
    </LinearLayout>
</LinearLayout>
```

#### 使用clipToPadding

```xml
<!-- 使用clipToPadding减少绘制区域 -->
<RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:padding="16dp"/>
```

### 3. RecyclerView优化

#### ViewHolder复用

```kotlin
// ✅ 好的做法：正确实现ViewHolder
class UserAdapter : RecyclerView.Adapter<UserAdapter.ViewHolder>() {
    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<User>,
    private val newList: List<User>
) : 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<User>
    // 一次请求获取多个用户，而不是多次请求
}

// ❌ 不好的做法：多次请求
// 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<String, Long>()
    
    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. **性能监控**：持续监控性能指标，及时发现问题

通过遵循这些最佳实践，可以显著提升应用的性能和用户体验。
