一步一步来实现简单安卓性能监控之ANT打包方式

ProcessBuilder的改写逻辑

<pre>
private static ClassAdapter createProcessBuilderClassAdapter(final ClassVisitor cw, final Log log) {
return new ClassAdapter(cw) {
@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
if (START_METHOD_NAME.equals(name)) {
mv = new SkipInstrumentedMethodsMethodVisitor(new BaseMethodVisitor(mv, access, name, desc) {
@Override
protected void onMethodEnter() {
this.builder.loadInvocationDispatcher().loadInvocationDispatcherKey(getProxyInvocationKey(PROCESS_BUILDER_CLASS_NAME, this.methodName)).loadArray(new Runnable() {
@Override
public void run() {
loadThis();
invokeVirtual(Type.getObjectType(PROCESS_BUILDER_CLASS_NAME), new Method("command", "()Ljava/util/List;"));
}
}).invokeDispatcher();
}
});
}
return mv;
}
};
}
</pre>

ProcessBuilder的start方法,被改成了如下(我格式化了)

ProcessBuilder.png

ProcessBuilder的start方法都被谁调用了?

也就是,调用processBuilder的start每次进程开启都做了啥
<pre>
691599399962749==>Bootstrapping agent args:logfile=workspace\aaa.txt;tttt=true
691600686737811==>Execute: [sdk\build-tools\25.0.1\aapt.exe, package, -f, -m, -0, apk, -M, workspace\bin\AndroidManifest.xml, -S, workspace\bin\res, -S, workspace\res, -I, sdk\platforms\android-19\android.jar, -J, workspace\gen, --generate-dependencies, -G, workspace\bin\proguard.txt]

691602027570542==>Execute: [sdk\build-tools\25.0.1\dx.bat, "-Jjavaagent:test-project\target\test-agentr=logfile=workspace\aaa.txt;tttt=true", --dex, --output, workspace\bin\dexedLibs\my-android-agent-efcafcfe1a4983df70fb48bca863819c.jar, workspace\libs\my-android-agent.jar]

691602351193570==>Bootstrapping agent args:logfile=workspace\aaa.txt;tttt=true
691604575500820==>Execute: [sdk\build-tools\25.0.1\dx.bat, "-Jjavaagent:test-project\target\test-agentr=logfile=workspace\aaa.txt;tttt=true", --dex, --output, workspace\bin\dexedLibs\fastjson-1.1.26-android-efaf839430a0a7a8394d7d55b0c392d1.jar, workspace\libs\fastjson-1.1.26-android.jar]

691604872029960==>Bootstrapping agent args:logfile=workspace\aaa.txt;tttt=true
691606526309021==>Execute: [sdk\build-tools\25.0.1\dx.bat, "-Jjavaagent:test-project\target\test-agentr=logfile=workspace\aaa.txt;tttt=true", --dex, --output, workspace\bin\dexedLibs\crittercism_v4_5_4_sdkonly-7db8d0f7a9e72de80599a5cf97e7d1fd.jar, workspace\libs\crittercism_v4_5_4_sdkonly.jar]

691606827791573==>Bootstrapping agent args:logfile=workspace\aaa.txt;tttt=true
691608129313368==>Execute: [sdk\build-tools\25.0.1\dx.bat, "-Jjavaagent:test-project\target\test-agentr=logfile=workspace\aaa.txt;tttt=true", --dex, --output, workspace\bin\dexedLibs\locSDK_3.3-4a69856b79665c8024bbe9255dc0a123.jar, workspace\libs\locSDK_3.3.jar]

691608414309803==>Bootstrapping agent args:logfile=workspace\aaa.txt;tttt=true
691609530548205==>Execute: [sdk\build-tools\25.0.1\dx.bat, "-Jjavaagent:test-project\target\test-agentr=logfile=workspace\aaa.txt;tttt=true", --dex, --output, workspace\bin\classes.dex, workspace\bin\classes, workspace\bin\dexedLibs\my-android-agent-efcafcfe1a4983df70fb48bca863819c.jar, workspace\bin\dexedLibs\fastjson-1.1.26-android-efaf839430a0a7a8394d7d55b0c392d1.jar, workspace\bin\dexedLibs\crittercism_v4_5_4_sdkonly-7db8d0f7a9e72de80599a5cf97e7d1fd.jar, workspace\bin\dexedLibs\locSDK_3.3-4a69856b79665c8024bbe9255dc0a123.jar]

691609830571207==>Bootstrapping agent args:logfile=workspace\aaa.txt;tttt=true
691611183745961==>Execute: [sdk\build-tools\25.0.1\aapt.exe, crunch, -v, -S, workspace\res, -C, workspace\bin\res]

691611841932449==>Execute: [sdk\build-tools\25.0.1\aapt.exe, package, --no-crunch, -f, --debug-mode, -0, apk, -M, workspace\bin\AndroidManifest.xml, -S, workspace\bin\res, -S, workspace\res, -I, sdk\platforms\android-19\android.jar, -F, workspace\bin\SplashActivity.ap_, --generate-dependencies]

691612245238729==>Execute: [sdk\build-tools\25.0.1\zipalign.exe, -f, 4, workspace\bin\SplashActivity-debug-unaligned.apk, workspace\bin\SplashActivity-debug.apk]
</pre>

分析

类似这个格式:691599399962749==>Bootstrapping agent args:logfile=workspace\aaa.txt;tttt=true ,打印的时候是一个Key-Value结构前面使用的是system.nanoTime,后面是运行参数。

