Code Monkey home page Code Monkey logo

lancet's Introduction

Lancet

Chinese README

Lancet is a lightweight AOP framework for Android.

It's fast and just take up a little time during compiling. Also, it supports incremental compiling.

But it provides great api to help you coding in Android.

It takes no runtime jar.

In addition, not only App developers but also SDK developers can use Lancet.

Usage

Installation

Firstly, add following code in root build.gradle of your project.

dependencies {
    classpath 'com.android.tools.build:gradle:3.3.2'
    classpath 'me.ele:lancet-plugin:1.0.6'
}

Tips: Lancet 1.0.5 and above only supports gradle 3.3.2 and above.

And then, add following code in your application module's build.gradle

apply plugin: 'me.ele.lancet'

dependencies {
    provided 'me.ele:lancet-base:1.0.6'
}

That's OK.Now you can follow our tutorial to learn how to use it.

Tutorial

Lancet use annotation to indicate where to cut the code and focus on interacting with origin class's methods and fields;

Firstly, let's see a example. Look at the following code:

@Proxy("i")
@TargetClass("android.util.Log")
public static int anyName(String tag, String msg){
    msg = msg + "lancet";
    return (int) Origin.call();
}

There are some key points:

  • @TargetClass directly locate the target android.util.Log
  • @Proxylocate the method namei
  • Origin.call() will be replaced byLog.i() as we explained above
  • so the influence is every Log.i's second parametermsg will has a trailing "lancet"

Choose target class

public @interface TargetClass {
    String value();

    Scope scope() default Scope.SELF;
}

public @interface ImplementedInterface {

    String[] value();

    Scope scope() default Scope.SELF;
}

public enum Scope {

    SELF,
    DIRECT,
    ALL,
    LEAF
}

We use the three classes above to locate our targets.

@TargetClass

  1. value in @TargetClass should be a full class name.
  2. Scope.SELF means the target is the class named by value
  3. Scope.DIRECT locate the direct subclasses of value
  4. Scope.All indicates the all subclasses of value
  5. The Scope.LEAF is a little bit special, it means all leaf subclasses of value.For example: A <- B <- C, B <- D, the leaf children of A are C and D.

@ImplementedInterface

  1. value in @ImplementedInterface is a string array filled with full interface names and classes that satisfied all conditions will be chosen.
  2. Scope.SELF : all classes implements interfaces literally
  3. Scope.DIRECT : all classes implements interfaces or their children interfaces literally
  4. Scope.ALL: all classes included in Scope.DIRECT and their childrens
  5. Scope.LEAF: all classes in Scope.ALL with no children.

Let's see a illustration.

scope

When we use@ImplementedInterface(value = "I", scope = ...), the targets are:

  • Scope.SELF -> A
  • Scope.DIRECT -> A C
  • Scope.ALL -> A B C D
  • Scope.LEAF -> B D

Choose target method

Choose method name

public @interface Insert {
    String value();
    boolean mayCreateSuper() default false;
}

public @interface Proxy {
    String value();
}

public @interface TryCatchHandler {
}

public @interface NameRegex {
    String value();
}
@TryCatchHandler

This annotation is easy.

@TryCatchHandler
@NameRegex("(?!me/ele/).*")
    public static Throwable catches(Throwable t){
        return t;
    }

As the code above, it hook every try catch handle, you can deal with and return. And the control flow will jump to it's origin space.

But with the @NameRegex, something is different.

@NameRegex

@NameRegex is used to restrict hook method by match the class name.Be caution, the dot in class name will be replaced by slash.

String value in @NameRegex will be compiled to pattern. the hook method only works if the pattern matches the class name where appear the cut point.

Such as the above example, every class will be ignored if it's package name start with "me.ele.";

@NameRegex can only be used with @Proxy or @TryCatchHandler.

