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: 2,018
  • Reflection2.4.zip
    33 KB · Views: 4,277
Last edited:

stevel05

Expert
Licensed User
Longtime User
Why are you using reflection to do this?

you can just do

B4X:
Dim c As myclass
c.initialize
c.i = 10
Log(c.i)

using the get setters you have setup.

Although you do need to add the initialize sub in the class, even if it's empty.

B4X:
Sub initialize
End Sub

If you are experimenting and just curious, then a quick look at the generated java source code (in the objects folder) for the class shows that the variable is prefixed with a "_" so

B4X:
Dim r As Reflector
r.Target=c
R.GetField("_v_i")
works.
 
Last edited:

mterveen

Member
Licensed User
Longtime User
get field info

my main goal was to try to figure out how to get the type of a variable in a class. thanks for your example/explanation. i would have NEVER figured out i need the "_" prefix! need to read up on the generated source code a bit it looks like. (thx for the response also in the other thread. exactly what i needed).

using the getfieldinfo member gives me all the info i need. although i can parse it for the field type, i was wondering if there are "sub members" that can be called that specifically pull out the type?
 

stevel05

Expert
Licensed User
Longtime User
Yes, there are. Have a look at the Field documentation link in the other thread.

Sent from my HTC Sensation XE with Beats Audio Z715e using Tapatalk 4 Beta
 

padvou

Active Member
Licensed User
Longtime User
I'm a :sign0104: on reflection lib ...
Why does this :
B4X:
Dim r As Reflector
    r.Target = r.GetContext
    r.Target = r.RunMethod2("getSystemService", "POWER", "java.lang.String")

  r.RunMethod("goToSleep")
produce this:
B4X:
java.lang.NullPointerException


   at anywheresoftware.b4a.agraham.reflection.Reflection.runmethod(Reflection.java:205)
   at anywheresoftware.b4a.agraham.reflection.Reflection.RunMethod(Reflection.java:802)
   at b4a.example.main._button1_click(main.java:285)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:157)
   at anywheresoftware.b4a.BA.raiseEvent(BA.java:153)
   at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:63)
   at android.view.View.performClick(View.java:3549)
   at android.view.View$PerformClick.run(View.java:14393)
   at android.os.Handler.handleCallback(Handler.java:605)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:154)
   at android.app.ActivityThread.main(ActivityThread.java:4945)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
   at dalvik.system.NativeStart.main(Native Method)
java.lang.NullPointerException
?
 

stevel05

Expert
Licensed User
Longtime User
Looking at the documentation for getSystemService "power" should be lowercase.

Next you'll find that goToSleep requires a parameter of type long.
 
Last edited:

padvou

Active Member
Licensed User
Longtime User
Looking at the documentation for getSystemService "power" should be lowercase.

Next you'll find that goToSleep requires a parameter of type long.

You mean like this:
B4X:
r.Target = r.RunMethod2("getSystemService", "power", "java.lang.String")
?
I looked also at the documentation but I don't understand what this value is, what to enter and how to code it...

I added this:
B4X:
Dim now As Long = DateTime.now
r.RunMethod2("goToSleep",now,"java.lang.long")

but now I get this:
B4X:
java.lang.SecurityException: Neither user 10219 nor current process has android.permission.DEVICE_POWER.

This is my manifest:
B4X:
AddManifestText(
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="14"/>
<supports-screens android:largeScreens="true" 
    android:normalScreens="true" 
    android:smallScreens="true" 
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
AddPermission(android.permission.DEVICE_POWER)
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
OK, that's as far as my knowledge goes on this then, I don't have a rooted device. I hope someone can help you.
 

Rusty

Well-Known Member
Licensed User
Longtime User
I would like to assign Tags to views (mostly buttons). To do this, I envision using reflection or ? to dynamically load the Tag information into views based upon a list of viewnames and related Tag values.
My thought is to read a datatable containing view names and Tag values; assign the named view the tag value.
Is there a way to do this?
B4X:
View name: btnOne
View Tag: 5

reflect.Target = "btnOne"
reflect.SetField2("tag", 5)
Thanks in advance.
Rusty
 

stevel05

Expert
Licensed User
Longtime User
Tag is a property of View (the highest level view) so you should be able to do something like:

B4X:
Dim v As View
v=Button1
v.Tag="B1"
v=ImageView1
v.Tag="IV1"


Log(Button1.Tag)
Log(ImageView1.Tag)

It may not work for all views especially if they are custom views, it depends on how they are wrapped, but that's where I'd start. No need for reflection.
 

warwound

Expert
Licensed User
Longtime User
This is my manifest:
B4X:
AddManifestText(
<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="14"/>
<supports-screens android:largeScreens="true" 
    android:normalScreens="true" 
    android:smallScreens="true" 
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
AddPermission(android.permission.DEVICE_POWER)

Compile your project and then open the manifest.xml in a text editor - has the permission android.permission.DEVICE_POWER been added?

Martin.
 

intera

Member
Licensed User
Longtime User
Compile your project and then open the manifest.xml in a text editor - has the permission android.permission.DEVICE_POWER been added?

Martin.


Hi Martin and Padvou

Hi the same happens to me and also on a rooted device.....
The manifest include that permission (seeing with notepad as you suggested)
any idea ?
thanks in advanced

BTW my workaround is to reduce the screen_off_timeout with this:

B4X:
'   ok pues ahora vamos a ponerlo a 0.1 segundo y luego habra que resetearlo

  Dim SettingName,SettingValue As String


SettingName="screen_off_timeout"'en minusculas!!!!

SettingValue="100"'10 segusndos para probar....300 milisecs...siempre tarda 3 segs...con el -1 al emnos lo hace sin hacer un dim priemro..


    Dim r As Reflector

  Dim cr AsObject'for storing the ContentResolver needed by android.provider.Settings.System")

   

  r.Target = r.GetContext

  cr = r.RunMethod("getContentResolver")

   

  Dim args(3) As Object

  args(0) = cr

  args(1) = SettingName

  args(2) = SettingValue

   

  Dim Types(3) As String

  Types(0) = "android.content.ContentResolver"

  Types(1) = "java.lang.String"

  Types(2) =  "java.lang.String"

   

  Log("y el lockscreeen off se cambio OK:" & r.RunStaticMethod("android.provider.Settings$System", "putString", args, Types))'ojo es "putString""""

But some how it does no works as spected and there is a 3 secs delay...(probably it is phone dependant or a safety isuue....)

PS:ADVICE if you use this code be EXTRA CAREFULL to listen for the screen_off (I did it with the phone LIB (PE_ScreenOff) intent to reset this value to the original one(or anyone bigger than 300 msecs......
 
Last edited:

b4auser1

Well-Known Member
Licensed User
Longtime User
I need to intecept events from Spinner, but Reflection library doesn't support setOnItemClickListener :(
B4X:
java.lang.RuntimeException: Don't call setOnClickListener for an AdapterView. You probably want setOnItemClickListener instead
Is there a plan to add setOnItemClickListener support to the Reflection library?
 

b4auser1

Well-Known Member
Licensed User
Longtime User
Why not use the built-in ItemClick event?
I used ItemClick event in the activity as a workaround,
B4X:
Sub AB_spnListSelector_ItemClick (Position As Int, Value As Object)
    CallSub3(m_clsAB_Panel, "spnListSelector_ItemClick", Position, Value)
End Sub
but my idea was to encapsulate all functionality inside the class spnListSelector, separated from the Activity
module.
 
Top