2021SC@SDUSC
- layout/android/jni
- JNI是什么?
- FlexNode.h
- FlexNode.cpp
JNI是Java Native Interface的缩写,通过使用Java本地接口书写程序,可以确保代码在不同的平台上方便移植,从java1.1开始,JNI标准成为java平台的一部分,它允许java代码和其他语言写的代码进行交互,JNI一开始是为了与本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其它编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台的可移植性,但是,有些情况下这样做是可以接受的,甚至是必须的,例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能,JNI标准至少要保证本地代码能工作在任何java虚拟机环境
FlexNode.h#pragma once //一个比较常用的C/C++预处理指令,只要在头文件最开始加入这条预处理指令,就能保证头文件只被编译一次 #includeFlexNode.cpp#include "../../engine/Hippy.h" #include "scoped_java_ref.h" #define FLEX_NODE_MEM_FUN_GET_INCLUDE(type, name) type FlexNodeGet##name(JNIEnv* env, const base::android::JavaParamRef & obj) #define FLEX_NODE_MEM_FUN_SET_INCLUDE(type, name) void FlexNodeSet##name(JNIEnv* env, const base::android::JavaParamRef & obj, type name) //define可以替换多行的代码关键是要在每个换行的时候加上一个‘’ class FlexNode { public: HPNodeRef mHPNode; FlexNode(JNIEnv* env, const base::android::JavaParamRef & jcaller); void FlexNodeReset(JNIEnv* env, const base::android::JavaParamRef & jcaller); // 通过JNI调用java方法 ----------------------------------------- void FlexNodeFree(JNIEnv* env, const base::android::JavaParamRef & obj); void FlexNodeFreeRecursive(JNIEnv* env, const base::android::JavaParamRef & obj); void FlexNodeInsertChild(JNIEnv* env, const base::android::JavaParamRef & obj, jlong childPointer, jint indext); void FlexNodeRemoveChild(JNIEnv* env, const base::android::JavaParamRef & obj, jlong childPointer); void FlexNodeCalculateLayout(JNIEnv* env, const base::android::JavaParamRef & obj, jfloat width, jfloat height, const base::android::JavaParamRef & nativeNodes, const base::android::JavaParamRef & javaNodes, jint direction); void FlexNodeNodeMarkDirty(JNIEnv* env, const base::android::JavaParamRef & obj); bool FlexNodeNodeIsDirty(JNIEnv* env, const base::android::JavaParamRef & obj); void FlexNodeNodeSetHasMeasureFunc(JNIEnv* env, const base::android::JavaParamRef & obj, jboolean hasMeasureFunc); void FlexNodeNodeSetHasbaselineFunc(JNIEnv* env, const base::android::JavaParamRef & obj, jboolean hasMeasureFunc); void FlexNodemarkHasNewLayout(JNIEnv* env, const base::android::JavaParamRef & obj); bool FlexNodehasNewLayout(JNIEnv* env, const base::android::JavaParamRef & obj); void FlexNodemarkLayoutSeen(JNIEnv* env, const base::android::JavaParamRef & obj); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, Width); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, Width); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, Height); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, Height); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, Left); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, Left); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, Top); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, Top); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, Right); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, Right); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, Bottom); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, Bottom); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, MarginLeft); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, MarginLeft); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, MarginTop); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, MarginTop); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, MarginRight); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, MarginRight); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, MarginBottom); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, MarginBottom); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, PaddingLeft); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, PaddingLeft); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, PaddingTop); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, PaddingTop); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, PaddingRight); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, PaddingRight); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, PaddingBottom); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, PaddingBottom); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, BorderLeft); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, BorderLeft); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, BorderTop); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, BorderTop); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, BorderRight); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, BorderRight); FLEX_NODE_MEM_FUN_GET_INCLUDE(jfloat, BorderBottom); FLEX_NODE_MEM_FUN_SET_INCLUDE(jfloat, BorderBottom); private: virtual ~FlexNode(); // DISALLOW_COPY_AND_ASSIGN(FlexNode); }; bool RegisterFlexNode(JNIEnv* env); JNIEnv* GetJNIEnv();
LayoutContext类
class LayoutContext {
public:
LayoutContext(jlongArray nativeNodes, jobjectArray javaNodes) {
// 1.设置HPNodes和java nodes的映射指针
jboolean isCopy = JNI_FALSE;
JNIEnv* env = GetJNIEnv();
jlong* flexNodes = env->GetLongArrayElements(nativeNodes, &isCopy);
jsize size = env->GetArrayLength(nativeNodes);
for (int i = 0; i < size; i++) {
HPNodeRef hpNode = _jlong2HPNodeRef(flexNodes[i]);
ASSERT(hpNode != nullptr);
node_ptr_index_map[hpNode] = i;
}
env->ReleaseLongArrayElements(nativeNodes, flexNodes, 0);
// 2.保存java数组
ASSERT(size == env->GetArrayLength(javaNodes));
jnode_arr = javaNodes;
}
base::android::ScopedJavaLocalRef get(HPNodeRef node) {
JNIEnv* env = GetJNIEnv();
auto idx = node_ptr_index_map.find(node);
if (idx == node_ptr_index_map.end()) {
return base::android::ScopedJavaLocalRef();
} else {
jobject java_object = env->GetObjectArrayElement(jnode_arr, idx->second);
return base::android::ScopedJavaLocalRef(env, java_object);
}
}
private:
std::map node_ptr_index_map;
jobjectArray jnode_arr;
};



