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