@Proxy and @Insert
  1. Value in @Proxy and @Insert is the target method name.

  2. @Proxy means to hook every invoke point of the target method.

  3. @Insert means to hook the code inside the method.

  4. In another word, if you use @Insert to hook a method, the running code in the target method will be changed.But @Proxy can control the scope by using it combined with @NameRegex.

  5. Another different is, classes in Android's ROM can't be touched as compiling time.So we can't use @Insert if we want to change the behavior of ROM's classes, but @Proxy can do it.

@Insert has a special boolean parameter is mayCreateSuper.Let's see a example.

@TargetClass(value = "android.support.v7.app.AppCompatActivity", scope = Scope.LEAF)
@Insert(value = "onStop", mayCreateSuper = true)
protected void onStop(){
    System.out.println("hello world");
    Origin.callVoid();
}

The goal method of the hook method is every leaf child of AppcompatActivity void onStop().

If a class MyActivity extends AppcompatActivitydo not override the onStop method, we will create a method for MyActivity like this:

protected void onStop() {
    super.onStop();
}

And then hook the method.

If you open the flag, it will always create the method if target class has no matched method no matter it has the super method or doesn't.

And the public/protected/private flag is inherited from above hook method.This is the flag's only use.

Also be care that

Choose method descriptor

The example shown at first also indicates a important rule which is the strict match.The Log.i 's full descriptor is "int Log.i(String, String)", more precisely ""(Ljava/lang/String;Ljava/lang/String;)I"".

It means our hook method should have the same method descriptor and static flag with target method.

It doesn't matter if you don't known method descriptor. You can have a look at JVM Specification Chapter 4.3 if interested.

We doesn't care if parameters' generic type are the same or not.In another word, we don't care signature of method, only descriptor.

Also, exceptions declaration is also ignorable.You can write them for convenience.

Any other access flag will be ignored except private/protected/public/static that we said above.

@ClassOf

Sometimes, we can't directly declare a class that we can't touch as parameter of our hook method.

we can use @ClassOf to do this job.

Take a look at the following example:

public class A {
    protected int execute(B b){
        return b.call();
    }

    private class B {

        int call() {
            return 0;
        }
    }
}

@TargetClass("com.dieyidezui.demo.A")
@Insert("execute")
public int hookExecute(@ClassOf("com.dieyidezui.demo.A$B") Object o) {
    System.out.println(o);
    return (int) Origin.call();
}

We use @ClassOfto locate the parameter's actual type.

And the parameter declared in method should be it's super class, such as java.lang.Object;

value in @ClassOf should be in the form of "(package_name.)(outer_class_name$)class_name([]...)", such as:

  • java.lang.Object
  • java.lang.Integer[][]
  • A[]
  • A$B

if no @ClassOf, the hook method's descriptor is "(Ljava/lang/Object;)I". But now it is "(Lcom/dieyidezui/demo/A$B;)I".

So the hookExecute method can match A.execute.

API

Till now, we have two classes to use, they are Origin and This.

Origin

Origin is used to call original method. You can invoke its method zero or one more times if you like.

Origin.call/callThrowOne/callThrowTwo/callThrowThree()

This group API is used for call the original method which has return value. You should cast it to original type that the same with hook method descriptor's return type.

Origin.callVoid/callVoidThrowOne/callVoidThrowTwo/callVoidThrowThree()

Similar with above three methods, these methods are used for method without return value.

By the way, the ThrowOne/ThrowTwo/ThrowThree are for deceiving the compiler if you want to catch some exceptions for some convenience.

For example:

@TargetClass("java.io.InputStream")
@Proxy("read")
public int read(byte[] bytes) throws IOException {
    try {
        return (int) Origin.<IOException>callThrowOne();
    } catch (IOException e) {
        e.printStackTrace();
        throw e;
    }
}

So that on every invoke point of int InputStream.read(byte[]), if IOException happens, we will see its stacktrace.

This

get()

This method is used for none static method to find this object. You can cast it to its actual type.

putField(Object, String) / getField(String)

You can directly get or put a field in the target class even if the field is protected or private!

What's more! If the field name is not exists, we will create it for you!

Auto box and unbox are also supported.

