久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx

如何快速定位Android啟動耗時問題

本篇內容主要講解“如何快速定位Android啟動耗時問題”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“如何快速定位Android啟動耗時問題”吧!

創新互聯專業為企業提供灌南網站建設、灌南做網站、灌南網站設計、灌南網站制作等企業網站建設、網頁設計與制作、灌南企業網站模板建站服務,10年灌南做網站經驗,不只是建網站,更提供有價值的思路和整體網絡服務。

1. 接入Tencent Matrix

1.1 在你項目根目錄下的 gradle.properties 中配置要依賴的 Matrix 版本號,如:

MATRIX_VERSION=1.0.0

1.2 在你項目根目錄下的 build.gradle 文件添加 Matrix 依賴,如:

dependencies {
      classpath ("com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}") { changing = true }
  }

1.3 在 app/build.gradle 文件中添加 Matrix 各模塊的依賴,如:

  dependencies {
    implementation group: "com.tencent.matrix", name: "matrix-android-lib", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-android-commons", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-trace-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-resource-canary-android", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-resource-canary-common", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-io-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-sqlite-lint-android-sdk", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-battery-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-hooks", version: MATRIX_VERSION, changing: true
  }

  apply plugin: "com.tencent.matrix-plugin"
  matrix {
    trace {
        enable = true	//if you don"t want to use trace canary, set false
        baseMethodMapFile = "${project.buildDir}/matrix_output/Debug.methodmap"
        blackListFile = "${project.projectDir}/matrixTrace/blackMethodList.txt"
    }
  }

1.4 實現 PluginListener,接收 Matrix 處理后的數據, 如:

class MatrixListener(context: Context?) : DefaultPluginListener(context) {
    companion object {
        const val TAG: String = "Matrix.TestPluginListener"
    }

    override fun onReportIssue(issue: Issue) {
        super.onReportIssue(issue)
        MatrixLog.e(TAG, issue.toString())

    }
}

1.5 實現動態配置接口, 可修改 Matrix 內部參數. 在 sample-android 中 我們有個簡單的動態接口實例DynamicConfigImplDemo.java, 其中參數對應的 key 位于文件 MatrixEnum中, 摘抄部分示例如下:

  class MatrixConfig : IDynamicConfig {
    val isFPSEnable: Boolean
        get() = true
    val isTraceEnable: Boolean
        get() = true
    val isMatrixEnable: Boolean
        get() = true

    override fun get(key: String, defStr: String): String {

        // for Activity leak detect
        if (ExptEnum.clicfg_matrix_resource_detect_interval_millis.name == key || ExptEnum.clicfg_matrix_resource_detect_interval_millis_bg.name == key) {
            Log.d(
                "DynamicConfig",
                "Matrix.ActivityRefWatcher: clicfg_matrix_resource_detect_interval_millis 10s"
            )
            return TimeUnit.SECONDS.toMillis(5).toString()
        }
        if (ExptEnum.clicfg_matrix_resource_max_detect_times.name == key) {
            Log.d(
                "DynamicConfig",
                "Matrix.ActivityRefWatcher: clicfg_matrix_resource_max_detect_times 5"
            )
            return 3.toString()
        }
        return defStr
    }

    override fun get(key: String, defInt: Int): Int {
        //TODO here return default value which is inside sdk, you can change it as you wish. matrix-sdk-key in class MatrixEnum.
        if (MatrixEnum.clicfg_matrix_resource_max_detect_times.name == key) {
            MatrixLog.i(TAG, "key:$key, before change:$defInt, after change, value:2")
            return 2 //new value
        }
        if (MatrixEnum.clicfg_matrix_trace_fps_report_threshold.name == key) {
            return 10000
        }
        if (MatrixEnum.clicfg_matrix_trace_fps_time_slice.name == key) {
            return 12000
        }
        if (ExptEnum.clicfg_matrix_trace_app_start_up_threshold.name == key) {
            return 3000
        }
        return if (ExptEnum.clicfg_matrix_trace_evil_method_threshold.name == key) {
            200
        } else defInt
    }

    override fun get(key: String, defLong: Long): Long {
        //TODO here return default value which is inside sdk, you can change it as you wish. matrix-sdk-key in class MatrixEnum.
        if (MatrixEnum.clicfg_matrix_trace_fps_report_threshold.name == key) {
            return 10000L
        }
        if (MatrixEnum.clicfg_matrix_resource_detect_interval_millis.name == key) {
            MatrixLog.i(TAG, "$key, before change:$defLong, after change, value:2000")
            return 2000
        }
        return defLong
    }

    override fun get(key: String, defBool: Boolean): Boolean {
        //TODO here return default value which is inside sdk, you can change it as you wish. matrix-sdk-key in class MatrixEnum.
        return defBool
    }

    override fun get(key: String, defFloat: Float): Float {
        //TODO here return default value which is inside sdk, you can change it as you wish. matrix-sdk-key in class MatrixEnum.
        return defFloat
    }

    companion object {
        private const val TAG = "Matrix.DynamicConfigImplDemo"
    }
}

