IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> djinni使用实践(三)--Android项目中的使用 -> 正文阅读

[移动开发]djinni使用实践(三)--Android项目中的使用

djinni使用实践(一) -- 官方文档

djinni使用实践(二) -- djinni究竟都有哪些配置选项

djinni使用实践(三)--Android项目中的使用

?????? 本篇是介绍djinni在Android项目中JNI开发的使用场景,所以默认大家有一定的Android JNI开发经验,此篇中涉及到的JNI相关的知识点不做介绍,大家可自行学习。

?????? djinni工具集成过程中需要用到该项目中的一些文件,我们先下载到本地以备使用

djinni项目地址

接下来先看下工程结构:

着重看下djinni相关的文件夹: api_generator

ok,工程整体结构大概就是这个样子,关于目录层级及目录名称大家可以按需调整。

???????? 接下来是构建整个项目中的第一个操作:根据djinni文件自动生成接口文件和bean文件,为了方便项目自动化构建我们将所有的要执行的命令行写成脚本文件。

info.djinni

//枚举
sex_mode_enum = enum {
	SEX_MAN;
	SEX_WOMAN;
}


//数据结构(java中的bean对象,c中的结构体)
test_info_store = record {
    id: i32;
	name: string;
	project: string;
	sex: sex_mode_enum;
}

//接口类
test_djnni_interface = interface +c {
	show(testInfo: test_info_store): string;
	static newInstance(): test_djnni_interface;
	const version: i32 = 1;
}

djinni文件编写可参考本系列第一篇文章。

generate.sh

#!/bin/bash

#返回这个脚本文件放置的目录
cd `dirname $0`