Also, we have some restricts:

  • These two methods only are only allowed to use with @Insert till now.
  • You can't retrieve it's field of super class. When you try to get or put a field that it's super class has. We still will create the field for you. If the field of super class is private, it's OK. Otherwise, you will get a error at runtime.

For example:

package me.ele;
public class Main {
    private int a = 1;

    public void nothing(){

    }

    public int getA(){
        return a;
    }
}

@TargetClass("me.ele.Main")
@Insert("nothing")
public void testThis() {
    Log.e("debug", This.get().getClass().getName());
    This.putField(3, "a");
    Origin.callVoid();
}

Then we run the following codes:

Main main = new Main();
main.nothing();
Log.e("debug", "a = " + main.getA());

We will see:

E/debug: me.ele.Main
E/debug: a = 3

Tips

  1. Inner classes should be named like package.outer_class$inner_class
  2. SDK developer needn't to apply plugin, just provided me.ele:lancet-base:x.y.z
  3. Although we support incremental compilation. But when you use Scope.LEAF、Scope.ALL or edit the hook class, the incremental judgement will be a little special. It may cause full compilation.

License

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

lancet's People

Contributors

dieyidezui avatar liangxiwei avatar penneryu avatar twlkyao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lancet's Issues

Lancet如何织入@hide的类

如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进行代码织入了呢?

对This.get()的疑问??

看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();
}

Android 5.0以下

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

java.lang.NoSuchMethodError: com.google.common.io.Files.fileTraverser()Lcom/google/common/graph/Traverser;

使用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插件后编译不过

Lancet版本:1.0.5

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':App:transformClassesWithLancetForDemoRelease'.

java.lang.ClassCastException: me.ele.lancet.weaver.internal.graph.ClassNode cannot be cast to me.ele.lancet.weaver.internal.graph.InterfaceNode

Execution failed for task ':app:transformClassesWithLancetForDebug'. > java.lang.RuntimeException: java.lang.UnsupportedOperationException: This feature requires ASM6

lancet 1.0.6, gradle 4.2.1, jdk 1.8,Android Studio4.2.1

  • Exception is:
    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformClassesWithLancetForDebug'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:200)
    at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:263)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:198)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:179)
    at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
    at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
    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:77)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
    at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
    at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:372)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:359)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:352)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:338)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.UnsupportedOperationException: This feature requires ASM6
    at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:71)
    at com.android.build.gradle.internal.profile.AnalyticsResourceManager.recordBlockAtExecution(AnalyticsResourceManager.kt:226)
    at com.android.build.gradle.internal.profile.AnalyticsService.recordBlock(AnalyticsService.kt:151)
    at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:242)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
    at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:47)
    at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
    at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
    at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.run(ExecuteActionsTaskExecuter.java:555)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
    at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:540)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:523)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:108)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:271)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:260)
    at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$0(ExecuteStep.java:33)
    at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:33)
    at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
    at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:67)
    at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:36)
    at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:49)
    at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:34)
    at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:43)
    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.CreateOutputsStep.execute(CreateOutputsStep.java:44)
    at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:54)
    at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:38)
    at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:42)
    at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:159)
    at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:72)
    at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:43)
    at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:44)
    at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:33)
    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:92)
    at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:85)
    at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
    at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:39)
    at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:76)
    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:94)
    at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)
    at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:79)
    at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:53)
    at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:74)
    at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:78)
    at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:78)
    at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34)
    at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:39)
    at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:40)
    at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:28)
    at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:187)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:179)
    at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
    at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
    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:77)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
    at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
    at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:372)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:359)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:352)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:338)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    Caused by: java.lang.RuntimeException: java.lang.UnsupportedOperationException: This feature requires ASM6
    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:284)
    at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:69)
    ... 99 more
    Caused by: java.lang.UnsupportedOperationException: This feature requires ASM6
    at org.objectweb.asm.ClassVisitor.visitModule(ClassVisitor.java:130)
    at org.objectweb.asm.ClassReader.readModuleAttributes(ClassReader.java:715)
    at org.objectweb.asm.ClassReader.accept(ClassReader.java:535)
    at org.objectweb.asm.ClassReader.accept(ClassReader.java:391)
    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)

