lucasr / probe Goto Github PK
View Code? Open in Web Editor NEW[DEPRECATED] Dissect layout traversals on Android
License: Apache License 2.0
[DEPRECATED] Dissect layout traversals on Android
License: Apache License 2.0
I pulled fresh from git to fork, but when I tried to compile, it gave this error:
probe/library/src/main/java/org/lucasr/probe/DexProxyBuilder.java:27: error: package com.google.dexmaker does not exist
import com.google.dexmaker.Code;
This repeats for all the imported classes in DexProxyBuilder.
If a setFactory2() is already provided using fragments, Android does a merge of the factories. In that case, it may call onCreateView() without the parent argument. In this case Probe will not be created, hence no probing will be done.
E/AndroidRuntime(20649): java.lang.IncompatibleClassChangeError: superclass is final
E/AndroidRuntime(20649): at dalvik.system.DexFile.defineClassNative(Native Method)
E/AndroidRuntime(20649): at dalvik.system.DexFile.defineClass(DexFile.java:222)
E/AndroidRuntime(20649): at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:215)
E/AndroidRuntime(20649): at dalvik.system.DexPathList.findClass(DexPathList.java:322)
E/AndroidRuntime(20649): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54)
E/AndroidRuntime(20649): at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
E/AndroidRuntime(20649): at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
E/AndroidRuntime(20649): at org.lucasr.probe.ViewProxyBuilder.generateProxyClass(ViewProxyBuilder.java:428)
E/AndroidRuntime(20649): at org.lucasr.probe.ViewProxyBuilder.build(ViewProxyBuilder.java:559)
E/AndroidRuntime(20649): at org.lucasr.probe.ProbeViewFactory.createProxyView(ProbeViewFactory.java:51)
E/AndroidRuntime(20649): at org.lucasr.probe.ProbeViewFactory.onCreateView(ProbeViewFactory.java:72)
E/AndroidRuntime(20649): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:684)
E/AndroidRuntime(20649): at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
E/AndroidRuntime(20649): at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
E/AndroidRuntime(20649): at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
E/AndroidRuntime(20649): at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
E/AndroidRuntime(20649): at com.android.internal.policy.impl.PhoneWindow.generateLayout(PhoneWindow.java:3022)
E/AndroidRuntime(20649): at com.android.internal.policy.impl.PhoneWindow.installDecor(PhoneWindow.java:3085)
E/AndroidRuntime(20649): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:286)
This is not a real issues but more a question: Is it possible to chain Interceptors?
If I deploy multiple Interceptors like this:
@Override
protected void onCreate(Bundle savedInstanceState) {
Probe.deploy(this, new OvermeasureInterceptor(R.id.root));
Probe.deploy(this, new LayoutBoundsInterceptor(this));
Probe.deploy(this, new ImageViewInterceptor(this));
I get a Runtime Exception:
java.lang.IllegalStateException : A factory has already been set on this LayoutInflater
Hey,
I'm trying to add Probe to my project and get this error:
/Users/Zaur/Projects/android/MyListView/app/build/generated/source/probe/debug/ru/agamov/mylistview/probe/ProbeProxy$android_widget_DateTimeView.java
Error:(8, 22) error: cannot find symbol class DateTimeView
Error:(9, 67) error: cannot find symbol class DateTimeView
Error:(20, 19) error: method onMeasure in class Interceptor cannot be applied to given types;
required: View,int,int
found: ProbeProxy$android_widget_DateTimeView,int,int
reason: actual argument ProbeProxy$android_widget_DateTimeView cannot be converted to View by method invocation conversion
Here is my build.gradle:
apply plugin: 'com.android.application'
apply plugin: 'org.lucasr.probe'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.lucasr.probe:gradle-plugin:0.1.3'
}
}
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "ru.agamov.mylistview"
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled false
}
}
}
probe {
buildVariants {
debug {
enabled = true
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
}
This doesn't have any android resources. It's better to generate a jar.
Hi, I'm having this strange error show up. I've put your DrawGreen sample class into a new sample project, and am calling
Probe.deploy(this, new DrawGreen(), new Filter.ViewId(R.id.start_button));
on the onCreate of my Activity, just before the super.onCreate(). R.id.start_button
is just the Button
class.
I dug a little and it seems like this class is getting generated:
public final class ProbeProxy$android_widget_DateTimeView extends DateTimeView
implements InterceptableView {
...
}
But it looks like it's unable to find DateTimeView.
I'm on Android Studio 2.1.1, compileSdkVersion 23.
I've added this to my build.gradle file; but when I try running assembleProbeDebug in the gradle logs I see that probe is disabled; when I run my code it is in fact disabled.
productFlavors {
probe {
buildVariants {
debug {
enabled true
}
}
}
}
Hi Lucas,
When I add probe as a dependency to my app, apply the plugin, and enable it for my debug builds, compilation fails with this exception, even before I deploy Probe in any of my Activities. Any idea what's going on? Happy to provide any more information you need.
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':probeDebugViews'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:305)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
Caused by: groovy.lang.MissingMethodException: No signature of method: org.lucasr.probe.internal.LayoutResourceParser$_traverseLayoutXml_closure1.traverseLayoutXml() is applicable for argument types: (java.lang.String, java.util.HashSet) values: [
/>
, ...]
at org.lucasr.probe.internal.LayoutResourceParser$_traverseLayoutXml_closure1.doCall(LayoutResourceParser.groovy:45)
at org.lucasr.probe.internal.LayoutResourceParser.traverseLayoutXml(LayoutResourceParser.groovy:45)
at org.lucasr.probe.internal.LayoutResourceParser.parse(LayoutResourceParser.groovy:29)
at org.lucasr.probe.internal.LayoutResourceParser$parse.call(Unknown Source)
at org.lucasr.probe.ProbeTask$_parseLayoutFiles_closure3.doCall(ProbeTask.groovy:82)
at org.lucasr.probe.ProbeTask.parseLayoutFiles(ProbeTask.groovy:81)
at org.lucasr.probe.ProbeTask.this$4$parseLayoutFiles(ProbeTask.groovy)
at org.lucasr.probe.ProbeTask$this$4$parseLayoutFiles.callCurrent(Unknown Source)
at org.lucasr.probe.ProbeTask.taskAction(ProbeTask.groovy:51)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:63)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.doExecute(AnnotationProcessingTaskFactory.java:235)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:211)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.execute(AnnotationProcessingTaskFactory.java:222)
at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:200)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
... 13 more
BUILD FAILED
When I install JDK 7,gradle tells me
Error:(2, 0) Cause: org/lucasr/probe/ProbePlugin : Unsupported major.minor version 51.0
in XML throws the following error.
W/System.err(18079): java.lang.ClassNotFoundException: Couldn't load View class for View
W/System.err(18079): at org.lucasr.probe.ViewClassUtil.findViewClass(ViewClassUtil.java:67)
W/System.err(18079): at org.lucasr.probe.ProbeViewFactory.createProxyView(ProbeViewFactory.java:51)
W/System.err(18079): at org.lucasr.probe.ProbeViewFactory.onCreateView(ProbeViewFactory.java:72)
W/System.err(18079): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:684)
W/System.err(18079): at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
W/System.err(18079): at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
W/System.err(18079): at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
W/System.err(18079): at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
If the XML has a tag, it throws a ClassNotFoundException inside Probe. Anything under this fragment cannot be probed after this.
If there is a ListView, the rows in the ListView have a different inflater. It's hard to create probe for each inflation inside each Adapter. It would be better to have a ProbeLayoutInflater that is returned by the MainActivity. That way, everything inside an Activity can be probed.
I ran into another problem -- the package name for the generated source files is null.probe
, which is invalid. Where's it supposed to get the package name from?
By the way, how do I run / debug Probe itself? I tried to set a breakpoint in ProbeTask (to see where it's getting the package name) and then ran the sample project, but no dice.
Example: (this happens for every view class)
package null.probe;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import org.lucasr.probe.InterceptableView;
import org.lucasr.probe.Interceptor;
import android.view.View;
public final class ProbeProxy$android_view_View extends View
implements InterceptableView {
private Interceptor mInterceptor;
public ProbeProxy$android_view_View(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setInterceptor(Interceptor interceptor) {
mInterceptor = interceptor;
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mInterceptor != null) {
mInterceptor.onMeasure(this, widthMeasureSpec, heightMeasureSpec);
}
else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void superOnMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (mInterceptor != null) {
mInterceptor.onLayout(this, changed, left, top, right, bottom);
}
else {
super.onLayout(changed, left, top, right, bottom);
}
}
public void superOnLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
public void draw(Canvas canvas) {
if (mInterceptor != null) {
mInterceptor.draw(this, canvas);
}
else {
super.draw(canvas);
}
}
public void superDraw(Canvas canvas) {
super.draw(canvas);
}
protected void onDraw(Canvas canvas) {
if (mInterceptor != null) {
mInterceptor.onDraw(this, canvas);
}
else {
super.onDraw(canvas);
}
}
public void superOnDraw(Canvas canvas) {
super.onDraw(canvas);
}
public void requestLayout() {
if (mInterceptor != null) {
mInterceptor.requestLayout(this);
}
else {
super.requestLayout();
}
}
public void superRequestLayout() {
super.requestLayout();
}
public void superSetMeasuredDimension(int width, int height) {
super.setMeasuredDimension(width, height);
}
}
The fragment in use is the support library version. But the LayoutInflater tries to inflate the android version (android.app.fragment), and tries to cast to it. This causes a ClassNotFoundException. The same piece of code works fine without Probe.
E/AndroidRuntime( 1156): at android.app.Fragment.instantiate(Fragment.java:607)
E/AndroidRuntime( 1156): at android.app.Fragment.instantiate(Fragment.java:583)
E/AndroidRuntime( 1156): at android.app.Activity.onCreateView(Activity.java:4859)
E/AndroidRuntime( 1156): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)
E/AndroidRuntime( 1156): ... 23 more
E/AndroidRuntime( 1156): Caused by: java.lang.ClassCastException
E/AndroidRuntime( 1156): ... 27 more
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.