B4A Library Reflection library

There will be lots to come in future versions of Basic4Android as Erel adds more of Androids capabilities. In the mean time there will be things that would be nice to have but are not actually implemented. This library will help to solve at least some of those requirements.

This is the Android equivalent of the Basic4ppc Door library that turned out to be so useful. There is a demo for the library that adds onFocus and onTouch events to views that don't implement them, accesses objects fields and runs methods.

A separate demo shows how to "Linkify" text so that URLs in the text become active hyperlinks.

EDIT:- Version 1.1 posted. See post #17 for details.

EDIT:- Version 1.2 posted. Bug fix. See post#19 for details.

EDIT:- Version 1.3 posted. See post#20 for details.

EDIT:- Version 1.4 posted. See post#21 for details.

EDIT:- Version 1.5 posted. See post #25 for details.

EDIT:- Version 1.6 posted. See post #31 for details.

EDIT:- Version 1.7 posted. See post #32 for details.

EDIT:- Version 1.8 posted. See post #33 for details.

EDIT:- Version 1.9 posted. See post #48 for details.

EDIT:- Version 2.0 posted. See post #51 for details.

EDIT:- Version 2.1 posted. See post #53 for details.

EDIT:- Version 2.2 posted for Basic4android 2.0 or later. Version 2.1 remains for earlier versions. See post #57 for details.

EDIT:- Informatix has produced Version 2.3 in post #317

EDIT:- Version 2.4 posted. See post #91 for details.
 

Attachments

  • Reflection2.1.zip
    33.2 KB · Views: 1,881
  • Reflection2.4.zip
    33 KB · Views: 4,112
Last edited:

agraham

Expert
Licensed User
Longtime User
A rapid update to version 1.4 as I realised that the one exception that the modified RunMethodX methods would not rethrow was "Method not found" which might be important! Instead they returned null but now they will throw the exception.

I also added GetMethod and InvokeMethod methods as finding a method from its string and array of types is expensive in processor time and you might want to invoke the same method several times.
 

Cor

Active Member
Licensed User
Longtime User
reflection help

need some help for the reflection lib to get the hang of it

android.os.Vibrator is supported by b4a

This will help me further exploring the reflection possibilities

How to implement: methods

void cancel()
Turn the vibrator off.

boolean hasVibrator()
Check whether the hardware has a vibrator.

void vibrate(long[] pattern, int repeat)
Vibrate with a given pattern.

void vibrate(long milliseconds)
Turn the vibrator on.


B4X:
Dim Obj2 As Reflector
Obj2.Target = Obj2.CreateObject("android.os.Vibrator")
 

peacemaker

Expert
Licensed User
Longtime User
Agraham, what do you think about PowerManager PowerManager | Android Developers and trying to use PARTIAL_WAKE_LOCK with help of Reflection ?
Possible ?

I think that PhoneWakeState of b4a does not implement this variant yet.
 

agraham

Expert
Licensed User
Longtime User
The last two queries above would need access to the application Context to get a system service using Context.getSystemService.

As this seems like a useful thing to be able to do version 1.5 now posted has a new GetContext method and the demo includes a fragment showing how to fetch the system PowerManager object.
 

peacemaker

Expert
Licensed User
Longtime User
It really needs Java knowledge :sign0013: to go on.
Thanks anyway.
 

peacemaker

Expert
Licensed User
Longtime User
Obj1.Target = Obj1.GetContext
Msgbox(Obj1.TypeName, "GetContext")
Obj2.Target = Obj1.RunMethod2("getSystemService", "power", "java.lang.String")
Msgbox(Obj2.TypeName, "Obj2.Target")
Obj3.Target = Obj2.RunMethod3("newWakeLock","1", "java.lang.Integer","Mytag", "java.lang.String") '1 = PARTIAL_WAKE_LOCK
Obj3.RunMethod("acquire")