并不能 hook 未重写方法

 @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();
//    }
}

Cause: inner class in hook class com/xx/lancettest/AopLancet must be public static

@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();无法传参,那还怎么实现这种功能呢,我只知道反射可以。

升级到AndroidStudio3.5编译出错

  • What went wrong:
    Execution failed for task ':app:transformClassesWithLancetForLandscapeDuerosRelease'.

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

Lancet project transfer

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:

  1. reduce duplicated codes copy
  2. support runtime API
  3. other API optimize
  4. support almost totally incremental builds (improve build performance
  5. fix incremental problems #10 (In fact, the early version is OK, but we broken it

Most API will keep compatible, but the package will be replaced.
I hope you enjoy it!
At last, stars welcome!

如何weave onCreate一类无返回值的方法

@Proxy("onCreate")
@TargetClass("androidx.appcompat.app.AppCompatActivity")
public static void onCreate(@nullable Bundle savedInstanceState) {
Log.e(tag, "AppCompatActivity.onCreate");
Origin.callVoid();
}
没有Log出对应的信息
应该是没有weave成功

lancet支持在应用中hook ActivityManagerService中的方法吗

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();
}

variantOutput.getProcessResources()

集成插件后,出现这个问题...删除就不会报.
INFO: API 'variantOutput.getProcessResources()' is obsolete and has been replaced with 'variantOutput.getProcessResourcesProvider()'.
It will be removed at the end of 2019.

作为sdk提供给第三方用,插件不支持高版本gradle

A是主工程,B集成了lancet,A使用B的时候,会提示下面的错。

  • What went wrong:
    Execution failed for task ':app:transformClassesWithLancetForDebug'.

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的版本,就会发现有一样的错。

lancet可以支持织入静态方法吗

wiki中的例子

@Proxy("i")
@TargetClass("android.util.Log")
public int i(String tag,String msg){
    msg = msg+ "lancet";
    return (int)Origin.call();
}

是不起作用,我试了一下,静态方法不论是@Proxy还是@insert都没用,是没有支持还是我使用的姿势有问题

@Insert方法下调用被拦截的Log.d未生效

@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

增量编译导致严重的问题

项目配置:
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'

问题

  1. 当修改一个xml布局文件,修改样式等,重新编译运行,发现出来的效果是修改前的。移除lancet使用后,发现恢复正常
  2. 使用此插件之后,debug代码,发现断点各种异常。比如:单步调试时,代码的执行流程和原有的代码执行流程对不上。初步怀疑因为代码插装的缘故,到时断点的位置不正确,别插入的代码影响到了

proxy MessageQueue的enqueueMessage方法无效

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();
}

引用插件后运行时异常,求解答

日志输出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.

This feature requires ASM6

Android gradle 版本号: classpath 'com.android.tools.build:gradle:3.6.3'

distributionUrl=https://services.gradle.org/distributions/gradle-5.6.4-all.zip

AndroidX

编译报错

Lancet导致库工程里的修改,需要clean后才能run入apk里

使用Lancet后,在library Module里的修改,需要clean后再次run,修改才能加载到APK里
测试后发现,需要删除掉Lancet里的transforms缓存,才可以成功;
麻烦检测下transforms的逻辑是否正确

另外,建议在修复该bug之前,在ReadMe里增加以下文字:
在app的build.gradle下插入以下代码fix该问题
"rm -rf ${project.buildDir}/intermediates/transforms/lancet".execute()

lancet:1.0.5织入代码失败 ; lancet:1.0.6

工程环境:
com.android.tools.build:gradle:3.3.2

使用1.0.5版本织入失败

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,执行织入失败IllegalArgumentException

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

三方库能hook吗?

