11import CJNI
2+ import Dispatch
23
34/// Designed to simplify calling a constructor and methods on a JavaClass
45/// Subclass this and add the methods appropriate to the object you are constructing.
56open class JNIObject {
6- public let javaClass : JavaClass
7+ open class var className : String {
8+ return " java.lang.object "
9+ }
10+
11+ private static var classInstances = [ String: JavaClass] ( )
12+
13+ public static var javaClass : JavaClass {
14+ return DispatchQueue . main. sync {
15+ if let classInstance = classInstances [ className] {
16+ return classInstance
17+ }
18+
19+ let javaClassLocalRef = try ! jni. FindClass ( name: className. replacingFullstopsWithSlashes ( ) )
20+ try ! checkAndThrowOnJNIError ( )
21+ let classInstance = jni. NewGlobalRef ( javaClassLocalRef) !
22+ classInstances [ className] = classInstance
23+
24+ return classInstance
25+ }
26+ }
27+
728 public let instance : JavaObject
829
930 required public init ( _ instance: JavaObject ) throws {
1031 guard let globalInstanceRef = jni. NewGlobalRef ( instance) else {
1132 throw Error . couldntCreateGlobalRef
1233 }
1334
14- let javaClassLocalRef = try jni. GetObjectClass ( obj: instance)
15- let javaClass = jni. NewGlobalRef ( javaClassLocalRef)
1635 try checkAndThrowOnJNIError ( )
17- self . javaClass = javaClass!
1836 self . instance = globalInstanceRef
1937 }
2038
39+ @available ( * , deprecated, message: " Override Self.className instead and use the initializers that don't take className as an argument " )
2140 convenience public init ( _ className: String , arguments: [ JavaParameterConvertible ] = [ ] ) throws {
2241 let className = className. replacingFullstopsWithSlashes ( )
2342 let javaClassLocalRef = try jni. FindClass ( name: className)
@@ -29,22 +48,39 @@ open class JNIObject {
2948 try self . init ( instanceLocalRef)
3049 }
3150
51+ convenience public init ( arguments: JavaParameterConvertible ... ) throws {
52+ guard let instanceLocalRef = try jni. callConstructor ( on: type ( of: self ) . javaClass, arguments: arguments) else {
53+ throw Error . couldntCallConstructor
54+ }
55+
56+ try self . init ( instanceLocalRef)
57+ }
58+
3259 deinit {
3360 jni. DeleteGlobalRef ( instance)
34- jni. DeleteGlobalRef ( javaClass)
3561 }
3662
3763 public func call( methodName: String , arguments: [ JavaParameterConvertible ] = [ ] ) throws {
3864 try jni. call ( methodName, on: self . instance, arguments: arguments)
3965 }
4066
41- public func call< T: JavaInitializableFromMethod & JavaParameterConvertible > ( methodName: String , arguments: [ JavaParameterConvertible ] = [ ] ) throws -> T {
67+ public func call< T: JavaInitializableFromMethod & JavaParameterConvertible > (
68+ methodName: String ,
69+ arguments: [ JavaParameterConvertible ] = [ ]
70+ ) throws -> T {
4271 return try jni. call ( methodName, on: self . instance, arguments: arguments)
4372 }
4473
45- public func callStatic( methodName: String , arguments: [ JavaParameterConvertible ] = [ ] ) throws {
74+ public static func callStatic( methodName: String , arguments: [ JavaParameterConvertible ] = [ ] ) throws {
4675 try jni. callStatic ( methodName, on: self . javaClass, arguments: arguments)
4776 }
77+
78+ public static func callStatic< T: JavaInitializableFromMethod & JavaParameterConvertible > (
79+ methodName: String ,
80+ arguments: [ JavaParameterConvertible ] = [ ]
81+ ) throws -> T {
82+ return try jni. callStatic ( methodName, on: self . javaClass, arguments: arguments)
83+ }
4884}
4985
5086extension JNIObject {
@@ -55,7 +91,10 @@ extension JNIObject {
5591}
5692
5793extension JNI {
58- func callConstructor( on targetClass: JavaClass , arguments: [ JavaParameterConvertible ] = [ ] ) throws -> JavaObject ? {
94+ func callConstructor(
95+ on targetClass: JavaClass ,
96+ arguments: [ JavaParameterConvertible ] = [ ]
97+ ) throws -> JavaObject ? {
5998 let methodID = _env. pointee. pointee. GetMethodID ( _env, targetClass, " <init> " , arguments. methodSignature ( returnType: nil ) )
6099 try checkAndThrowOnJNIError ( )
61100
@@ -64,19 +103,19 @@ extension JNI {
64103}
65104
66105public extension JNI {
67- public func NewObject( targetClass: JavaClass , _ methodID: JavaMethodID , _ args: [ JavaParameter ] ) throws -> JavaObject ? {
68- let env = self . _env
106+ func NewObject( targetClass: JavaClass , _ methodID: JavaMethodID , _ args: [ JavaParameter ] ) throws -> JavaObject ? {
107+ let env = self . _env
69108 var mutableArgs = args
70109 let newObject = env. pointee. pointee. NewObject ( env, targetClass, methodID, & mutableArgs)
71110 try checkAndThrowOnJNIError ( )
72111
73112 return newObject
74- }
113+ }
75114
76- public func GetObjectClass( obj: JavaObject ) throws -> JavaClass {
77- let env = self . _env
115+ func GetObjectClass( obj: JavaObject ) throws -> JavaClass {
116+ let env = self . _env
78117 let result = env. pointee. pointee. GetObjectClass ( env, obj)
79118 try checkAndThrowOnJNIError ( )
80119 return result!
81- }
120+ }
82121}
0 commit comments