Android之一个简单的NDK使用(一)
2017-10-05 15:55
309 查看
写在前面
刚入职那会,经理就布置了一道题目,由于涉及到NDK的知识,所以还是显得有些不知所措,但经理说不难,下载官方的Demo做些修改就可以搞定了。所以通过经理的一些提示和资料的查找,也算在周末里完成了,做了之后才发现这题确实不难……GitHub代码
同样地,这一篇也还是直接地写实现方法,然后也要其它时间写一些原理性地东西。另外由于经理对结构有一些要求,所以这道题目里也做了一些调整,可能会被看作是“过度设计”。
另外这里用的是Android Studio 2.2后使用的CMake,所以应该是跟之前需要的使用mk的方法不一样,当时不了解,看了一些文章比较旧,所以有些概念混淆了,是经理提醒了才明白。
结构和流程
同样地先看下结构这个project里包含了两个module,app和library,library是个依赖库,用于提供C++的方法。
主要的实现流程:
Created with Raphaël 2.1.0开始build.gradle里添加CMake使用编写C(C++)代码CMakeLists文件里添加C依赖app里使用编写好的C(C++)结束
实现
library
1. 添加CMake
在创建library后需要在build.gradle里添加CMake的使用:android { defaultConfig { externalNativeBuild { cmake { cppFlags "-frtti -fexceptions" } } } externalNativeBuild { cmake { path "CMakeLists.txt" } } }
2. 编写C(C++)代码
在main目录下创建cpp文件夹,在这里进行C代码的编写。本来只有一个native-lib.cpp,但后来我还是做了拆分。calculateBeerResult.cpp和calculateBeerResult.h是对计算方法的封装,把.cpp里的方法在.h头部文件里进行声明,这样我们在native-lib.cpp里引用calculateBeerResult.h的时候就能使用该方法了。
如下:
calculateBeerResult.cpp
#include "calculateBeerResult.h" /** * 返回一个int数组 * 第一个数表示已经喝的瓶数 * 第二个数表示剩下的空瓶子 * 第三个数表示剩下的盖子 */ int* calculateBeerResult(int money){ //总价格 int allMoney = money; //已经喝的瓶数 int drunkBottle = allMoney / 2; //剩下的空瓶子 int emptyBottle = drunkBottle; //剩下的瓶盖 int top = drunkBottle; int size = 3; int *result = new int[size]; while (emptyBottle >= 2 || top >= 4) { int tmp = emptyBottle / 2 + top / 4; drunkBottle = drunkBottle + tmp; emptyBottle = tmp + emptyBottle % 2; top = tmp + top % 4; } result[0] = drunkBottle; result[1] = emptyBottle; result[2] = top; return result; }
calculateBeerResult.h
#ifndef DRINKBEER_CALCULATEBEERRESULT_H #define DRINKBEER_CALCULATEBEERRESULT_H //声明我们写的计算方法 int* calculateBeerResult(int money); #endif //DRINKBEER_CALCULATEBEERRESULT_H
native-lib.cpp
#include <jni.h> #include "calculateBeerResult.h" //引入计算方法的头部 extern "C" JNIEXPORT jintArray JNICALL Java_message_license_szca_com_drinkbeer_presenter_CalculateBeerPresenter_getCalculateResult( JNIEnv *env, jobject /* this */, int money//java传进来的金额) { //因为返回的结果是个数组,所以这里查阅后使用了指针这种方法 int *result = calculateBeerResult(money); int size = sizeof(result); jintArray arry = env->NewIntArray(size); env->SetIntArrayRegion(arry, 0, size, result); return arry; }
这样我们就可以看出来,在native-lib.cpp里,主要是接收java传进来的金额,然后通过计算后,返回一个数组结果给java即可。
3. CMakeLists文件里添加C依赖
在当前module目录下的CmakeLists.txt里添加我们用到的C文件:# For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). src/main/cpp/native-lib.cpp ) add_library( calculateBeerResult SHARED src/main/cpp/calculateBeerResult.cpp) # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. target_link_libraries( # Specifies the target library. native-lib calculateBeerResult # Links the target library to the log library # included in the NDK. ${log-lib} )
app
1. app使用编写好的C
在app这个module里我们要做的就只是对我们编写的C的引用,传入数据和获取结果即可:public class CalculateBeerPresenter { //1.声明我们要引入的cpp文件 static { System.loadLibrary("native-lib"); } //2.声明我们要使用该cpp文件里的哪个方法 public native int[] getCalculateResult(int money); private Activity mContext; private ICalculateBeerView mICalculateBeerView; public CalculateBeerPresenter(Activity context , ICalculateBeerView iCalculateBeerView){ this.mContext = context; this.mICalculateBeerView = iCalculateBeerView; } /** * 计算结果 * @param str */ public void calculateBeer(String str) { String input = str; if (TextUtils.isEmpty(input)) { mICalculateBeerView.calculateFailed("输入金额"); return; } //3.调用该方法 int result[] = getCalculateResult(Integer.valueOf(input)); mICalculateBeerView.calculateSuccess(result); } }
至此,我们就完成了一个简单的NDK的使用。
相关文章推荐
- Android之一个简单的NDK使用(二)
- 使用Android-studio简单实现一个NDK的例子
- 一个简单的demo学习Android远程Service(AIDL的使用)
- 一个简单的demo学习Android远程Service(AIDL的使用
- Android之使用VideoView组件播放一个简单的视频
- 用Eclipse+Cygwin+CDT+NDK来创建一个简单的Android JNI 项目
- Android的NDK开发(2)————利用Android NDK编写一个简单的HelloWorld
- Android之使用MediaPlayer和SurfaceView组件播放一个简单的视频
- android 使用Eclipse开发NDK的配置和简单使用
- Android的NDK开发(2)————利用Android NDK编写一个简单的HelloWorld
- Android的NDK开发(2)——利用Android NDK编写一个简单的HelloWorld
- 使用html写一个android关于界面,事情原来可以如此简单
- Android NDK rb5 文档之使用 Android 工具链作为一个独立编译器
- 第二章:Android之NDK配置与简单使用
- android 一个简单的CardView的 使用
- 打造支持apk下载和html5缓存的 IIS(配合一个超简单的android APP使用)具体解释
- Android的NDK开发(2)————利用Android NDK编写一个简单的HelloWorld
- 【Android】使用Chronometer组件实现一个简单的计时器
- Android中使用WebView去构建一个简单的web app.
- android 一个小例子说明handler和AlertDialog的简单使用