2021SC@SDUSC

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_INCLUDE(type, name) \
  type FlexNodeGet##name(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj)

#define FLEX_NODE_MEM_FUN_SET_INCLUDE(type, name) \
  void FlexNodeSet##name(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, type name)
//define可以替换多行的代码关键是要在每个换行的时候加上一个‘\’
class FlexNode {
 public:
  HPNodeRef mHPNode;
  FlexNode(JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller);
  void FlexNodeReset(JNIEnv* env, const base::android::JavaParamRef<jobject>& jcaller);

  // 通过JNI调用java方法 -----------------------------------------
  void FlexNodeFree(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
  void FlexNodeFreeRecursive(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);

  void FlexNodeInsertChild(JNIEnv* env,
                           const base::android::JavaParamRef<jobject>& obj,
                           jlong childPointer,
                           jint indext);
  void FlexNodeRemoveChild(JNIEnv* env,
                           const base::android::JavaParamRef<jobject>& obj,
                           jlong childPointer);
  void FlexNodeCalculateLayout(JNIEnv* 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 FlexNodeNodeMarkDirty(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
  bool FlexNodeNodeIsDirty(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
  void FlexNodeNodeSetHasMeasureFunc(JNIEnv* env,
                                     const base::android::JavaParamRef<jobject>& obj,
                                     jboolean hasMeasureFunc);
  void FlexNodeNodeSetHasBaselineFunc(JNIEnv* env,
                                      const base::android::JavaParamRef<jobject>& obj,
                                      jboolean hasMeasureFunc);
  void FlexNodemarkHasNewLayout(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
  bool FlexNodehasNewLayout(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
  void FlexNodemarkLayoutSeen(JNIEnv* env, const base::android::JavaParamRef<jobject>& 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();

FlexNode.cpp

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<jobject> 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<jobject>();
    } else {
      jobject java_object = env->GetObjectArrayElement(jnode_arr, idx->second);
      return base::android::ScopedJavaLocalRef<jobject>(env, java_object);
    }
  }

 private:
  std::map<HPNodeRef, size_t> node_ptr_index_map;
  jobjectArray jnode_arr;
};
Logo

智屏生态联盟致力于大屏生态发展,利用大屏快应用技术降低开发者开发、发布大屏应用门槛

更多推荐