1.6 選擇程序啟動的位置對 Matrix 進行初始化,如在 Application 的繼承類中, Init 核心邏輯如下:

  Matrix.Builder builder = new Matrix.Builder(application); // build matrix
  builder.patchListener(new TestPluginListener(this)); // add general pluginListener
  DynamicConfigImplDemo dynamicConfig = new DynamicConfigImplDemo(); // dynamic config
  
  // init plugin 
  IOCanaryPlugin ioCanaryPlugin = new IOCanaryPlugin(new IOConfig.Builder()
                    .dynamicConfig(dynamicConfig)
                    .build());
  //add to matrix               
  builder.plugin(ioCanaryPlugin);
  
  //init matrix
  Matrix.init(builder.build());

  // start plugin 
  ioCanaryPlugin.start();

2. 改造Application子類

2.1 模擬Application卡頓

private fun A() {
        B()
        H()
        L()
        SystemClock.sleep(800)
    }

    private fun B() {
        C()
        G()
        SystemClock.sleep(200)
    }

    private fun C() {
        D()
        E()
        F()
        SystemClock.sleep(100)
    }

    private fun D() {
        SystemClock.sleep(20)
    }

    private fun E() {
        SystemClock.sleep(20)
    }

    private fun F() {
        SystemClock.sleep(20)
    }

    private fun G() {
        SystemClock.sleep(20)
    }

    private fun H() {
        SystemClock.sleep(20)
        I()
        J()
        K()
    }

    private fun I() {
        SystemClock.sleep(20)
    }

    private fun J() {
        SystemClock.sleep(6)
    }

    private fun K() {
        SystemClock.sleep(10)
    }


    private fun L() {
        SystemClock.sleep(10000)
    }

2.2 Application.onCreate()調用卡頓方法

override fun onCreate() {
  A()
}

2.3 反射獲取ActivityThread的mHandler

override fun attachBaseContext(base: Context?) {
      super.attachBaseContext(base)
      println("zijiexiaozhan MyApp attachBaseContext")
      time1 = SystemClock.uptimeMillis()
      time3 = System.currentTimeMillis()

      try {
          val forName = Class.forName("android.app.ActivityThread")
          val field = forName.getDeclaredField("sCurrentActivityThread")
          field.isAccessible = true
          val activityThreadValue = field[forName]
          val mH = forName.getDeclaredField("mH")
          mH.isAccessible = true
          val handler = mH[activityThreadValue]
          mHandler = handler as Handler
      } catch (e: Exception) {
      }
}

2.4 將原來的onCreate的方法調用轉入匿名內部類調用

inner class ApplicationTask : Runnable {
    override fun run() {
        A()
    }
}

2.5 重寫Application onCreate方法

override fun onCreate() {
    super.onCreate()
    //重點
    mHandler.postAtFrontOfQueue(ApplicationTask())
}

3.運行,快速定位

3.1 關鍵字"Trace_EvilMethod"查找日志

