In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-26 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article focuses on "how to quickly locate the time-consuming problem of Android startup", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to quickly locate the time-consuming problem of Android startup.
1. Access to Tencent Matrix
1.1 configure the Matrix version number to rely on in the gradle.properties in the root directory of your project, such as:
MATRIX_VERSION=1.0.0
1.2 add Matrix dependencies to the build.gradle file in the root directory of your project, such as:
Dependencies {classpath ("com.tencent.matrix:matrix-gradle-plugin:$ {MATRIX_VERSION}") {changing = true}}
1.3 add the dependencies of Matrix modules in the app/build.gradle file, such as:
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 {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 implement PluginListener to receive data processed by Matrix, such as:
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 to dynamically configure the interface and modify the internal parameters of Matrix. In sample-android, we have a simple dynamic interface instance DynamicConfigImplDemo.java, where the key corresponding to the parameters is located in the file MatrixEnum. The excerpt section is as follows:
Class MatrixConfig: IDynamicConfig {val isFPSEnable: Boolean get () = trueval isTraceEnable: Boolean get () = trueval 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 Select the location where the program starts to initialize Matrix. For example, in the inheritance class of Application, the core logic of Init is as follows:
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. Modification of Application subclass
2.1 simulate Application stutter
Private fun A () {B () H () L () SystemClock.sleep} 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 () calls the Catton method
Override fun onCreate () {A ()}
2.3Reflections to obtain mHandler of ActivityThread
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 = trueval activityThreadValue = field [forName] val mH = forName.getDeclaredField ( "mH") mH.isAccessible = trueval handler = mH [activityThreadValue] mHandler = handler as Handler} catch (e: Exception) {}}
2.4 transfer the original onCreate method call to anonymous inner class call
Inner class ApplicationTask: Runnable {override fun run () {A ()}}
2.5 override the Application onCreate method
Override fun onCreate () {super.onCreate () / / key mHandler.postAtFrontOfQueue (ApplicationTask ())} 3. Running, quick positioning
3.1 keyword "Trace_EvilMethod" to find the log
Tagged [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": "0mei 1048574, 1344, 1338, 17582, 17383, 17558, 1338, 1379, 17562, 17562, 1160, 17568, 17668, 120, 17568, 1756, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, and 556, 556, 556, 556, 556, 556, 556, and 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, and 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, and 556, respectively. "tag": "Trace_EvilMethod", "process": "com.peter.viewgrouptutorial", "time": 1624837969986}
3.2 parsing the log to print the Cotton stack
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
At this point, I believe you have a deeper understanding of "how to quickly locate the time-consuming problem of Android startup". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 243
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.