Android性能优化方面

在 Android 开发中,性能优化 是中后期稳定性和用户体验的关键工作,优化的目标是让 应用运行更流畅、内存更省、耗电更低、启动更快、界面不卡顿

下面我会系统性地分析 Android 性能优化的各个方向,并附带一些关键代码示例(含注释)。


🧭 一、性能优化的主要方向

优化方向目标常见手段
启动优化缩短冷启动/热启动时间延迟初始化、启动页优化
内存优化降低内存占用、防止 OOM使用内存分析工具、合理管理 Bitmap
绘制优化提升界面流畅度避免过度绘制、减少层级
布局优化提高渲染效率ConstraintLayout、ViewStub、Merge 标签
I/O 优化降低磁盘/网络延迟异步加载、缓存、压缩
线程优化防止主线程卡顿使用协程、Handler、Executor
电量优化降低耗电降低后台唤醒频率、批量任务处理
数据结构优化提高算法效率使用 SparseArray、LruCache 等
动画优化流畅不卡顿使用硬件加速、Property Animation

🚀 二、启动优化(App 启动速度)

启动时间太长会让用户误以为应用卡死。

✅ 优化思路:

  1. 延迟加载不必要模块(例如广告、推送)

  2. Application 中只做必要初始化

  3. 使用异步初始化

class App : Application() {

    override fun onCreate() {
        super.onCreate()

        // ✅ 必要初始化(立即执行)
        initLogger()

        // ⚙️ 非必要初始化(异步延迟执行)
        GlobalScope.launch(Dispatchers.Default) {
            initAnalytics()
            initPushService()
        }
    }
}

🧠 三、内存优化(Memory Leak / OOM)

常见内存泄漏场景:Activity 引用未释放、Handler 匿名类、单例持有 Context。

✅ 示例:使用 WeakReference 避免 Handler 内存泄漏

class SafeHandler(activity: Activity) : Handler(Looper.getMainLooper()) {
    private val weakRef = WeakReference(activity)

    override fun handleMessage(msg: Message) {
        val act = weakRef.get() ?: return
        when (msg.what) {
            1 -> act.showToast("任务完成")
        }
    }
}

🎨 四、绘制与布局优化

布局过于复杂会导致 UI 卡顿、渲染慢。

✅ 使用 ConstraintLayout 代替多层嵌套布局

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 多个布局通过约束定位,减少嵌套 -->
    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

✅ 使用 ViewStub 延迟加载不常用布局

<ViewStub
    android:id="@+id/vs_empty"
    android:layout="@layout/layout_empty"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
// 当需要显示空布局时再加载,减少初始布局解析
val emptyView = binding.vsEmpty.inflate()

💾 五、I/O 与网络优化

I/O 阻塞会导致主线程 ANR。

✅ 异步加载 + 缓存策略

suspend fun loadData(): String = withContext(Dispatchers.IO) {
    // 优先读缓存
    val cache = getCache("data.json")
    if (cache != null) return@withContext cache

    // 缓存不存在则请求网络
    val response = apiService.getData()
    saveCache("data.json", response)
    return@withContext response
}

⚙️ 六、线程优化(避免主线程卡顿)

所有耗时操作都应放在子线程执行。

✅ 协程方式处理耗时任务

lifecycleScope.launch {
    showLoading()
    val data = withContext(Dispatchers.IO) {
        // 耗时操作,如数据库或网络请求
        fetchUserInfo()
    }
    updateUI(data)
    hideLoading()
}

🔋 七、电量优化

减少后台唤醒与频繁网络请求。

✅ 批量上传日志(而非每次事件都上传)

private val logs = mutableListOf<String>()

fun logEvent(event: String) {
    logs.add(event)
    if (logs.size >= 10) {
        uploadLogs()
    }
}

🧮 八、数据结构优化

使用合适的数据结构能显著提升性能。

✅ 使用 SparseArray 替代 HashMap(key 为 Int 时)

val map = SparseArray<String>()
map.put(1, "Hello")
map.put(2, "World")
Log.d("TAG", map[1]) // 输出 Hello

✅ 使用 LruCache 缓存 Bitmap

val cache = LruCache<String, Bitmap>(10 * 1024 * 1024) // 10MB 缓存
cache.put("avatar", bitmap)
val bmp = cache.get("avatar")

📊 九、工具与检测