tag[Trace_EvilMethod]type[0];key[null];content[{"machine":"MIDDLE","cpu_app":0,"mem":3822452736,"mem_free":1164132,"detail":"NORMAL","cost":1344,"usage":"0.37%","scene":"default","stack":"0,1048574,1,1344 1,5471,1,1338 2,17582,1,1338 3,17558,1,1338 4,17560,1,379 5,17562,1,160 6,17563,1,17 6,17566,1,20 6,17568,1,20 5,17569,1,20 4,17573,1,56 5,17575,1,21 5,17576,1,5 5,17578,1,10 4,17580,1,102 ","stackKey":"17558|","tag":"Trace_EvilMethod","process":"com.peter.viewgrouptutorial","time":1624837969986}]

3.2 解析日志 打印卡頓堆棧

android.os.Handler dispatchMessage 1344
.com.peter.viewgrouptutorial.MyApp$ApplicationTask run 1338
..com.peter.viewgrouptutorial.MyApp access$A 1338
...com.peter.viewgrouptutorial.MyApp A 1338
....com.peter.viewgrouptutorial.MyApp B 379
.....com.peter.viewgrouptutorial.MyApp C 160
......com.peter.viewgrouptutorial.MyApp D 17
......com.peter.viewgrouptutorial.MyApp E 20
......com.peter.viewgrouptutorial.MyApp F 20
.....com.peter.viewgrouptutorial.MyApp G 20
....com.peter.viewgrouptutorial.MyApp H 56
.....com.peter.viewgrouptutorial.MyApp I 21
.....com.peter.viewgrouptutorial.MyApp J 5
.....com.peter.viewgrouptutorial.MyApp K 10
....com.peter.viewgrouptutorial.MyApp L 102

到此,相信大家對“如何快速定位Android啟動耗時問題”有了更深的了解,不妨來實際操作一番吧!這里是創新互聯網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

網站題目:如何快速定位Android啟動耗時問題
鏈接地址:http://www.js-pz168.com/article40/pojceo.html