rm -rf ../auto_gen/*

djinniFile(){
	java -jar ./djinni.jar \
	     --idl ../api_idl/$1\
	     \
	     --cpp-namespace test::hello \
	     --cpp-out ../auto_gen/cpp_impl/ \
	     --cpp-header-out ../auto_gen/public/include/$2 \
	     --hpp-ext h \
	     --ident-cpp-enum FOO_BAR \
	     --ident-cpp-method FooBar \
	     \
	     --java-out ../auto_gen/java/$2/ \
	     --java-package com.zhoumohan.djinni.gen \
	     --java-use-final-for-record true \
	     --jni-out ../auto_gen/jni/$2 \
	     --ident-jni-class JNIFooBar \
	     --ident-jni-file JNIFooBar \
	     --java-implement-android-os-parcelable false \
	     \
	     --objc-out ../auto_gen/objc/$2 \
	     --objcpp-out ../auto_gen/objc-cpp/$2 \
	     --objc-swift-bridging-header "test-hello-Bridging-Header"

}

//调用djinniFile这个函数,后面为两个参数,对应函数中的$1、$2变量
djinniFile info.djinni "common"

关于脚本文件如何编写,可以参考本系列的文章的第二篇。

执行generate.sh? shell脚本文件,没有报错的话,此时auto_gen文件夹及子文件已经成功生成了。

不难看出其中的对应关系。

然后我们来实现自动生成的c++接口,这样我们就能在java层调用c层的方法实现了。

test_djinni_wrapper.cpp

接下来第二步就是把生成的文件放到android工程里,进行混合编译,为了自动化编译我们也写了一个脚本来做文件的映射(软连接)。

build_android.sh

#!/bin/bash

cd `dirname $0`
work_dir=$(pwd)

#配置ndk环境变量,将ndk的path赋值给ANDROID_NDK_ROOT
if [ $ANDROID_NDK_HOME ];then
  ANDROID_NDK_ROOT=$ANDROID_NDK_HOME
fi

echo $ANDROID_NDK_ROOT

function clean(){
  echo "clean"
	rm -rf CMakeCache.txt
	rm -rf CMakeFiles
	rm -rf cmake_install.cmake
	rm -rf Makefile
}

function unln_source_files {
	echo "unln_source_files"
	cd ..
	base_path=$(pwd)
  library_path=${base_path}/android_files/sample

  dest_support="${library_path}/app/src/main/cpp/support_lib"
  unlink ${dest_support}

  dest_jni="${library_path}/app/src/main/cpp/jni"
  for f in $(find $dest_jni -type l); do rm -rf $f; done

  dest_header="${library_path}/app/src/main/cpp/header"
  for f in $(find $dest_header -type l); do rm -rf $f; done

  dest_src="${library_path}/app/src/main/cpp/common_src"
  for f in $(find $dest_src -type l); do rm -rf $f; done

  dest_java="${library_path}/app/src/main/java/com/zhoumohan/djinni/gen"
  for f in $(find $dest_java -type l); do rm -rf $f; done

  dest_third="${library_path}/app/src/main/cpp/third_part"
  unlink ${dest_third}
}

function ln_source_files {
	echo "ln_source_files"

	base_path=$(pwd)
	library_path=${base_path}/android_files/sample

  # djinni库相关文件软链接
	source_support="${base_path}/api_generator/support_lib"
	dest_support="${library_path}/app/src/main/cpp/support_lib"
	ln -snf $source_support $dest_support

	# djinni生成的JNI接口文件的软链接
	source_jni="${base_path}/api_generator/auto_gen/jni/common/*"
	dest_jni="${library_path}/app/src/main/cpp/jni"
	
	# djinni生成C++头文件的软链接
	source_header="${base_path}/api_generator/auto_gen/public/include/common/*"
  dest_header="${library_path}/app/src/main/cpp/header"
    
  # 自己写的C++文件的软链接
  source_src="${base_path}/src/common/*"
  dest_src="${library_path}/app/src/main/cpp/common_src"

  # 生成的java文件的软链接
  source_java="${base_path}/api_generator/auto_gen/java/common/*"
  dest_java="${library_path}/app/src/main/java/com/zhoumohan/djinni/gen"


  # 第三方库(c++)的软链接
  source_third="${base_path}/third_part"
  dest_third="${library_path}/app/src/main/cpp/third_part"
  ln -snf $source_third $dest_third

  mkdir -p $dest_jni
  mkdir -p $dest_header
  mkdir -p $dest_src
  mkdir -p $dest_java

  ln -snf $source_jni $dest_jni
  ln -snf $source_header $dest_header
  ln -snf $source_src $dest_src
  ln -snf $source_java $dest_java
}

function build_android() {
  echo "build_android"
  pwd

  cd "android_files/sample/app/src/main/cpp"

  cmake . \
      -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake \
      -DCMAKE_SYSTEM_NAME=Android \
      -DANDROID_NDK=$ANDROID_NDK_ROOT \
      -DANDROID_ARM_NEON=ON \
      -DANDROID_PLATFORM=android-14 \
      -DANDROID_STL=c++_shared \
      -DANDROID_TOOLCHAIN=clang \
      -DCMAKE_BUILD_TYPE=Release \
      -DANDROID_ABI=armeabi-v7a

  make -j4
  clean
}


unln_source_files
ln_source_files
build_android

cd $work_dir



不过在执行此脚本之前配置你的sdk路径,及CMakeLists.txt的编写

CMakeLists.txt


#设置工程名
project("mytest")
#设置最低版本
cmake_minimum_required(VERSION 3.6.0)

#给变量赋值,设置编译参数,指定c++标椎库
#set(CMAKE_C_FLAGS_RELEASE "-std=c++11 -O2 -s ")
set(CMAKE_CXX_FLAGS_RELEASE "-std=c++11 -O2 ")
#set(CMAKE_C_FLAGS_DEBUG "-std=c++11 -O2 ")
set(CMAKE_CXX_FLAGS_DEBUG "-std=c++11 -O2 ")


set(COMMON_SRC_ROOT "./common_src/")
#加载以下路径中的所有文件
file(GLOB all_src
        "${COMMON_SRC_ROOT}/*.hpp"
        "${COMMON_SRC_ROOT}/*.cpp"
        )

#构建一个库供他人使用(库名称(name) 库类型 源文件),
#用于指定从一组源文件 source1 source2 … sourceN 编译出一个库文件且命名为 name
add_library(mytest SHARED
        ${all_src})

file(GLOB jni_src
        "${CMAKE_CURRENT_SOURCE_DIR}/jni/*.h"
        "${CMAKE_CURRENT_SOURCE_DIR}/jni/*.cpp"
        )
#向test库添加源文件
target_sources(mytest PRIVATE ${jni_src})

#添加头文件
target_include_directories(mytest PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/header
        )

#添加头文件
target_include_directories(mytest PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/support_lib/include/jni
        ${CMAKE_CURRENT_SOURCE_DIR}/support_lib/include
        )

file(GLOB support_src
        "${CMAKE_CURRENT_SOURCE_DIR}/support_lib/*.cpp"
        )
target_sources(mytest PRIVATE ${support_src})

set(PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../..)
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
    set_target_properties(mytest
            PROPERTIES
            ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_ROOT}/android_files/android_out/${CMAKE_ANDROID_ARCH_ABI}"
            LIBRARY_OUTPUT_DIRECTORY "${PROJECT_ROOT}/android_files/android_out/${CMAKE_ANDROID_ARCH_ABI}")
elseif (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
    set_target_properties(mytest
            PROPERTIES
            ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_ROOT}/android_files/android_out/${CMAKE_ANDROID_ARCH_ABI}/Debug"
            LIBRARY_OUTPUT_DIRECTORY "${PROJECT_ROOT}/android_files/android_out/${CMAKE_ANDROID_ARCH_ABI}/Debug")
endif()


find_library( log-lib
              log )

target_link_libraries( mytest
                       ${log-lib} )

大家可根据自己项目修改配置文件。

最后附上github地址,方便大家参考。djinniDemo

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 12:02:43  更:2022-05-10 12:04:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:50:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码