我最近用 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();
    

    }

    /**

    • @return {@code true} If the application was force stopped.
      */
      @VisibleForTesting
      public boolean isForceStopped() {
      // Alarms get cancelled when an app is force-stopped starting at Eclair MR1.
      // Cancelling of Jobs on force-stop was introduced in N-MR1 (SDK 25).
      // Even though API 23, 24 are probably safe, OEMs may choose to do
      // something different.
      PendingIntent pendingIntent = getPendingIntent(mContext, FLAG_NO_CREATE);
      if (pendingIntent == null) {
      setAlarm(mContext);
      return true;
      } else {
      return false;
      }
      }

    /**

    • @return {@code true} If we need to reschedule Workers.
      */
      @VisibleForTesting
      boolean shouldRescheduleWorkers() {
      return mWorkManager.getPreferences().needsReschedule();
      }

    /**

    • @param flags The {@link PendingIntent} flags.
    • @return an instance of the {@link PendingIntent}.
      */
      private static PendingIntent getPendingIntent(Context context, int flags) {
      Intent intent = getIntent(context);
      return PendingIntent.getBroadcast(context, ALARM_ID, intent, flags);
      }

    /**

    • @return The instance of {@link Intent} used to keep track of force stops.
      */
      @VisibleForTesting
      static Intent getIntent(Context context) {
      Intent intent = new Intent();
      intent.setComponent(new ComponentName(context, ForceStopRunnable.BroadcastReceiver.class));
      intent.setAction(ACTION_FORCE_STOP_RESCHEDULE);
      return intent;
      }

    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);
      }
      }
      }
      }
      `
      ·

Execution failed for task ':app:transformClassesWithLancetForDebug'. > java.lang.RuntimeException: java.lang.UnsupportedOperationException: This feature requires ASM6

lancet 1.0.6, gradle 4.2.1, jdk 1.8,Android Studio4.2.1

  • Exception is:
    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformClassesWithLancetForDebug'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:200)
    at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:263)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:198)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:179)
    at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
    at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
    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:77)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
    at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
    at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:372)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:359)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:352)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:338)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    Caused by: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.UnsupportedOperationException: This feature requires ASM6
    at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:71)
    at com.android.build.gradle.internal.profile.AnalyticsResourceManager.recordBlockAtExecution(AnalyticsResourceManager.kt:226)
    at com.android.build.gradle.internal.profile.AnalyticsService.recordBlock(AnalyticsService.kt:151)
    at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:242)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
    at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:47)
    at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
    at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
    at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.run(ExecuteActionsTaskExecuter.java:555)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
    at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:540)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:523)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:108)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:271)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:260)
    at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$0(ExecuteStep.java:33)
    at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:33)
    at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
    at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:67)
    at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:36)
    at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:49)
    at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:34)
    at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:43)
    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.CreateOutputsStep.execute(CreateOutputsStep.java:44)
    at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:54)
    at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:38)
    at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:42)
    at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:159)
    at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:72)
    at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:43)
    at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:44)
    at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:33)
    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:92)
    at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:85)
    at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
    at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:39)
    at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:76)
    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:94)
    at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)
    at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:79)
    at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:53)
    at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:74)
    at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:78)
    at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:78)
    at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34)
    at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:39)
    at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:40)
    at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:28)
    at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:187)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:179)
    at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
    at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
    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:77)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
    at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
    at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
    at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
    at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
    at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
    at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:372)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:359)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:352)
    at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:338)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
    at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    Caused by: java.lang.RuntimeException: java.lang.UnsupportedOperationException: This feature requires ASM6
    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:284)
    at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:69)
    ... 99 more
    Caused by: java.lang.UnsupportedOperationException: This feature requires ASM6
    at org.objectweb.asm.ClassVisitor.visitModule(ClassVisitor.java:130)
    at org.objectweb.asm.ClassReader.readModuleAttributes(ClassReader.java:715)
    at org.objectweb.asm.ClassReader.accept(ClassReader.java:535)
    at org.objectweb.asm.ClassReader.accept(ClassReader.java:391)
    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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.