这一行的意思是:javaagent的启动参数是 logfile=workspace\aaa.txt;tttt=true ,这个是外界给javaagent传递给javaagent的参数。
需要启动javaagent的时候这样 -javaagent:/path/to/javaagent/agent.jar=logfile=workspace\aaa.txt;tttt=true

  • 下一行
    <pre>
    691600686737811==>Execute: [sdk\build-tools\25.0.1\aapt.exe, package, -f, -m, -0, apk, -M, workspace\bin\AndroidManifest.xml, -S, workspace\bin\res, -S, workspace\res, -I, sdk\platforms\android-19\android.jar, -J, workspace\gen, --generate-dependencies, -G, workspace\bin\proguard.txt]
    </pre>
    意思是,开启一个进程执行的命令参数是Execute后面的,也就是调用aapt命令处理资源
  • 往下
    <pre>
    691602027570542==>Execute: [sdk\build-tools\25.0.1\dx.bat, "-Jjavaagent:test-project\target\test-agentr=logfile=workspace\aaa.txt;tttt=true", --dex, --output, workspace\bin\dexedLibs\my-android-agent-efcafcfe1a4983df70fb48bca863819c.jar, workspace\libs\my-android-agent.jar]
    </pre>
    意思是,执行dx命令来处理 my-android-agent.jar 文件,这里要注意,这里添加了一个javaagent参数哦!!!这个javaagent参数正式我们第一次启动javaagent的时候传递进来的。这里又被传到了子进程里面了。

再接着的几个都是调用dx命令处理jar文件为dalvik 能识别的格式!
最后调用aapt处理png的图片压缩,调用zipalign处理apk文件的对齐等!

就不写了,注意,这里的每一个命令都是在单独的进程执行的!

DexExecTask改写逻辑

<pre>
private static ClassAdapter createAntTaskClassAdapter(final ClassVisitor cw, final Log log) {
final Map<Method, MethodVisitorFactory> methodVisitors = new HashMap<Method, MethodVisitorFactory>() {
{

            put(new Method(PRE_DEX_LIBRARIES_METHOD_NAME, "(Ljava/util/List;)V"), new MethodVisitorFactory() {
                @Override
                public MethodVisitor create(final MethodVisitor mv, final int access, final String name, final String desc) {
                    return new BaseMethodVisitor(mv, access, name, desc) {
                        @Override
                        protected void onMethodEnter() {
                            this.builder.loadInvocationDispatcher().loadInvocationDispatcherKey(getProxyInvocationKey(ANT_DEX_EXEC_TASK, this.methodName))
                                    .loadArray(new Runnable() {
                                        @Override
                                        public void run() {
                                            loadArg(0);
                                        }
                                    }).invokeDispatcher(false);
                            this.loadThis();
                            this.swap();
                            this.putField(Type.getObjectType(ANT_DEX_EXEC_TASK), "BlueWareAgentFile", Type.getType(Object.class));
                        }
                    };
                }
            });
            put(new Method("runDx", "(Ljava/util/Collection;Ljava/lang/String;Z)V"), new MethodVisitorFactory() {
                @Override
                public MethodVisitor create(final MethodVisitor mv, final int access, final String name, final String desc) {
                    return new SafeInstrumentationMethodVisitor(mv, access, name, desc) {
                        @Override
                        protected void onMethodEnter() {
                            this.builder.loadInvocationDispatcher().loadInvocationDispatcherKey(SET_INSTRUMENTATION_DISABLED_FLAG).loadArray(new Runnable() {
                                @Override
                                public void run() {
                                    loadThis();
                                    getField(Type.getObjectType(ANT_DEX_EXEC_TASK), "BlueWareAgentFile", Type.getType(Object.class));
                                }
                            }).invokeDispatcher();
                        }
                    };
                }
            });
        }
    };
    return new ClassAdapterBase(log, cw, methodVisitors) {
        @Override
        public void visitEnd() {
            super.visitEnd();
            this.visitField(2, "BlueWareAgentFile", Type.getType(Object.class).getDescriptor(), null, null);
        }
    };
}

</pre>

DexExecTask的preDexLibraries被改成了如下

插码preDexLibraries

DexExecTask的Rundx被改成了如下

rundx插码.png

com/android/dx/command/dexer/Main的processClass的改写逻辑

<pre>
private static ClassAdapter createDexerMainClassAdapter(final ClassVisitor cw, final Log log) {
return new ClassAdapterBase(log, cw, new HashMap<Method, MethodVisitorFactory>() {
{
put(new Method(PROCESS_CLASS_METHOD_NAME, "(Ljava/lang/String;[B)Z"), new MethodVisitorFactory() {
@Override
public MethodVisitor create(final MethodVisitor mv, final int access, final String name, final String desc) {
return new BaseMethodVisitor(mv, access, name, desc) {
@Override
protected void onMethodEnter() {
log.debug("Found onMethodEnter in processClass");
final String proxyInvocationKey = getProxyInvocationKey(DEXER_MAIN_CLASS_NAME, this.methodName);
this.builder.loadInvocationDispatcher().loadInvocationDispatcherKey(proxyInvocationKey).
loadArgumentsArray(this.methodDesc).invokeDispatcher(false);
this.checkCast(Type.getType(byte[].class));
this.storeArg(1);
}
};
}
});

        }
    });
}

</pre>

com/android/dx/command/dexer/Main的processClass被改成了

Paste_Image.png

结论

ANT_DEX_EXEC_TASK 这个任务,就没做什么核心的事情,它做的主要的事情是,

  • 检测依赖的jar包是否有我们指定的jar包的名字
  • 在rundex的时候,设置instrumentation是否可用

另外取消所有有关ANT_DEX_EXEC_TASK的任务,对打包以及插码没有任何影响

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容