工具功能
Android Profiler查看 CPU、内存、网络使用情况
LeakCanary自动检测内存泄漏
StrictMode检测主线程耗时操作
Systrace / Perfetto分析卡顿、掉帧问题
MAT / Profiler Heap Dump深度分析内存占用

✅ 总结

Android 性能优化的核心思想是:

让主线程更轻、内存更省、布局更扁平、数据加载更聪明。

优化不是一次性的,而是一个持续监测与调优的过程。
推荐在开发周期中定期使用 Profiler 检测应用性能,及时发现瓶颈。

以下是实例:
 

一、内存优化

1. 内存泄漏检测与预防

import android.content.Context
import android.os.Handler
import android.os.Looper
import java.lang.ref.WeakReference

/**
 * 内存泄漏常见场景及解决方案
 * 1. Handler内存泄漏
 * 2. 静态变量持有Context
 * 3. 匿名内部类持有外部类引用
 * 4. 资源未及时释放
 */
class MemoryOptimizationDemo {

    // ❌ 错误示例:静态变量持有Context导致内存泄漏
    companion object {
        private var sContext: Context? = null // 静态变量持有Context
        
        fun setContext(context: Context) {
            sContext = context // 这会导致Activity无法被回收
        }
    }
    
    // ✅ 正确示例:使用Application Context或弱引用
    companion object {
        private var sAppContext: WeakReference<Context>? = null
        
        fun setContext(context: Context) {
            // 使用Application Context而不是Activity Context
            sAppContext = WeakReference(context.applicationContext)
        }
    }

    private val mainHandler = Handler(Looper.getMainLooper())
    private var runnable: Runnable? = null

    /**
     * ❌ 错误示例:Handler导致的内存泄漏
     * 匿名Runnable隐式持有外部类引用
     */
    fun startProblematicTask() {
        runnable = object : Runnable {
            override fun run() {
                // 执行任务
                mainHandler.postDelayed(this, 1000) // 循环执行
            }
        }
        mainHandler.postDelayed(runnable!!, 1000)
    }

    /**
     * ✅ 正确示例:使用静态内部类+弱引用
     */
    fun startOptimizedTask() {
        val task = SafeRunnable(this)
        mainHandler.postDelayed(task, 1000)
    }
    
    private fun doWork() {
        // 执行具体工作
    }

    /**
     * 静态内部类,不持有外部类引用
     */
    private class SafeRunnable(outer: MemoryOptimizationDemo) : Runnable {
        // 使用弱引用,避免内存泄漏
        private val outerRef: WeakReference<MemoryOptimizationDemo> = WeakReference(outer)
        
        override fun run() {
            val outer = outerRef.get()
            outer?.doWork()
            // 注意:这里不再自动循环,由外部控制生命周期
        }
    }

    /**
     * 及时清理资源
     */
    fun cleanup() {
        // 移除所有回调
        mainHandler.removeCallbacksAndMessages(null)
        runnable = null
    }
}

2. 图片内存优化

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.LruCache

/**
 * 图片内存优化管理类
 * 1. 使用LruCache进行内存缓存
 * 2. 图片采样压缩
 * 3. 使用合适的Bitmap.Config
 * 4. 及时回收Bitmap
 */
class ImageMemoryManager(context: Context) {
    
    private val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
    private val cacheSize = maxMemory / 8 // 使用1/8的可用内存作为缓存
    
    // LruCache内存缓存
    private val memoryCache: LruCache<String, Bitmap> = object : LruCache<String, Bitmap>(cacheSize) {
        override fun sizeOf(key: String, bitmap: Bitmap): Int {
            // 返回Bitmap占用的内存大小,单位KB
            return bitmap.byteCount / 1024
        }
        
        override fun entryRemoved(evicted: Boolean, key: String, 
                                oldValue: Bitmap, newValue: Bitmap?) {
            // 当Bitmap被移除时,可以在这里进行回收
            if (evicted) {
                oldValue.recycle()
            }
        }
    }
    
    /**
     * 从内存缓存获取Bitmap
     */
    fun getBitmapFromMemory(key: String): Bitmap? {
        return memoryCache.get(key)
    }
    
    /**
     * 添加Bitmap到内存缓存
     */
    fun addBitmapToMemory(key: String, bitmap: Bitmap) {
        if (getBitmapFromMemory(key) == null) {
            memoryCache.put(key, bitmap)
        }
    }
    
