* An implementation of ValdiAction which calls the given function name on the actionHandler. * It uses Java's reflection to call the method. * IMPORTANT: Note that you must make sure the method doesn't get mangled by Proguard. */
| 13 | * IMPORTANT: Note that you must make sure the method doesn't get mangled by Proguard. |
| 14 | */ |
| 15 | class ValdiNativeAction(private val actionHandlerHolder: ValdiActionHandlerHolder, private val functionName: String, private val logger: Logger): ValdiAction { |
| 16 | |
| 17 | private var lastActionHandlerClass: Class<*>? = null |
| 18 | private var lastResolvedMethod: Method? = null |
| 19 | private var lastResolvedMethodHasMapParam = false |
| 20 | |
| 21 | @UiThread |
| 22 | private fun doPerform(parameters: Array<Any?>) { |
| 23 | val actionHandler = actionHandlerHolder.actionHandler |
| 24 | val actionHandlerClass = actionHandler?.javaClass |
| 25 | if (actionHandlerClass != lastActionHandlerClass) { |
| 26 | lastActionHandlerClass = actionHandlerClass |
| 27 | lastResolvedMethod = null |
| 28 | } |
| 29 | if (actionHandler == null || actionHandlerClass == null) { |
| 30 | return |
| 31 | } |
| 32 | |
| 33 | if (lastResolvedMethod == null) { |
| 34 | // Resolving the method to call on the actionHandler |
| 35 | try { |
| 36 | lastResolvedMethod = actionHandlerClass.getDeclaredMethod(functionName, Array<Any?>::class.java)!! |
| 37 | lastResolvedMethodHasMapParam = true |
| 38 | } catch (exc: NoSuchMethodException) { |
| 39 | try { |
| 40 | lastResolvedMethod = actionHandlerClass.getDeclaredMethod(functionName) |
| 41 | lastResolvedMethodHasMapParam = false |
| 42 | } catch (exc: NoSuchMethodException) { |
| 43 | } |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | val resolvedMethod = lastResolvedMethod |
| 48 | |
| 49 | if (resolvedMethod == null) { |
| 50 | logger.log(LogLevel.ERROR, "Unable to call function $functionName on ${actionHandler::class.java}. ActionHandler does not implement method.") |
| 51 | return |
| 52 | } |
| 53 | if (lastResolvedMethodHasMapParam) { |
| 54 | resolvedMethod.invoke(actionHandler, parameters) |
| 55 | } else { |
| 56 | resolvedMethod.invoke(actionHandler) |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | @AnyThread |
| 61 | override fun perform(parameters: Array<Any?>): Any? { |
| 62 | runOnMainThreadIfNeeded { |
| 63 | doPerform(parameters) |
| 64 | } |
| 65 | |
| 66 | return null |
| 67 | } |
| 68 | |
| 69 | } |