eleme / lancet Goto Github PK
View Code? Open in Web Editor NEWA lightweight and fast AOP framework for Android App and SDK developers
A lightweight and fast AOP framework for Android App and SDK developers
我最近用 WorkManager 1.0.1, 有一些crash需要hook下
@Proxy("run")
@TargetClass("androidx.work.impl.utils.ForceStopRunnable")
public void run() {
try {
Origin.callVoid();
} catch (Exception e) {
e.printStackTrace();
}
}
但是并没生效,请问是我哪里用的不对吗?
============= 源码 ===========
`package androidx.work.impl.utils;
import static android.app.AlarmManager.RTC_WAKEUP;
import static android.app.PendingIntent.FLAG_NO_CREATE;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static androidx.work.impl.model.WorkSpec.SCHEDULE_NOT_REQUESTED_YET;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
import android.support.annotation.VisibleForTesting;
import androidx.work.Logger;
import androidx.work.impl.Schedulers;
import androidx.work.impl.WorkDatabase;
import androidx.work.impl.WorkManagerImpl;
import androidx.work.impl.model.WorkSpec;
import androidx.work.impl.model.WorkSpecDao;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
WorkManager is restarted after an app was force stopped.
Alarms and Jobs get cancelled when an application is force-stopped. To reschedule, we
create a pending alarm that will not survive force stops.
@hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class ForceStopRunnable implements Runnable {
private static final String TAG = Logger.tagWithPrefix("ForceStopRunnable");
@VisibleForTesting
static final String ACTION_FORCE_STOP_RESCHEDULE = "ACTION_FORCE_STOP_RESCHEDULE";
// All our alarms are use request codes which are > 0.
private static final int ALARM_ID = -1;
private static final long TEN_YEARS = TimeUnit.DAYS.toMillis(10 * 365);
private final Context mContext;
private final WorkManagerImpl mWorkManager;
public ForceStopRunnable(@nonnull Context context, @nonnull WorkManagerImpl workManager) {
mContext = context.getApplicationContext();
mWorkManager = workManager;
}
@OverRide
public void run() {
if (shouldRescheduleWorkers()) {
Logger.get().debug(TAG, "Rescheduling Workers.");
mWorkManager.rescheduleEligibleWork();
// Mark the jobs as migrated.
mWorkManager.getPreferences().setNeedsReschedule(false);
} else if (isForceStopped()) {
Logger.get().debug(TAG, "Application was force-stopped, rescheduling.");
mWorkManager.rescheduleEligibleWork();
} else {
WorkDatabase workDatabase = mWorkManager.getWorkDatabase();
WorkSpecDao workSpecDao = workDatabase.workSpecDao();
try {
workDatabase.beginTransaction();
List workSpecs = workSpecDao.getEnqueuedWork();
if (workSpecs != null && !workSpecs.isEmpty()) {
Logger.get().debug(TAG, "Found unfinished work, scheduling it.");
// Mark every instance of unfinished work with
// SCHEDULE_NOT_REQUESTED_AT = -1 irrespective of its current state.
// This is because the application might have crashed previously and we should
// reschedule jobs that may have been running previously.
// Also there is a chance that an application crash, happened during
// onStartJob() and now no corresponding job now exists in JobScheduler.
// To solve this, we simply force-reschedule all unfinished work.
for (WorkSpec workSpec : workSpecs) {
workSpecDao.markWorkSpecScheduled(workSpec.id, SCHEDULE_NOT_REQUESTED_YET);
}
Schedulers.schedule(
mWorkManager.getConfiguration(),
workDatabase,
mWorkManager.getSchedulers());
}
workDatabase.setTransactionSuccessful();
} finally {
workDatabase.endTransaction();
}
Logger.get().debug(TAG, "Unfinished Workers exist, rescheduling.");
}
mWorkManager.onForceStopRunnableCompleted();
}
/**
/**
/**
/**
static void setAlarm(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Using FLAG_UPDATE_CURRENT, because we only ever want once instance of this alarm.
PendingIntent pendingIntent = getPendingIntent(context, FLAG_UPDATE_CURRENT);
long triggerAt = System.currentTimeMillis() + TEN_YEARS;
if (alarmManager != null) {
if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(RTC_WAKEUP, triggerAt, pendingIntent);
} else {
alarmManager.set(RTC_WAKEUP, triggerAt, pendingIntent);
}
}
}
/**
A {@link android.content.BroadcastReceiver} which takes care of recreating the
long lived alarm which helps track force stops for an application. This is the target of the
alarm set by ForceStopRunnable in {@link #setAlarm(Context)}.
@hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public static class BroadcastReceiver extends android.content.BroadcastReceiver {
private static final String TAG = Logger.tagWithPrefix("ForceStopRunnable$Rcvr");
@OverRide
public void onReceive(Context context, Intent intent) {
// Our alarm somehow got triggered, so make sure we reschedule it. This should really
// never happen because we set it so far in the future.
if (intent != null) {
String action = intent.getAction();
if (ACTION_FORCE_STOP_RESCHEDULE.equals(action)) {
Logger.get().verbose(
TAG,
"Rescheduling alarm that keeps track of force-stops.");
ForceStopRunnable.setAlarm(context);
}
}
}
}
`
·
如题, 另外请问支持module或者Library 工程中使用么?我记得AspectJ是不支持在Module或者Library中使用的。
请问lancet支持往类的初始化方法()注入字节码吗?
按照文档提供的子,hook 下log.i 没有生效,变以没问题,有人使用生效的吗
@TargetClass("androidx.appcompat.app.AppCompatActivity")
@Proxy("onDestroy")
public void onDestroy() {
Log.e("siyehua", "onDestroy");
Origin.callVoid();
}
如果不重写onDestroy(),则无效
public class Main2Activity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
setContentView(R.layout.activity_main2);
}
// @Override
// protected void onDestroy() {
// super.onDestroy();
// }
}
java.lang.RuntimeException: java.lang.RuntimeException
at me.ele.lancet.plugin.internal.context.ContextReader.accept(ContextReader.java:88)
at me.ele.lancet.plugin.internal.preprocess.PreClassAnalysis.fullyParse(PreClassAnalysis.java:94)
at me.ele.lancet.plugin.internal.preprocess.PreClassAnalysis.execute(PreClassAnalysis.java:76)
at me.ele.lancet.plugin.LancetTransform.transform(LancetTransform.java:110)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:239)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:235)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:106)
at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:230)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
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:103)
at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:46)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41)
at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$5.run(ExecuteActionsTaskExecuter.java:404)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:393)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:376)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:213)
at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$0(ExecuteStep.java:32)
at java.util.Optional.map(Optional.java:215)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:32)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:58)
at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:35)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:48)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:33)
at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:39)
at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:35)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:45)
at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:31)
at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:201)
at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:70)
at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:45)
at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)
at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:43)
at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:32)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:96)
at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:89)
at java.util.Optional.map(Optional.java:215)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:54)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:38)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:77)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:90)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:48)
at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:120)
at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionStateTaskExecuter.execute(ResolveBeforeExecutionStateTaskExecuter.java:75)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:62)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:108)
at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionOutputsTaskExecuter.execute(ResolveBeforeExecutionOutputsTaskExecuter.java:67)
at org.gradle.api.internal.tasks.execution.ResolveAfterPreviousExecutionStateTaskExecuter.execute(ResolveAfterPreviousExecutionStateTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:94)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:95)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:49)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
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)
Caused by: java.lang.RuntimeException
at org.objectweb.asm.ClassVisitor.visitModule(ClassVisitor.java:148)
at org.objectweb.asm.ClassReader.readModule(ClassReader.java:731)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:632)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
at me.ele.lancet.plugin.internal.preprocess.AsmClassProcessorImpl.process(AsmClassProcessorImpl.java:15)
at me.ele.lancet.plugin.internal.preprocess.PreClassAnalysis$PreAnalysisClassFetcher.onClassFetch(PreClassAnalysis.java:127)
at me.ele.lancet.plugin.internal.context.JarContentProvider.forActualInput(JarContentProvider.java:34)
at me.ele.lancet.plugin.internal.context.JarContentProvider.forEach(JarContentProvider.java:22)
at me.ele.lancet.plugin.internal.context.ClassifiedContentProvider.forEach(ClassifiedContentProvider.java:29)
at me.ele.lancet.plugin.internal.context.ContextReader$QualifiedContentTask.call(ContextReader.java:131)
at me.ele.lancet.plugin.internal.context.ContextReader$QualifiedContentTask.call(ContextReader.java:119)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
... 1 more
lancet支持在应用中hook ActivityManagerService中的方法吗,比如
@Proxy("handleApplicationCrash")
@TargetClass("com.android.server.am.ActivityManagerService ")
public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo){
Log.v("handleApplicationCrash", JSON.toJSONString(crashInfo));
Origin.callVoid();
}
代码见 https://github.com/liujianAndroid/lancet
使用方式如下
repositories {
mavenCentral()
}
classpath 'com.bytedance.tools.lancet:lancet-plugin-asm6:1.0.0'
看readMe介绍里说,Proxy里不可以用This.get(),但我试了下,是可以的,请问是添加支持了吗?
版本:'me.ele:lancet-base:1.0.5'
如下:This.get()是可以获取到View的
@TargetClass(value = "android.view.View",scope = Scope.SELF)
@Proxy(value = "setOnClickListener")
public void setOnClickListener(View.OnClickListener l) {
System.out.println("setOnClickListener"+" l:"+ l+" "+This.get());
Origin.callVoid();
}
@Proxy("i")
@TargetClass("android.util.Log")
public static int printLog(String tag, String msg) {
msg = msg + "----lancet";
return (int) Origin.call();
}
@TargetClass(value = "android.support.v7.app.AppCompatActivity", scope = Scope.LEAF)
@Insert(value = "onStop", mayCreateSuper = true)
protected void onStop() {
Log.i("ZLOVE", "hello word");
Origin.callVoid();
}
打印出来的是 hello word,而不是hello word----lancet
Lancet版本:1.0.5
FAILURE: Build failed with an exception.
java.lang.ClassCastException: me.ele.lancet.weaver.internal.graph.ClassNode cannot be cast to me.ele.lancet.weaver.internal.graph.InterfaceNode
private void notifySuccessListeners(T value) {}
A是主工程,B集成了lancet,A使用B的时候,会提示下面的错。
java.lang.IllegalAccessError: tried to access method com.google.common.io.Files.fileTreeTraverser()Lcom/google/common/collect/TreeTraverser; from class me.ele.lancet.plugin.internal.context.DirectoryContentProvider
具体可以把饿了么另外的一个名为trojan的项目升级一下gradlewrapper的版本,就会发现有一样的错。
version:1.0.6
code:
@Proxy("enqueueMessage")
@TargetClass("android.os.MessageQueue")
protected Boolean test(Message msg, long delayMillis){
Log.d("enqueueMessage","testssss",new Exception());
return (Boolean) Origin.call();
}
Proxy和Insert有什么本质区别么
使用1.0.5编译期报错
Caused by: java.lang.NoSuchMethodError: com.google.common.io.Files.fileTraverser()Lcom/google/common/graph/Traverser;
at me.ele.lancet.plugin.internal.context.DirectoryContentProvider.forEach(DirectoryContentProvider.java:35)
at me.ele.lancet.plugin.internal.context.ClassifiedContentProvider.forEach(ClassifiedContentProvider.java:29)
at me.ele.lancet.plugin.internal.context.ContextReader$QualifiedContentTask.call(ContextReader.java:131)
at me.ele.lancet.plugin.internal.context.ContextReader$QualifiedContentTask.call(ContextReader.java:119)
lancet 1.0.6, gradle 4.2.1, jdk 1.8,Android Studio4.2.1
这样,无法表示三方SDK中的自定义class的参数, 有什么方法替代吗。
项目配置:
gradle版本:com.android.tools.build:gradle:4.0.0
使用插件:com.bytedance.tools.lancet:lancet-plugin-asm6:1.0.0
库版本:implementation 'me.ele:lancet-base:1.0.6'
问题
readme里用的provided,用compile没问题
lancet 1.0.6, gradle 4.2.1, jdk 1.8,Android Studio4.2.1
使用插件时,运行就一直报这个错误。已经将其依赖在app主工程了,但还是不行。
使用Lancet后,在library Module里的修改,需要clean后再次run,修改才能加载到APK里
测试后发现,需要删除掉Lancet里的transforms缓存,才可以成功;
麻烦检测下transforms的逻辑是否正确
另外,建议在修复该bug之前,在ReadMe里增加以下文字:
在app的build.gradle下插入以下代码fix该问题
"rm -rf ${project.buildDir}/intermediates/transforms/lancet".execute()
我们用了robust 是不是冲突了?
None
@TargetClass(value = "android.view.View",scope = Scope.SELF)
@Proxy(value = "setOnClickListener")
public void setOnClickListener(@Nullable View.OnClickListener l) {
System.out.println("setOnClickListener:"+l+" l=");
AopClickener a=new AopClickener() {
@Override
public void onClick(View v) {
System.out.println("onClick:"+v);
}
};
Origin.callVoid();
}
public static class AopClickener implements View.OnClickListener{
@Override
public void onClick(View v) {
}
}
我想代理所有点击事件,可是编译一直报这个错Cause: inner class in hook class com/xx/lancettest/AopLancet must be public static,我这已经是public static class 了呀,不过就算编译通过,好像也实现不了这种效果,因为Origin.callVoid();无法传参,那还怎么实现这种功能呢,我只知道反射可以。
我搞定了ASM6.0的兼容,就是懒得配置sonatype的上传,太麻烦了,我可以maven私服传过去
工程环境:
com.android.tools.build:gradle:3.3.2
lancet:1.0.5
[exec] Caching disabled for JetifyTransform: /opt/gradle/caches/modules-2/files-2.1/me.ele/lancet-base/1.0.5/2a0c9faab1d6e85ea14bfb54f14d65252b8e00f7/lancet-base-1.0.5.jar because:
[exec] Build cache is disabled
lancet:1.0.6
[exec] [RewritePlugin] fail process jar: /data/build/temp/149508/beta/android/WuxianClient/build/intermediates/transforms/lancet/xxxx/release/269.jar
[exec] java.lang.IllegalArgumentException
[exec] at org.objectweb.asm.ClassReader.readCode(ClassReader.java:1609)
[exec] at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1283)
[exec] at org.objectweb.asm.ClassReader.accept(ClassReader.java:688)
[exec] at org.objectweb.asm.ClassReader.accept(ClassReader.java:400)
[exec] at com.coofee.rewrite.util.AsmUtil.convert(AsmUtil.java:11)
[exec] at com.coofee.rewrite.RewriteTransform.lambda$processJar$8(RewriteTransform.java:260)
[exec] at com.coofee.rewrite.util.FileUtil.traverseJarClass(FileUtil.java:92)
[exec] at com.coofee.rewrite.RewriteTransform.processJar(RewriteTransform.java:259)
[exec] at com.coofee.rewrite.RewriteTransform.lambda$null$0(RewriteTransform.java:135)
[exec] at com.google.common.collect.ImmutableList.forEach(ImmutableList.java:407)
[exec] at com.coofee.rewrite.RewriteTransform.lambda$fullTransform$3(RewriteTransform.java:134)
[exec] at com.google.common.collect.ImmutableList.forEach(ImmutableList.java:407)
[exec] at com.coofee.rewrite.RewriteTransform.fullTransform(RewriteTransform.java:131)
[exec] at com.coofee.rewrite.RewriteTransform.transform(RewriteTransform.java:112)
[exec] at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:239)
[exec] at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:235)
[exec] at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:106)
[exec] at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:230)
[exec] at sun.reflect.GeneratedMethodAccessor644.invoke(Unknown Source)
[exec] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[exec] at java.lang.reflect.Method.invoke(Method.java:497)
[exec] at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:103)
[exec] at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:46)
[exec] at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41)
[exec] at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
[exec] at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
[exec] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$5.run(ExecuteActionsTaskExecuter.java:404)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
[exec] at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
[exec] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:393)
[exec] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:376)
[exec] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:80)
[exec] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:213)
[exec] at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$0(ExecuteStep.java:32)
[exec] at java.util.Optional.map(Optional.java:215)
[exec] at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:32)
[exec] at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
[exec] at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:58)
[exec] at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:35)
[exec] at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:48)
[exec] at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:33)
[exec] at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:39)
[exec] at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
[exec] at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
[exec] at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:35)
[exec] at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
[exec] at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:45)
[exec] at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:31)
[exec] at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:201)
[exec] at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:70)
[exec] at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:45)
[exec] at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)
[exec] at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:43)
[exec] at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:32)
[exec] at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
[exec] at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
[exec] at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:96)
[exec] at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:89)
[exec] at java.util.Optional.map(Optional.java:215)
[exec] at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:54)
[exec] at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:38)
[exec] at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:77)
[exec] at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
[exec] at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
[exec] at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
[exec] at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:90)
[exec] at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:48)
[exec] at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
[exec] at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:120)
[exec] at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionStateTaskExecuter.execute(ResolveBeforeExecutionStateTaskExecuter.java:75)
[exec] at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:62)
[exec] at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:108)
[exec] at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionOutputsTaskExecuter.execute(ResolveBeforeExecutionOutputsTaskExecuter.java:67)
[exec] at org.gradle.api.internal.tasks.execution.ResolveAfterPreviousExecutionStateTaskExecuter.execute(ResolveAfterPreviousExecutionStateTaskExecuter.java:46)
[exec] at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:94)
[exec] at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
[exec] at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:95)
[exec] at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
[exec] at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
[exec] at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
[exec] at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:73)
[exec] at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
[exec] at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
[exec] at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
[exec] at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
[exec] at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:49)
[exec] at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
[exec] at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)
[exec] at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
[exec] at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
[exec] at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
[exec] at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
[exec] at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
[exec] at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
[exec] at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
[exec] at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
[exec] at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
[exec] at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
[exec] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[exec] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[exec] at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
[exec] at java.lang.Thread.run(Thread.java:745)
[exec] [RewritePlugin] process directory: 270
如android原生View存在以下方法:
/** {@hide} */
@CallSuper
protected void encodeProperties(@NonNull ViewHierarchyEncoder stream) {
// ......
}
其传入参数 ViewHierarchyEncoder 也存在@hide注解
而我写了以下方法均不生效
@Insert(value = "encodeProperties")
@TargetClass(value = "android.view.View")
protected void _encodeProperties(ViewHierarchyEncoder stream) {
Log.d(TAG, "_encodeProperties_1: android.view.View.encodeProperties(ViewHierarchyEncoder stream)");
Origin.callVoid();
}
@Insert(value = "encodeProperties")
// @Proxy("encodeProperties")
@TargetClass(value = "android.view.View", scope = Scope.ALL)
protected void _encodeProperties(@ClassOf("android.view.ViewHierarchyEncoder") Object stream) {
Log.d(TAG, "_encodeProperties_2: android.view.View.encodeProperties(ViewHierarchyEncoder stream)");
Origin.callVoid();
}
我的理解是@hide会使得类或者方法不参与编译,这种情况是不是就不能使用lancet进行代码织入了呢?
Android gradle 版本号: classpath 'com.android.tools.build:gradle:3.6.3'
distributionUrl=https://services.gradle.org/distributions/gradle-5.6.4-all.zip
AndroidX
编译报错
如题,海外产品用了 AAB 之后 bundle 不能使用 lancet,能否支持,谢谢!
java.lang.IllegalAccessError: tried to access method com.google.common.io.Files.fileTreeTraverser()Lcom/google/common/collect/TreeTraverser; from class me.ele.lancet.plugin.internal.context.DirectoryContentProvider
Because of ELEME organization is deprecated, I create another repo for Lancet: https://github.com/CoffeePartner/Lancet.
I will continue to maintain Lancet at a long term.
Recently, I start to rewrite almost all the codes for the purpose:
Most API will keep compatible, but the package will be replaced.
I hope you enjoy it!
At last, stars welcome!
日志输出transformClassesWithLancetForDebug时failed;在app的gradle中移除apply plugin: 'me.ele.lancet'后运行正常。
以下是给出的错误提示:
me.ele.lancet.weaver.internal.graph.InterfaceNode cannot be cast to me.ele.lancet.weaver.internal.graph.ClassNode
Possible causes for this unexpected error include:
Gradle's dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)
Re-download dependencies and sync project (requires network)
The state of a Gradle build process (daemon) may be corrupt. Stopping all Gradle daemons may solve this problem.
Stop Gradle build processes (requires restart)
Your project may be using a third-party plugin which is not compatible with the other plugins in the project or the version of Gradle requested by the project.
In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.
集成插件后,出现这个问题...删除就不会报.
INFO: API 'variantOutput.getProcessResources()' is obsolete and has been replaced with 'variantOutput.getProcessResourcesProvider()'.
It will be removed at the end of 2019.
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.