电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

一分鐘快速定位Android啟動耗時問題

瀏覽:5日期:2022-09-17 15:58:59
目錄前言1. 接入Tencent Matrix2. 改造Application子類3.運行,快速定位總結(jié)前言

Tencent Matrix默認無法監(jiān)測Application冷啟動的耗時方法,本文介紹了如何改造Matrix支持冷啟動耗時方法監(jiān)測。讓你一分鐘就能給App啟動卡頓號脈。

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 falsebaseMethodMapFile = '${project.buildDir}/matrix_output/Debug.methodmap'blackListFile = '${project.projectDir}/matrixTrace/blackMethodList.txt' } }

1.4 實現(xiàn) PluginListener,接收 Matrix 處理后的數(shù)據(jù), 如:

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 實現(xiàn)動態(tài)配置接口, 可修改 Matrix 內(nèi)部參數(shù). 在 sample-android 中 我們有個簡單的動態(tài)接口實例DynamicConfigImplDemo.java, 其中參數(shù)對應的 key 位于文件 MatrixEnum中, 摘抄部分示例如下:

class MatrixConfig : IDynamicConfig { val isFPSEnable: Booleanget() = true val isTraceEnable: Booleanget() = true val isMatrixEnable: Booleanget() = true override fun get(key: String, defStr: String): String {// for Activity leak detectif (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()調(diào)用卡頓方法

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的方法調(diào)用轉(zhuǎn)入匿名內(nèi)部類調(diào)用

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

2.5 重寫Application onCreate方法

override fun onCreate() { super.onCreate() //重點 mHandler.postAtFrontOfQueue(ApplicationTask())}3.運行,快速定位

3.1 關(guān)鍵字'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,1344n1,5471,1,1338n2,17582,1,1338n3,17558,1,1338n4,17560,1,379n5,17562,1,160n6,17563,1,17n6,17566,1,20n6,17568,1,20n5,17569,1,20n4,17573,1,56n5,17575,1,21n5,17576,1,5n5,17578,1,10n4,17580,1,102n','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

總結(jié)

到此這篇關(guān)于快速定位Android啟動耗時問題的文章就介紹到這了,更多相關(guān)定位Android啟動耗時內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Android
相關(guān)文章:
主站蜘蛛池模板: 一路商机网-品牌招商加盟优选平台-加盟店排行榜平台 | 北京自然绿环境科技发展有限公司专业生产【洗车机_加油站洗车机-全自动洗车机】 | 科威信洗净科技,碳氢清洗机,超声波清洗机,真空碳氢清洗机 | 品牌策划-品牌设计-济南之式传媒广告有限公司官网-提供品牌整合丨影视创意丨公关活动丨数字营销丨自媒体运营丨数字营销 | 大行程影像测量仪-探针型影像测量仪-增强型影像测量仪|首丰百科 大通天成企业资质代办_承装修试电力设施许可证_增值电信业务经营许可证_无人机运营合格证_广播电视节目制作许可证 | 招商帮-一站式网络营销服务|搜索营销推广|信息流推广|短视视频营销推广|互联网整合营销|网络推广代运营|招商帮企业招商好帮手 | 紧急泄压人孔_防爆阻火器_阻火呼吸阀[河北宏泽石化] | 分子精馏/精馏设备生产厂家-分子蒸馏工艺实验-新诺舜尧(天津)化工设备有限公司 | lcd条形屏-液晶长条屏-户外广告屏-条形智能显示屏-深圳市条形智能电子有限公司 | TTCMS自助建站_网站建设_自助建站_免费网站_免费建站_天天向上旗下品牌 | 精密机械零件加工_CNC加工_精密加工_数控车床加工_精密机械加工_机械零部件加工厂 | [官网]叛逆孩子管教_戒网瘾学校_全封闭问题青少年素质教育_新起点青少年特训学校 | 建筑消防设施检测系统检测箱-电梯**检测仪器箱-北京宇成伟业科技有限责任公司 | 啤酒设备-小型啤酒设备-啤酒厂设备-济南中酿机械设备有限公司 | 滚筒烘干机_转筒烘干机_滚筒干燥机_转筒干燥机_回转烘干机_回转干燥机-设备生产厂家 | 缓蚀除垢剂_循环水阻垢剂_反渗透锅炉阻垢剂_有机硫化物-郑州威大水处理材料有限公司 | 邢台人才网_邢台招聘网_邢台123招聘【智达人才网】 | 运动木地板厂家,篮球场木地板品牌,体育场馆木地板安装 - 欧氏运动地板 | 电缆隧道在线监测-智慧配电站房-升压站在线监测-江苏久创电气科技有限公司 | 重庆钣金加工厂家首页-专业定做监控电视墙_操作台 | AGV无人叉车_激光叉车AGV_仓储AGV小车_AGV无人搬运车-南昌IKV机器人有限公司[官网] | 真空粉体取样阀,电动楔式闸阀,电动针型阀-耐苛尔(上海)自动化仪表有限公司 | 全自动不干胶贴标机_套标机-上海今昂贴标机生产厂家 | 冰雕-冰雪世界-大型冰雕展制作公司-赛北冰雕官网 | hdpe土工膜-防渗膜-复合土工膜-长丝土工布价格-厂家直销「恒阳新材料」-山东恒阳新材料有限公司 ETFE膜结构_PTFE膜结构_空间钢结构_膜结构_张拉膜_浙江萬豪空间结构集团有限公司 | 广州工业氧气-工业氩气-工业氮气-二氧化碳-广州市番禺区得力气体经营部 | 短信通106短信接口验证码接口群发平台_国际短信接口验证码接口群发平台-速度网络有限公司 | 吹塑加工_大型吹塑加工_滚塑代加工-莱力奇吹塑加工有限公司 | 示波器高压差分探头-国产电流探头厂家-南京桑润斯电子科技有限公司 | 叉车电池-叉车电瓶-叉车蓄电池-铅酸蓄电池-电动叉车蓄电池生产厂家 | 刺绳_刀片刺网_刺丝滚笼_不锈钢刺绳生产厂家_安平县浩荣金属丝网制品有限公司-安平县浩荣金属丝网制品有限公司 | 冷热冲击试验箱_温度冲击试验箱价格_冷热冲击箱排名_林频厂家 | 水质监测站_水质在线分析仪_水质自动监测系统_多参数水质在线监测仪_水质传感器-山东万象环境科技有限公司 | 柔性测斜仪_滑动测斜仪-广州杰芯科技有限公司 | 洁净实验室工程-成都手术室净化-无尘车间装修-四川华锐净化公司-洁净室专业厂家 | 移动厕所租赁|移动卫生间|上海移动厕所租赁-家瑞租赁 | 公交驾校-北京公交驾校欢迎您! 工作心得_读书心得_学习心得_找心得体会范文就上学道文库 | 智慧物联网行业一站式解决方案提供商-北京东成基业 | 河北凯普威医疗器材有限公司,高档轮椅系列,推车系列,座厕椅系列,协步椅系列,拐扙系列,卫浴系列 | 成都顶呱呱信息技术有限公司-贷款_个人贷款_银行贷款在线申请 - 成都贷款公司 | 上海小程序开发-上海小程序制作公司-上海网站建设-公众号开发运营-软件外包公司-咏熠科技 |