    /**
     * 加载压缩后的图片
     * @param filePath 图片文件路径
     * @param reqWidth 目标宽度
     * @param reqHeight 目标高度
     */
    fun decodeSampledBitmapFromFile(filePath: String, reqWidth: Int, reqHeight: Int): Bitmap {
        // 第一次解析只获取图片尺寸,不加载像素数据
        val options = BitmapFactory.Options().apply {
            inJustDecodeBounds = true
        }
        BitmapFactory.decodeFile(filePath, options)
        
        // 计算采样率
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
        
        // 使用RGB_565减少内存占用(如果不需要透明度)
        options.inPreferredConfig = Bitmap.Config.RGB_565
        options.inJustDecodeBounds = false
        
        return BitmapFactory.decodeFile(filePath, options) ?: 
            throw IllegalArgumentException("无法解码图片: $filePath")
    }
    
    /**
     * 计算合适的采样率
     */
    private fun calculateInSampleSize(options: BitmapFactory.Options, 
                                    reqWidth: Int, reqHeight: Int): Int {
        val (width, height) = options.run { outWidth to outHeight }
        var inSampleSize = 1
        
        if (height > reqHeight || width > reqWidth) {
            val halfHeight = height / 2
            val halfWidth = width / 2
            
            // 计算最大的采样率,保证图片尺寸大于等于目标尺寸
            while (halfHeight / inSampleSize >= reqHeight && 
                   halfWidth / inSampleSize >= reqWidth) {
                inSampleSize *= 2
            }
        }
        
        return inSampleSize
    }
    
    /**
     * 清理缓存
     */
    fun clearCache() {
        memoryCache.evictAll()
    }
}

二、布局优化

1. 布局层级优化

<!-- ❌ 错误示例:嵌套过深的布局 -->
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        
        <ImageView
            android:layout_width="48dp"
            android:layout_height="48dp" />
            
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical">
            
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
                
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

<!-- ✅ 优化示例:使用ConstraintLayout减少嵌套 -->
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="48dp"
        android:layout_height="48dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toEndOf="@id/iv_icon"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@id/iv_icon" />

    <TextView
        android:id="@+id/tv_subtitle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="@id/tv_title"
        app:layout_constraintEnd_toEndOf="@id/tv_title"
        app:layout_constraintTop_toBottomOf="@id/tv_title" />

</androidx.constraintlayout.widget.ConstraintLayout>

2. ViewStub延迟加载

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewStub
import androidx.appcompat.app.AppCompatActivity

/**
 * 使用ViewStub优化布局加载
 * ViewStub是轻量级View,只有在需要时才inflate实际布局
 */
class ViewStubOptimizationActivity : AppCompatActivity() {
    
    private var errorViewStub: ViewStub? = null
    private var errorView: View? = null
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_viewstub_optimization)
        
        // 初始化ViewStub(此时不会加载实际布局)
        errorViewStub = findViewById(R.id.vs_error)
        
        // 模拟网络请求
        loadData()
    }
    
    private fun loadData() {
        // 模拟网络请求
        Thread {
            Thread.sleep(2000)
            
            runOnUiThread {
                // 假设请求失败,显示错误页面
                showErrorView()
            }
        }.start()
    }
    
    /**
     * 显示错误页面(只有这时才会实际加载错误布局)
     */
    private fun showErrorView() {
        if (errorView == null) {
            // 第一次调用时才会inflate实际布局
            errorView = errorViewStub?.inflate()
        } else {
            errorView?.visibility = View.VISIBLE
        }
        
        // 设置错误页面内容
        errorView?.findViewById<View>(R.id.btn_retry)?.setOnClickListener {
            // 重试逻辑
            errorView?.visibility = View.GONE
            loadData()
        }
    }
}

三、网络优化

import okhttp3.Cache
import okhttp3.CacheControl
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit

/**
 * 网络请求优化配置
 * 1. 连接池复用
 * 2. 请求缓存
 * 3. 超时优化
 * 4. 数据压缩
 */
class NetworkOptimizationManager(private val context: Context) {
    
    companion object {
        private const val CACHE_SIZE = 10 * 1024 * 1024L // 10MB缓存
        private const val CONNECT_TIMEOUT = 15L
        private const val READ_TIMEOUT = 30L
        private const val WRITE_TIMEOUT = 30L
    }
    
