didi / droidassist Goto Github PK
View Code? Open in Web Editor NEWA lightweight Android Studio gradle plugin based on Javassist for editing bytecode in Android.
License: Apache License 2.0
A lightweight Android Studio gradle plugin based on Javassist for editing bytecode in Android.
License: Apache License 2.0
将
private void test2(){
test3();
}
替换为
private void test2(){
test4();
}
FieldRead,InitializerExecution,都是过了,都是 类的static String变量可以替换,但是static final String就不行。
<Replace>
<MethodExecution>
<Source>
void okhttp3.internal.ws.RealWebSocket.initReaderAndWriter(java.lang.String,okhttp3.internal.ws.RealWebSocket$Streams)
</Source>
<Target>
{
val extensions = this.extensions!!;
}
</Target>
<Filter>
<Include>okhttp3.internal.ws.RealWebSocket</Include>
</Filter>
</MethodExecution>
</Replace>
Transform failed for class: okhttp3.internal.ws.RealWebSocket with compile error: ; is missing
另外问下生成的文件在哪里呢?
private String getApp_ConfigSpPath() { String spPath = App.getInstance().getDir("config", Context.MODE_PRIVATE).getAbsolutePath(); StringBuilder pathBuilder = new StringBuilder(spPath); if (!spPath.endsWith("/")) { pathBuilder.append('/'); } pathBuilder.append(App.getInstance().getPackageName()).append("_preferences.xml"); Log.d(TAG, String.format("getApp_ConfigSpPath path: %s", pathBuilder)); return pathBuilder.toString(); }
这样的代码被扫描到后,插件就报错
比如
Object lock = new Object();
synchronized(lock){
a = 1;
}
改成
Object lock = new Object();
a = 1;
/
if a class is changed and don't need to be modified by javassist,the class will miss in dex
插入代码不成功...是不是和这个类是抽象类且带泛型参数有关
<BeforeMethodCall>
<Source>void com.didichuxing.tools.test.MainActivity.onCreate(android.os.Binder)</Source>
<Target>{java.lang.System.out.println("成功");}</Target>
</BeforeMethodCall>
我想修改 Glide库里的GifFrameLoader.getWidth()方法,配置是下面这样的
<DroidAssist> <Global> <Filter> <Include>*</Include> </Filter> </Global> <Insert> <BeforeMethodExecution> <Source>int com.bumptech.glide.load.resource.gif.GifFrameLoader.getWidth()</Source> <Target>System.out.println("BeforeMethodCall");</Target> </BeforeMethodExecution> </Insert> </DroidAssist>
在GifFrameLoader.getWidth方法体内,第一行加上代码,反编译出来还是没变,这是为什么,麻烦帮我分析一下
How this compare to lancet https://github.com/eleme/lancet
下面是配置文件
<Replace>
<MethodCall>
<Source>void android.view.View.setOnClickListener(android.view.View$OnClickListener)
</Source>
<Target>org.example.datacoll.ListenerUtil.setOnClickListener($0,$1);</Target>
<Filter>
<Include>*</Include>
<Exclude>org.example.datacoll.ListenerUtil</Exclude>
</Filter>
</MethodCall>
</Replace>
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.6'
编译时报下面的错误
/Users/liyuanbiao/projects/DataColl/app/build/intermediates/transforms/droidAssist/debug/30.jar: D8: Type leakcanary.internal.activity.screen.HprofExplorerScreen$createView$$inlined$apply$lambda$1$1 is defined multiple times: /Users/liyuanbiao/projects/DataColl/app/build/intermediates/transforms/droidAssist/debug/30.jar:leakcanary/internal/activity/screen/HprofExplorerScreen$createView$$inlined$apply$lambda$1$1.class, /Users/liyuanbiao/projects/DataColl/app/build/intermediates/transforms/droidAssist/debug/30.jar:leakcanary/internal/activity/screen/HprofExplorerScreen$createView$$inlined$apply$lambda$1$1.class
org.gradle.workers.WorkerExecutionException: There was a failure while executing work items
第一次用,android studio 4.1.1 添加写了一个方法体执行前插入,然后编译的时候一直卡在Task :app:transformClassesWithDroidAssistForRelease 过不去,不知道什么原因!
增加level 1配置也没看到什么错误日志, 这个要如何排错?把Insert删除用空配置是可以编译的,仔细确认我的配置也没错呀,然后版本太新兼容性问题?
Source = void com.geetest.onelogin.f.c.a(com.geetest.onelogin.config.OneLoginThemeConfig, com.geetest.onelogin.listener.AbstractOneLoginListener)
Target = android.util.Log.d("jay","test");
Caused by: java.io.IOException: Could not create empty folder D:\AndroidStudioProjects\LifeCycleLiveData\app\build\tmp\transformClassesWithDroidAssistForRelease\jar\com.android.support:design:28.0.0
at com.android.utils.FileUtils.cleanOutputDir(FileUtils.java:95)
at com.android.utils.FileUtils$cleanOutputDir.callStatic(Unknown Source)
at com.didichuxing.tools.droidassist.tasks.InputTask.ensureTemporaryDir(InputTask.groovy:66)
at com.didichuxing.tools.droidassist.tasks.InputTask.(InputTask.groovy:44)
at com.didichuxing.tools.droidassist.tasks.JarInputTask.(JarInputTask.groovy:18)
帮忙看看是什么原因
DroidAssist: Build failed with an exception: Transform failed for class: com.xx.WebViewTest with error: [source error] no such class: com.xx.xxHook com.didichuxi
ng.tools.droidassist.ex.DroidAssistException: com.didichuxing.tools.droidassist.ex.DroidAssistException: Transform failed for class: com.xx.WebViewTest with error: [source error] no such class: com.xx.xxHook
网上说ClassPath添加ClassPool中, 请问这块代码如何使用
如下代码:
Model model = new Model();ClassPool pool = ClassPool.getDefault();ClassClassPath ccpath = new ClassClassPath(model.getClass());pool.insertClassPath(ccpath);CtClass ctClass = pool.get("com.project.Model");
希望替换掉实例方法,这样可行么?
按照文档配置 replace 节点后编译报错,看起来是只能替换静态方法的调用
Caused by: javassist.CannotCompileException: [source error] setTextColor is not static
at javassist.expr.MethodCall.replace(MethodCall.java:257)
at com.didichuxing.tools.droidassist.transform.SourceTargetTransformer.replaceInstrument(SourceTargetTransformer.java:270)
... 102 more
Caused by: compile error: setTextColor is not static
at javassist.compiler.MemberCodeGen.atMethodCallCore2(MemberCodeGen.java:689)
at javassist.compiler.MemberCodeGen.atMethodCallCore(MemberCodeGen.java:618)
at javassist.compiler.MemberCodeGen.atCallExpr(MemberCodeGen.java:568)
at javassist.compiler.JvstCodeGen.atCallExpr(JvstCodeGen.java:261)
at javassist.compiler.ast.CallExpr.accept(CallExpr.java:49)
at javassist.compiler.CodeGen.atAssignCore(CodeGen.java:908)
at javassist.compiler.CodeGen.atVariableAssign(CodeGen.java:841)
at javassist.compiler.CodeGen.atAssignExpr(CodeGen.java:795)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:362)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:53)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:381)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:53)
at javassist.compiler.Javac.compileStmnt(Javac.java:578)
at javassist.expr.MethodCall.replace(MethodCall.java:251)
... 103 more
报这个错
I wan to insert a log in activity onCreate(), but it has some error, please help to check, Thanks.
QuickActivity is a abstract class that extends Activity.
And my log in xml:
ErrorLog:
DroidAssist: Build failed with an exception: Transform failed for class: com.example.camera.util.QuickActivity with compile error: ) is missing com.didichuxing.tools.droidassist.ex.DroidAssistBadStatementException: com.didichuxing.tools.droidassist.ex.DroidAssistBadStatementException: Transform failed for class: com.example.camera.util.QuickActivity with compile error: ) is missing
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:593)
at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677)
at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:735)
at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at sun.reflect.GeneratedMethodAccessor1262.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSiteNoUnwrap.invoke(PojoMetaMethodSite.java:213)
at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at com.didichuxing.tools.droidassist.DroidAssistExecutor.execute(DroidAssistExecutor.groovy:47)
at com.didichuxing.tools.droidassist.DroidAssistExecutor$execute.call(Unknown Source)
at com.didichuxing.tools.droidassist.DroidAssistTransform.onTransform(DroidAssistTransform.groovy:160)
at com.didichuxing.tools.droidassist.DroidAssistTransform$onTransform.callCurrent(Unknown Source)
at com.didichuxing.tools.droidassist.DroidAssistTransform.transform(DroidAssistTransform.groovy:84)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:222)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:218)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:102)
at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:213)
at sun.reflect.GeneratedMethodAccessor1437.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:46)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:121)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:110)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:97)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:87)
at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:626)
at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:581)
at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:748)
您好, 请问可以替换第三方库里的某一个类吗
设备信息
项目信息
xml内容
<DroidAssist>
<Global>
<Filter>
<Include>*</Include>
</Filter>
</Global>
<Insert>
<BeforeMethodExecution>
<Source>
void android.view.View$OnClickListener.onClick(android.view.View)
</Source>
<Target>
com.demo.aop.ClickAop.onClick($1);
</Target>
</BeforeMethodExecution>
</Insert>
</DroidAssist>
现象:
调用View的setOnClickListener方法
传入一个对象: onClick方法调用的时候会执行com.demo.aop.ClickAop.onClick
传入一个lambda表达式, onClick方法调用的时候不会执行com.demo.aop.ClickAop.onClick
((RequestBuilder)Glide.with(v.getContext()).asGif().diskCacheStrategy(DiskCacheStrategy.RESOURCE)).load(uri.getPath()).listener(new RequestListener() {
public boolean onLoadFailed(@nullable GlideException e, Object model, Target target, boolean isFirstResource) {
return false;
}
public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
}).into(holder.img);
我想把jar包里的上述待代码里的asGif().去掉,就这么简单,如何实现
在编译的过程中,碰到一个异常:
`
FAILURE: Build failed with an exception.
com.didichuxing.tools.droidassist.ex.DroidAssistException: Transform failed for class: com.didichuxing.tools.test.MainActivity with error: the resulting value is not stored in $_
Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
Get more help at https://help.gradle.org
BUILD FAILED in 6s`
请问这样如果解决?
升级了agp8.0,由于8.0移除了Transform api导致DroidAssist无法运行
例如,可以把import a.a.a替换成import a.a.b吗?
配置如下:
<Replace>
<MethodCall>
<Source>
void com.arialyy.aria.core.download.downloader.Downloader.onPostPre()
</Source>
<Target>
$_= com.arialyy.aria.core.download.downloader.DownloaderFixed.onPostPre();
</Target>
</MethodCall>
</Replace>
结果并没有替换成功.
如果我需要替换的方法是抛异常的,那么就无法替换,或者插入log等。
比如我想创建文件方法前后添加log
方法如下
public boolean createNewFile() throws IOException {
SecurityManager security = System.getSecurityManager();
if (security != null) security.checkWrite(path);
if (isInvalid()) {
throw new IOException("Invalid file path");
}
return fs.createFileExclusively(path);
}
此时xml配置这样写
发现无效。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.