NoSuchMethodExeption :( for "newWakeLock" :sign0085::sign0104:
 

agraham

Expert
Licensed User
Longtime User
Probably
B4X:
Obj3.Target = Obj2.RunMethod3("newWakeLock","1", "java.lang.[COLOR="Red"][B][SIZE="5"]I[/SIZE][/B][/COLOR]nteger","Mytag", "java.lang.String")
java.lang.Integer is the type of an int boxed as a true Object.

java.lang.integer is the type of a primitive int which is what the newWakeLock method signature requires.
 

peacemaker

Expert
Licensed User
Longtime User
java.lang.integer is the type of a primitive int which is what the newWakeLock method signature requires.

Thank you Agraham, finally "java.lang.int" has helped.
But it even does not exist in the class list on Dev.Android.
 
Last edited:

agraham

Expert
Licensed User
Longtime User
But it even does not exist in the class list on Dev.Android.
This is a simplification but unlike C# :( Java primitives don't have class types so I had to give the Reflection library some "made-up" class names to specify primitive types so I made them a lower-case version of the boxed primitive types. This is noted in the comments/help for the Reflection library.

Sorry, I was working from memory, as you wrote it should be "java.lang.int" not "integer".
 
Last edited:

agraham

Expert
Licensed User
Longtime User
Version 1.6 is now posted. The changes are :-

Reflector is no longer an ActivitytObject.

Added TargetRank, GetArray, SetArray, SetArray2. These enable arrays to be accessed.

Added IsNull and SetField2

Added GetB4AClass, GetProcessBA, GetMostCurrent, GetActivity, GetActivityBA. To use these somewhat arcane methods requires a knowledge of the internal structure of a Basic4android application. I don't think there are many of us about. :)
 

agraham

Expert
Licensed User
Longtime User
Version 1.7 is now posted. The changes are :-

Added GetStaticField, SetStaticField and SetStaticField2.
These enable access to a static field of a class where there is no class instance available.

Added GetPublicField, SetPublicField and SetPublicField2.
These are slightly more efficient i.e. slightly faster executing versions of GetField but can only be used on Public fields.

Added GetFieldInfo, GetField2, SetField3 and SetField4.
Where repeated access to a field may be needed it is more efficient to cache the field info and use that instead of reflecting on the field name every time.

Added RunPublicMethod.
This is a slightly more efficient i.e. slightly faster executing version of RunMethod4 but can only be used on Public methods.
 
Last edited:

agraham

Expert
Licensed User
Longtime User
Version 1.8 now posted.

A new method "GetProxy" is added. Used together with the existing capabilities of the Reflection library it now allows you to add events to objects when those events are not exposed by Basic4android and where those events are implemented by an interface and assigned by a setOnXxxxxListener method. An example is provided in the demo in the archive.
 

Widget

Well-Known Member
Licensed User
Longtime User
Agraham,
This may be a silly question, but where is the download link for the Reflection library for Android? I thought there should be a zip file attachment with your first post. I've looked all over for the .zip file and can't find it. :confused:

TIA
Widget
(Registered B4A user).
 

Widget

Well-Known Member
Licensed User
Longtime User
The download link is at the bottom of post #1. I've just checked and it downloads fine.

Agraham,
My bad. I did a search on Reflection 1.8 and it displayed this page. I thought your post of 7-16-2011 was the first post for the thread. It turns out I'm on page 3 of the thread. :sign0161:

Widget
 

riko

Member
Licensed User
Longtime User
Hello Agraham,

i am now working now for days to find a way to forward a event from one panel to an other. I have now seen this library from you.

So lets say i have a few panels which are one over the other. Each of them is transparent and each of them have some views on it (like layers).
Now if the user touches the topmost panel i hit-test all views on each panels if a view is at this x/y.
If one view is found there, i set focus at it...this works for most views.
But i am lost with the ACTION_MOVE...

Is it somehow possible to reinject the "user action" to the target panels event handling list so it is processed by android once more?
Target should be that the panel react as it would be the topmost panel.

I found this...
// Obtain MotionEvent object
long downTime = SystemClock.uptimeMillis();
long eventTime = SystemClock.uptimeMillis() + 100;
float x = 0.0f;
float y = 0.0f;
// List of meta states found here: developer.android.com/reference/android/view/KeyEvent.html#getMetaState()
int metaState = 0;
MotionEvent motionEvent = MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_UP,
x,
y,
metaState
);

// Dispatch touch event to view
view.dispatchTouchEvent(motionEvent);

and this link...
http://stackoverflow.com/questions/5867059/android-how-to-create-a-motionevent

So it looks like the dispatchTouchEvent methode is the one i need?

thank you
Richard.
 
Last edited:

riko

Member
Licensed User
Longtime User
But how can i get the type "MotionEvent" which is needed for the dispatch method?

Richard.
 
Top