成都網站建設公司_創新互聯,為您提供App開發電子商務手機網站建設營銷型網站建設網頁設計公司關鍵詞優化

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都app開發公司
久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx
日本在线观看一区二区三区| 欧美日本韩国一区| 欧美一级搡bbbb搡bbbb| 国产三级久久久| 午夜精品久久久久| 高清不卡在线观看av| 精品久久一区二区三区蜜桃| 色婷婷亚洲精品| 精品av久久707| 一区二区视频在线| 国产另类ts人妖一区二区| 高清国产在线一区| 91国产成人在线| 国产欧美一区二区精品性色| 天天色天天操综合| 91麻豆免费观看| 亚洲欧美日韩另类精品一区二区三区 | 欧美一卡二卡在线观看| 亚洲欧美在线观看| 韩国女主播成人在线| 国产乱码精品一区二区三区中文 | 日韩精品一区二区三区在线播放 | 日韩精品中午字幕| 亚洲综合999| bt7086福利一区国产| 一级日韩一区在线观看| 久久婷婷综合激情| 日日欢夜夜爽一区| 97碰碰视频| 精品视频123区在线观看| 亚洲欧洲国产日韩| 国产91在线看| 亚洲国产日韩综合一区| 久久精品亚洲乱码伦伦中文| 免费在线观看成人| 精品在线视频一区二区| 欧美一级国产精品| 婷婷久久综合九色国产成人| 岛国视频一区免费观看| 欧美日韩国产精品自在自线| 一区二区三区高清| 99久久国产综合色|国产精品| 中文字幕免费在线不卡| 国产拍揄自揄精品视频麻豆| 国产一区二区影院| 天堂av一区二区| 国产三级精品三级| 国产精品一区二区在线观看不卡| 免费看污久久久| 久久久久亚洲蜜桃| 韩国欧美国产1区| 亚洲一区二区三区乱码| 国产精品免费免费| 成人性生交大片免费看中文网站| 在线一区高清| 亚洲日本va午夜在线影院| 成年人网站91| 欧美日韩成人综合在线一区二区| 午夜激情一区二区| 美女亚洲精品| 久久精品一二三| 国产成人夜色高潮福利影视| 色综合中文字幕| 一区二区三区在线观看欧美| 成人精品一二区| 日韩情涩欧美日韩视频| 久久99这里只有精品| 亚洲国产欧美日韩| 亚洲视频在线一区观看| av蓝导航精品导航| 精品播放一区二区| 国产大陆a不卡| 欧美日韩一级黄| 日韩不卡一二三区| 日韩精品一区二区三区色偷偷| 国产精品每日更新在线播放网址| jizzjizzjizz欧美| 欧美一级二级三级蜜桃| 精品影视av免费| 欧洲国产伦久久久久久久| 天堂成人国产精品一区| 色综合影院在线观看| 亚洲乱码国产乱码精品精98午夜| 国产另类自拍| 国产欧美一区二区精品性| 99精品欧美一区二区蜜桃免费 | 国产经典欧美精品| 欧美日本国产视频| 久久精品国产久精国产爱| 一本一道综合狠狠老| 亚洲chinese男男1069| 日韩精品久久久| 亚洲午夜在线观看视频在线| 欧美日韩喷水| 亚洲女人小视频在线观看| 精品日本一区二区三区| 国产精品福利影院| 极品校花啪啪激情久久| 国产精品久久久久久亚洲伦 | 极品少妇xxxx精品少妇偷拍 | 欧美精品一区二区三区四区| 国产91综合网| 欧美成人乱码一区二区三区| 成人一区二区在线观看| 日韩一区二区在线观看视频| 国产精品一区2区| 欧美一区二区久久久| 国产成人亚洲综合a∨婷婷图片| 91精品国产免费| 成人免费视频一区| 欧美精品一区视频| 91蜜桃网站免费观看| 国产欧美日韩在线观看| 国产精品制服诱惑| 亚洲人成伊人成综合网小说| 欧美视频小说| 亚洲不卡在线观看| 日本韩国一区二区三区| 久久66热re国产| 666欧美在线视频| 成人动漫一区二区| 国产午夜精品美女毛片视频| 国产精品一区二区a| 亚洲免费高清视频在线| 日本一区免费观看| 日韩成人免费看| 欧美日韩国产高清一区二区| 国产电影一区在线| 久久精品一区二区三区四区| 国产一区二区三区高清视频| 亚洲精品国产一区二区精华液| 三区精品视频| 美国欧美日韩国产在线播放| 在线电影院国产精品| av午夜精品一区二区三区| 中文字幕不卡在线观看| 美乳视频一区二区| 日本中文在线一区| 91精品黄色片免费大全| 91精品久久香蕉国产线看观看| 国产精品久久免费看| 五月天久久综合网| 激情六月婷婷综合| 欧美精品一区视频| 久久精品二区| 婷婷夜色潮精品综合在线| 欧美日韩电影在线| 91老师国产黑色丝袜在线| 亚洲日本中文字幕区| 最新国产精品久久| 丁香婷婷综合网| 国产精品久久久久久久久久免费看| 日韩av一区二区三区在线观看| 久久疯狂做爰流白浆xx| 精品1区2区在线观看| 欧美xxxx黑人又粗又长精品| 青青青爽久久午夜综合久久午夜| 日韩一区二区精品葵司在线| 国产精品日韩一区二区| 丝袜国产日韩另类美女| 日韩视频123| 久久久亚洲综合网站| 免费看欧美女人艹b| 精品国产自在久精品国产| 九九99玖玖| 久久成人综合网| 国产欧美1区2区3区| 亚洲三区在线| 成人免费视频国产在线观看| 亚洲人精品一区| 欧美图片一区二区三区| 91麻豆精品在线观看| 亚洲高清不卡在线| 日韩欧美精品三级| 欧美日本亚洲| 国产乱对白刺激视频不卡| 国产精品国产三级国产普通话蜜臀| 色综合天天综合网天天狠天天 | 日韩欧美一级二级| 欧美h视频在线| 国模冰冰炮一区二区| 中文乱码免费一区二区| 在线亚洲一区二区| 99电影网电视剧在线观看| 日韩专区在线视频| 久久综合国产精品| 亚洲成人蜜桃| 99麻豆久久久国产精品免费| 亚洲国产精品自拍| 亚洲精品一区二区三区蜜桃下载 | 国产精品初高中精品久久| 蜜臀av国产精品久久久久| 国产亚洲女人久久久久毛片| 色婷婷国产精品| www.成人av.com| 99国产在线| 91中文字精品一区二区| 青青青伊人色综合久久| 国产亚洲欧美激情| 欧美视频精品在线观看|