    private val cacheDir by lazy { 
        File(context.cacheDir, "http_cache") 
    }
    
    private val cache by lazy { 
        Cache(cacheDir, CACHE_SIZE) 
    }
    
    /**
     * 创建优化的OkHttpClient
     */
    fun createOptimizedHttpClient(): OkHttpClient {
        return OkHttpClient.Builder().apply {
            // 连接池配置(默认已优化)
            connectionPool(ConnectionPool(5, 5, TimeUnit.MINUTES))
            
            // 超时配置
            connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
            
            // 缓存配置
            cache(cache)
            
            // 添加拦截器进行统一优化
            addInterceptor { chain ->
                val originalRequest = chain.request()
                
                // 添加公共头部
                val requestBuilder = originalRequest.newBuilder()
                    .header("Accept-Encoding", "gzip") // 启用Gzip压缩
                    .header("Connection", "keep-alive") // 保持连接
                    .method(originalRequest.method, originalRequest.body)
                
                // 网络不可用时使用缓存
                if (!isNetworkAvailable()) {
                    requestBuilder.cacheControl(
                        CacheControl.Builder()
                            .onlyIfCached()
                            .maxStale(7, TimeUnit.DAYS) // 最大缓存时间
                            .build()
                    )
                }
                
                val response = chain.proceed(requestBuilder.build())
                
                // 统一处理响应
                response.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public, max-age=300") // 5分钟缓存
                    .build()
            }
            
            // 调试日志(仅Debug模式开启)
            if (BuildConfig.DEBUG) {
                addInterceptor(
                    HttpLoggingInterceptor().apply {
                        level = HttpLoggingInterceptor.Level.BODY
                    }
                )
            }
            
            // 失败重试
            retryOnConnectionFailure(true)
            
        }.build()
    }
    
    /**
     * 创建Retrofit实例
     */
    fun createRetrofit(baseUrl: String): Retrofit {
        return Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(createOptimizedHttpClient())
            .addConverterFactory(GsonConverterFactory.create())
            .build()
    }
    
    /**
     * 检查网络是否可用
     */
    private fun isNetworkAvailable(): Boolean {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) 
                as? android.net.ConnectivityManager
        return connectivityManager?.activeNetworkInfo?.isConnected == true
    }
}

四、启动优化

import android.app.Application
import android.content.Context
import android.os.StrictMode
import androidx.startup.Initializer
import com.facebook.drawee.backends.pipeline.Fresco

/**
 * 应用启动优化
 * 1. 异步初始化
 * 2. 延迟初始化
 * 3. 多进程优化
 * 4. StrictMode检测
 */
class AppStartupOptimization : Application() {
    
    override fun onCreate() {
        super.onCreate()
        
        // 主线程初始化必要组件
        initMainThreadComponents()
        
        // 后台线程初始化非紧急组件
        initBackgroundComponents()
        
        // 仅在Debug模式开启StrictMode
        if (BuildConfig.DEBUG) {
            enableStrictMode()
        }
    }
    
    /**
     * 必须在主线程初始化的组件
     */
    private fun initMainThreadComponents() {
        // 必须主线程初始化的组件
    }
    
    /**
     * 在后台线程初始化的组件
     */
    private fun initBackgroundComponents() {
        Thread {
            // 设置线程优先级,避免影响主线程
            Thread.currentThread().priority = Thread.MIN_PRIORITY
            
            // 初始化第三方SDK等耗时操作
            initThirdPartyLibraries()
            
            // 预加载数据
            preloadData()
        }.start()
    }
    
    private fun initThirdPartyLibraries() {
        // 例如:Fresco、统计SDK等
    }
    
    private fun preloadData() {
        // 预加载常用数据
    }
    
    /**
     * 启用StrictMode检测主线程违规操作
     */
    private fun enableStrictMode() {
        StrictMode.setThreadPolicy(
            StrictMode.ThreadPolicy.Builder()
                .detectAll() // 检测所有违规
                .penaltyLog() // 违规时打印日志
                .penaltyDeath() // 违规时崩溃(仅Debug)
                .build()
        )
        
        StrictMode.setVmPolicy(
            StrictMode.VmPolicy.Builder()
                .detectActivityLeaks() // 检测Activity泄漏
                .detectLeakedClosableObjects() // 检测未关闭对象
                .detectLeakedSqlLiteObjects() // 检测数据库泄漏
                .penaltyLog()
                .build()
        )
    }
}

