-
Notifications
You must be signed in to change notification settings - Fork 26
Functions
The below are functions exported as global values in lua.'...' means repeating the previous one if following some code or means any if it's inside a body.
-
Imports a package or a class.
Usage:
import "android.os.*"
orimport "android.os.Process"
If you import a package then you can call
Type('shortName')
to get a type. For example,import "android.os.*" local p=class('Process') p.myPid() --or local pr=class('android.os.Process') pr.myPid()
If you import a Type then the returned value is the type and a global value named the short name is set. If the imported class is an inner class, avoid written '$' in the name though this can be handled, but no global value will be setted, instead, changing the character to '.', which makes it like general java syntax. If the short name is invalid java name or contains non-ascii characters, the global value won't be set, but you can still use the return value to get it; For example,
local p=import "android.os.Process" p.myPid() --or import "android.os.Process" Process.myPid() --or import "android.view.View.OnClickListener" print(OnClickListener.onClick)
By default,"java.lang.*", "java.util.*", "android.view.*", "android.widget.*", and "android.app.*" are imported,but only "java.lang.*" is allowed to be overwritten.
-
using :
Import all of the classes under the specified package, or add a external class loader. See import for the import way.
Usage:
using 'java.lang'
or using(externalClassLoader)For example:
using "android.os" Process.myPid() using "android.view.View" print(OnClickListener) --or using "java.lang" using(ClassLoader.getSystemClassLoader()) --for xposed environment only using "de.robv.android.xposed"
Note: The function is kind of time-consuming, especially at first call(about 40ms on my device), and will hold a large memory(around 1.5 m) to store all loaded class names.On the other hand, it can't make sure that all classes can be found,cause some classloaders may use proxy classloader to load classes.
Internally,it gets all classes like
dalvik.system.DexFile#entries
. For DexFile constructor has has been deprecated since Android O and unusable for boot class loader since Android P, I turned to read boot dex files from ClassLinker and return class list from classdefs since Android L. Dalvik need no optimization as no sort is performed, and current art runtime has been optimize by getClassList.For invalid characters in class name, see import
You can import an outer class as package to use its inner classes. No "$" is required.
If a previously imported class has the same name with the a class under the package, then the class won't be imported, but the previous class will be set to the global table.
using is not a really stable feature cause it's only available for known android version. Any new android version may break it's implementation expectation. If the device doesn't have enough memory, memory allocation error may occur, especially for old android version under 5.0. If you really care about stability, use import to feed your need. The function is design for saving time.
If you add a external class loader, then any class inside it is available for class or import.
-
new :
Constructs a new instance.
Usage1:
new(type,args...)
This is equal to call
type(args...)
ortype.new(args...)
.Usage2: 'new(typeName,args...)'
The type name can be both short or full. Moreover, you can add array length to the type name. So
new('String[][][]')
ornew ('String[1][2]')
ornew('int[1][2]',{2,4})
is allowed. Spaces are allowed around square brackets. e.g.import "java.lang.StringBuilder" new(StringBuilder,"haha") --or StringBuilder("haha") --or StringBuilder.new("haha") --or new('float[]',1,3,4) --{1,3,4} --or new('float[3]',1,2) --{1,2,0}
Note:
- If the type is a primitive type, then passing an argument after the type for this call is the same
as a forced conversion, e.g.
print(new('int','2'),int('2'),int.new('2'))--will prints 50 50 50
.See Value Conversion for detailed. - To construct an instance for a non-static inner class, you can use the new method added for the instance, and passing type and the arguments to the method, then the instance will be inserted as the first argument. Example:
inst.new(type,arg1,arg2,...)
- If the type is a primitive type, then passing an argument after the type for this call is the same
as a forced conversion, e.g.
-
newArray :
Constructs an array.
Usage:
newArray(ComponentType,length,initial args...)
The length of initial args must be less than or equal to the length. If the length==-1 then the length = the length of initial args. Function new can fully take over the function, so it's not suggested to use this function.
Alternative:
new(ArrayType,length,initial args...)
e.g.
newArray(class('String'),3,'hfh','hfht') --or new('int[]',-1,1,2,3) --array length is derived to be 4
Note:Never pass a type into the initial args.Type cast won't be accepted,since only one type is acceptable.Auto conversion will be performed if needed.
-
class :
Returns a type by give className,shortName or class
Usage:
class(full name)
orclass(short name)
orclass(Class Object)
class('java.lang.Object') --or class('Object') -- the package must be imported --or class(class('java.lang.Object').class)
Note: In module java the name is "type",the global function is changed to 'class' to avoid conflict with the internal function type,which returns the type of a lua object.
The name is used to be 'Type' while I suddenly find out that
using java.lang.reflect
will overlap the name. So I change it to 'class'To get a primitive type,pass it's name,e.g to get 'int', pass in 'int', rather than jni identifier 'I'.
The full name you pass in is the name from Class#getName,and the short Name is from Class#getSimpleName. For array type, both 'java.lang.String[]' or 'String[]' is ok. No space is allowed inner the around the square brackets.
For inner class, 'View$OnClickListener' ,'View.OnClickListener' and 'OnClickListener' are all qualified names.
You can put in multiple args actually, and the return values are according to the args' number. e.g.
ob,str=class('Object','String')
-
Gets an object representing the super object of current object. This method is designed for calling super method in the proxy callback. Or you can use it to call override method.
super(obj).instanceof(typeof(obj))
may still return true.super(obj).class
andtypeof(super(obj))
will return the super type.super(obj).getClass()
is the same asobj.getClass()
.Usage:
super(obj)
Equals to
obj.super
-
Gets the type of given obj.
Usage:
typeof(obj)
Equals to
class(obj.class)
-
To check whether the given object is an instance of the give type.
Equals to
object.instanceof(type)
Usage:
instanceof(object,type)
-
sync :
Equals to synchronized(object){...}
Usage:
sync(object,function()... end)
Note: before lua 5.3, yield is not supported inside the passed in function cause it will break lock scope and have object unlocked.
-
object :
Converts a lua object to java object,if no type provided, it works according to the following mapping,or it will works according to Automatic Conversion section The type is passed in like a general java method call. Primitive type is treated as its box type.
- number ->java.lang.Long or java.lang.Double,according to the value
- string ->java.lang.String
- boolean ->java.lang.Boolean
- userdata ->null
- table ->java.util.LinkedHashMap
- function ->com.oslorde.luadroid.LuaFunction
- java object is unchanged
Usage:
object(lua object...)
e.g.
using 'java.lang' i,k=object("Yu",Integer,1) --then i is a String object and k is an Integer object
-
unbox :
Unbox a serial boxed value,e.g. java.lang.Integer-> int. Other values will not be changed when unboxing and returned as it was. This method is designed for map operation for type like SparseArray.
Usage: 'unbox(boxedValue)'
-
try :
Starts java try,both lua error and java exception are caught.
Usage:
try(body function,[exception type,ecpection handler function]... ,["all",all exception handler function],[finally function]) --or try{ function () end,--body catch=function (e) end --catch all exceptions,alternative or --alternative { [exception type 1]=function (e) end, [exception type 2]=function (e) end, ... all=function catchAll(e) end }, finally=function () end--alternative }
e.g.
try{ function() throw(Type('RuntimeException')("haha")) end, catch=function (e) throw e end, finally=function print "JJ" end } --or try{ function() throw "haha" end, catch={ [Type('RuntimeException']=function (e) print(e) end, Exception=function (e) print(e) end, all=function (e) throw e end }, finally=function print "JJ" end }
The handler order and re-throw is according to java specifications However, you can just try without finally or catch, which will return the error code and the exception on error and nil on the other cases. The type can be a type name string rather than a java type.
Note:yield is supported inside any function you passed in since lua 5.3, but finally function may be un-called if yield not return. Lua built-in function pcall can also catch the error, while try will append stacktrace info to the error but pcall won't.
-
throw :
Throws a java exception, which ,while not an exception, will be converted to a string and wrapped as a LuaException, and finally, it will be caught by the above try function or try catch in your java code.
Usage:
throw(exception object)
e.g.
throw(class('RuntimeException')("haha")) throw "Ha Ha"
Notice: If you use pcall you will receive a java exception object as error info, and the exception won't be caught by upper try anymore. The call throw(java excption object) has the close meaning as error(java exception object) but differs by throw adding stacktrace info to the exception while error won't
-
proxy :
To implement interfaces ,alternatively plus with extending a class
Usage:
proxy([class to extend or object of class to extend], [interfaces to implement]..., [method name,parameter types...,handler function]..., [function] --for handling all the unspecified methods [shared classloader],--for extending only [initial args for constructor]...)--for extending only
or
proxy{ --auto detected,nilable super=class to extend or implement, object of class to extend, interfaces={interfaces to implement},--nilable --super and interfaces can't be nil at the same time methods={methodName= function(...) end,--function to handle all method with the same name --or { [param types...,function (...) end]...--handle specific method }, }, all=function(...) end --for handling all the unspecified methods --alternative,default is false for extension type only shared=true or false, --alternative for extension type only,constrctor args args={...} }
e.g.
proxy(Type('Runanble'),function() print 'ty' end).run() --or proxy(Type('Runanble'),'run',function() print 'ty' end).run() --or local obj=Type('ArrayList')(5) proxy(obj,'equals',function(thiz,name,obj) return obj==thiz end). equals(obj) --or proxy{ super=class('ArrayList'), methods={ equals=function(obj,thiz) return obj==thiz end }, shared=false, args={5} }
The callback function passed in will receive following args The first is this object represent the obj itself,and the second is the name, while the rest are the arguments passed in.
Note:
If you passed an object to extend,then the proxy object is directly allocated and have all fields from the object to be copied into the return object without constructor call. See ClassBuilder#cloneFromSuper for more information
Interface implementation is supported by java.lang.reflect.Proxy but class extension is supported by dexmaker, which may consume several time to generate and load a dex file.
Whether the object is multi-thread supported is determined by whether localFunction is set in the constructor of ScriptContext
When the object is multi-thread supported, then when functions are saved, their upvalues will be copied in. Make sure the function doesn't refers to any global value it can't access in another thread.
The function passed in for 'all' can't handler the following three method toString,hashCode,equals for they may trigger infinite loop when used by internal functions like print,==.Tho override them specified it by yourself