fix: Fix java.lang.NoSuchMethodError error for .toArrayList() (#322)

* fix: Fix `java.lang.NoSuchMethodError` error for `.toArrayList()`

* Fix `HashMap<K, V>` conversion to `jsi::Object`

* Update FRAME_PROCESSORS_CREATE_OVERVIEW.mdx
This commit is contained in:
Marc Rousavy 2021-08-04 16:07:08 +02:00 committed by GitHub
parent c5979688c8
commit b493576373
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 74 deletions

View File

@ -21,8 +21,6 @@
#include "java-bindings/JImageProxyHostObject.h"
#include "java-bindings/JImageProxy.h"
#include "java-bindings/JReadableArray.h"
#include "java-bindings/JReadableMap.h"
#include "java-bindings/JArrayList.h"
#include "java-bindings/JHashMap.h"
@ -128,59 +126,58 @@ jsi::Value JSIJNIConversion::convertJNIObjectToJSIValue(jsi::Runtime &runtime, c
return jsi::String::createFromUtf8(runtime, object->toString());
} else if (object->isInstanceOf(JReadableArray::javaClassStatic())) {
// ReadableArray
} else if (object->isInstanceOf(JArrayList<jobject>::javaClassStatic())) {
// ArrayList<E>
static const auto toArrayListFunc = JReadableArray::javaClassLocal()->getMethod<jni::JArrayClass<jobject>()>("toArrayList");
auto array = toArrayListFunc(object.get());
auto size = array->size();
auto result = jsi::Array(runtime, size);
for (size_t i = 0; i < size; i++) {
result.setValueAtIndex(runtime, i, convertJNIObjectToJSIValue(runtime, (*array)[i]));
}
return result;
} else if (object->isInstanceOf(JArrayList::javaClassStatic())) {
// ArrayList
static const auto iteratorFunc = JArrayList::javaClassLocal()->getMethod<jni::JIterator<jobject>()>("iterator");
static const auto sizeFunc = JArrayList::javaClassLocal()->getMethod<jint()>("size");
auto iterator = iteratorFunc(object.get());
auto size = sizeFunc(object.get());
auto arrayList = static_ref_cast<JArrayList<jobject>>(object);
auto size = arrayList->size();
auto result = jsi::Array(runtime, size);
size_t i = 0;
for (auto& item : *iterator) {
for (const auto& item : *arrayList) {
result.setValueAtIndex(runtime, i, convertJNIObjectToJSIValue(runtime, item));
i++;
}
return result;
} else if (object->isInstanceOf(JReadableMap::javaClassStatic())) {
// ReadableMap
} else if (object->isInstanceOf(react::ReadableArray::javaClassStatic())) {
// ReadableArray
static const auto toHashMapFunc = JReadableMap::javaClassLocal()->getMethod<jni::JHashMap<jstring, jobject>()>("toHashMap");
auto hashMap = toHashMapFunc(object.get());
static const auto toArrayListFunc = react::ReadableArray::javaClassLocal()->getMethod<JArrayList<jobject>()>("toArrayList");
// call recursive, this time ArrayList<E>
auto array = toArrayListFunc(object.get());
return convertJNIObjectToJSIValue(runtime, array);
} else if (object->isInstanceOf(jni::JHashMap<jstring, jobject>::javaClassStatic())) {
// HashMap<K, V>
auto map = static_ref_cast<jni::JHashMap<jstring, jobject>>(object);
auto result = jsi::Object(runtime);
for (const auto& entry : *hashMap) {
for (const auto& entry : *map) {
auto key = entry.first->toString();
auto value = entry.second;
auto jsiValue = convertJNIObjectToJSIValue(runtime, value);
result.setProperty(runtime, key.c_str(), jsiValue);
}
return result;
} else if (object->isInstanceOf(react::ReadableMap::javaClassStatic())) {
// ReadableMap
static const auto toHashMapFunc = react::ReadableMap::javaClassLocal()->getMethod<jni::JHashMap<jstring, jobject>()>("toHashMap");
// call recursive, this time HashMap<K, V>
auto hashMap = toHashMapFunc(object.get());
return convertJNIObjectToJSIValue(runtime, hashMap);
}
auto type = object->getClass()->toString();
auto message = "Received unknown JNI type \"" + type + "\"! Cannot convert to jsi::Value.";
__android_log_write(ANDROID_LOG_ERROR, "VisionCamera", message.c_str());
return jsi::Value::undefined();
throw std::runtime_error(message);
}
} // namespace vision

View File

@ -13,8 +13,9 @@ using namespace facebook;
using namespace jni;
// TODO: Remove when fbjni 0.2.3 releases.
struct JArrayList : public JavaClass<JArrayList> {
static constexpr auto kJavaDescriptor = "Ljava/util/ArrayList;";
template <typename E = jobject>
struct JArrayList : JavaClass<JArrayList<E>, JList<E>> {
constexpr static auto kJavaDescriptor = "Ljava/util/ArrayList;";
};
} // namespace vision

View File

@ -1,19 +0,0 @@
//
// Created by Marc Rousavy on 24.06.21.
//
#pragma once
#include <jni.h>
#include <fbjni/fbjni.h>
namespace vision {
using namespace facebook;
using namespace jni;
struct JReadableArray : public JavaClass<JReadableArray> {
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/ReadableArray;";
};
} // namespace vision

View File

@ -1,19 +0,0 @@
//
// Created by Marc Rousavy on 24.06.21.
//
#pragma once
#include <jni.h>
#include <fbjni/fbjni.h>
namespace vision {
using namespace facebook;
using namespace jni;
struct JReadableMap : public JavaClass<JReadableMap> {
static constexpr auto kJavaDescriptor = "Lcom/facebook/react/bridge/ReadableMap;";
};
} // namespace vision

View File

@ -39,8 +39,8 @@ Similar to a TurboModule, the Frame Processor Plugin Registry API automatically
| `number` | `NSNumber*` (double) | `Double` |
| `boolean` | `NSNumber*` (boolean) | `Boolean` |
| `string` | `NSString*` | `String` |
| `[]` | `NSArray*` | `ReadableNativeArray` |
| `{}` | `NSDictionary*` | `ReadableNativeMap` |
| `[]` | `NSArray*` | `ArrayList<E>` |
| `{}` | `NSDictionary*` | `HashMap<K, V>` |
| `undefined` / `null` | `nil` | `null` |
| `(any, any) => void` | [`RCTResponseSenderBlock`][4] | `(Object, Object) -> void` |
| [`Frame`][1] | [`Frame*`][2] | [`ImageProxy`][3] |