/**
 * 使用App Startup库进行初始化优化
 */
class FrescoInitializer : Initializer<Unit> {
    
    override fun create(context: Context) {
        // 初始化Fresco
        Fresco.initialize(context)
    }
    
    override fun dependencies(): List<Class<out Initializer<*>>> {
        // 定义依赖关系
        return emptyList()
    }
}

五、数据库优化

import android.content.ContentValues
import android.database.Cursor
import androidx.room.*
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.SupportSQLiteQuery

/**
 * Room数据库优化
 * 1. 索引优化
 * 2. 事务批量操作
 * 3. 查询优化
 * 4. 数据库升级优化
 */
@Database(
    entities = [User::class, Order::class],
    version = 1,
    exportSchema = false
)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
    
    abstract fun userDao(): UserDao
    abstract fun orderDao(): OrderDao
    
    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null
        
        fun getInstance(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
            }
        }
        
        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(
                context.applicationContext,
                AppDatabase::class.java,
                "app_database.db"
            ).apply {
                // 查询时在后台线程执行
                allowMainThreadQueries() // ❌ 生产环境不要使用
                
                // 添加回调进行数据库优化
                addCallback(object : Callback() {
                    override fun onCreate(db: SupportSQLiteDatabase) {
                        super.onCreate(db)
                        // 数据库创建时的优化
                        db.execSQL("PRAGMA journal_mode = WAL") // 启用WAL模式
                        db.execSQL("PRAGMA synchronous = NORMAL") // 同步模式优化
                        db.execSQL("PRAGMA cache_size = 10000") // 缓存大小
                    }
                    
                    override fun onOpen(db: SupportSQLiteDatabase) {
                        super.onOpen(db)
                        // 每次打开数据库时的优化
                        db.execSQL("PRAGMA optimize") // 优化数据库
                    }
                })
                
                // 数据库升级策略
                addMigrations(MIGRATION_1_2)
                
            }.build()
        }
        
        // 数据库迁移示例
        private val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                // 执行迁移SQL
                database.execSQL("ALTER TABLE user ADD COLUMN last_login_time INTEGER")
            }
        }
    }
}

/**
 * 用户实体类 - 使用索引优化
 */
@Entity(
    tableName = "user",
    indices = [
        Index(value = ["email"], unique = true), // 唯一索引
        Index(value = ["name"]), // 普通索引
        Index(value = ["age", "city"]) // 复合索引
    ]
)
data class User(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0,
    
    @ColumnInfo(name = "name")
    val name: String,
    
    @ColumnInfo(name = "email")
    val email: String,
    
    @ColumnInfo(name = "age")
    val age: Int,
    
    @ColumnInfo(name = "city")
    val city: String,
    
    @ColumnInfo(name = "last_login_time")
    val lastLoginTime: Long? = null
)

/**
 * 用户数据访问对象 - 查询优化
 */
@Dao
interface UserDao {
    
    /**
     * 插入用户(使用事务批量插入)
     */
    @Insert
    suspend fun insertUser(user: User)
    
    /**
     * 批量插入用户 - 使用事务优化
     */
    @Transaction
    suspend fun insertUsers(users: List<User>) {
        users.forEach { insertUser(it) }
    }
    
    /**
     * 查询优化 - 只查询需要的字段
     */
    @Query("SELECT id, name FROM user WHERE age > :minAge")
    suspend fun getUsersAboveAge(minAge: Int): List<UserBrief>
    
    /**
     * 使用索引优化查询
     */
    @Query("SELECT * FROM user WHERE name LIKE :name AND city = :city")
    suspend fun findUsersByNameAndCity(name: String, city: String): List<User>
    
    /**
     * 分页查询优化
     */
    @Query("SELECT * FROM user ORDER BY id LIMIT :pageSize OFFSET :offset")
    suspend fun getUsersPaged(pageSize: Int, offset: Int): List<User>
    
    /**
     * 使用原生SQL进行复杂查询优化
     */
    @RawQuery
    suspend fun executeOptimizedQuery(query: SupportSQLiteQuery): List<User>
}

/**
 * 用户简要信息 - 投影查询优化
 */
data class UserBrief(
    val id: Long,
    val name: String
)

/**
 * 类型转换器
 */
class Converters {
    @TypeConverter
    fun fromTimestamp(value: Long?): Date? {
        return value?.let { Date(it) }
    }
    
    @TypeConverter
    fun dateToTimestamp(date: Date?): Long? {
        return date?.time
    }
}

六、性能监控工具

import android.os.Debug
import android.os.SystemClock
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit

/**
 * 性能监控工具类
 * 1. 帧率监控
 * 2. 内存监控
 * 3. CPU监控
 * 4. 启动时间监控
 */
class PerformanceMonitor private constructor() {
    
    companion object {
        @Volatile
        private var instance: PerformanceMonitor? = null
        
        fun getInstance(): PerformanceMonitor {
            return instance ?: synchronized(this) {
                instance ?: PerformanceMonitor().also { instance = it }
            }
        }
    }
    
    private val scheduler = Executors.newScheduledThreadPool(1)
    private var monitoringTask: ScheduledFuture<*>? = null
    private var frameRateListener: ((Int) -> Unit)? = null
    private var memoryUsageListener: ((Long) -> Unit)? = null
    
    private var frameCount = 0
    private var lastFrameTime = 0L
    
    /**
     * 开始监控帧率
     */
    fun startFrameRateMonitoring(listener: (Int) -> Unit) {
        this.frameRateListener = listener
        lastFrameTime = SystemClock.elapsedRealtime()
        
        monitoringTask = scheduler.scheduleAtFixedRate({
            val currentTime = SystemClock.elapsedRealtime()
            val elapsed = currentTime - lastFrameTime
            
            if (elapsed >= 1000) { // 每秒计算一次帧率
                val fps = (frameCount * 1000 / elapsed).toInt()
                frameRateListener?.invoke(fps)
                
                frameCount = 0
                lastFrameTime = currentTime
            }
        }, 0, 16, TimeUnit.MILLISECONDS) // 每16ms执行一次(约60fps)
    }
    
    /**
     * 记录一帧渲染完成
     */
    fun onFrameRendered() {
        frameCount++
    }
    
    /**
     * 获取当前内存使用情况
     */
    fun getMemoryUsage(): Long {
        val runtime = Runtime.getRuntime()
        return runtime.totalMemory() - runtime.freeMemory()
    }
    
    /**
     * 开始内存监控
     */
    fun startMemoryMonitoring(listener: (Long) -> Unit) {
        this.memoryUsageListener = listener
        
        scheduler.scheduleAtFixedRate({
            val memoryUsage = getMemoryUsage()
            memoryUsageListener?.invoke(memoryUsage)
        }, 0, 2, TimeUnit.SECONDS) // 每2秒检查一次内存
    }
    
    /**
     * 停止所有监控
     */
    fun stopMonitoring() {
        monitoringTask?.cancel(true)
        monitoringTask = null
        frameRateListener = null
        memoryUsageListener = null
        frameCount = 0
    }
    
    /**
     * 检测是否在主线程
     */
    fun isOnMainThread(): Boolean {
        return Looper.getMainLooper().thread == Thread.currentThread()
    }
    
    /**
     * 方法执行时间监控
     */
    inline fun <T> measureTime(operationName: String, block: () -> T): T {
        val startTime = System.nanoTime()
        try {
            return block()
        } finally {
            val duration = (System.nanoTime() - startTime) / 1_000_000 // 转换为毫秒
            if (duration > 16) { // 超过一帧时间(16ms)
                Log.w("Performance", "$operationName 执行耗时: ${duration}ms")
            }
        }
    }
}

简单来说:

  1. 内存优化

    • 使用弱引用避免内存泄漏

    • 及时回收Bitmap等大对象

    • 使用LruCache合理管理缓存

  2. 布局优化

    • 减少布局层级

    • 使用ConstraintLayout

    • 善用ViewStub和Merge

  3. 网络优化

    • 合理使用缓存

    • 连接复用

    • 数据压缩

  4. 启动优化

    • 异步初始化

    • 延迟加载

    • 多进程优化

  5. 数据库优化

    • 使用索引

    • 事务批量操作

    • 查询字段优化

  6. 监控工具

    • 实时监控性能指标

    • 定位性能瓶颈

    • 持续优化改进

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值