NDK初步

栏目: C++ · 发布时间: 9年前

内容简介:NDK初步

环境搭建

在Android Studio上设置NDK的路径时,会自动下载NDK开发环境, 之后我们新建新工程选中 Include C++ Support 即可.

工程新建完成后,可以看到如上的目录,其中:

cpp中包含了所有项目中使用的native源码文件、头文件和预编译库。native-lib.cpp是Android Studio自动生成的一个sample文件,放在module的src/main/cpp中。

External Build Files中包含了CMake或ndk-build的编译脚本。CMakeLists.txt是Android Studio自动生成的一个CMake脚本,放在module的根目录中。

CMakeLists.txt

在我们的模块的build.gradle里,可以看到有Cmake的编译设置.

externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }

我们去看一下 CMakeLists.txt 文件

里面有如下配置

//声明库名称、类型、源码文件
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 )

// 将NDK库链接到native库中,这样native库才能调用NDK库中的函数
target_link_libraries( # Specifies the target library.
                      native-lib

                      # Links the target library to the log library
                      # included in the NDK.
                      ${log-lib} )

Java中调用Cpp的函数

当我们在 Java 文件写下

public native String getNativeString(Object obj);

时, AS便提示我们去完成这个native方法. 并自动帮我们生成了对应签名的jni文件.

JNIEXPORT jstring JNICALL
Java_com_jerey_testndk_MainActivity_getNativeString(JNIEnv *env, jclass type, jobject obj) {
    return env->NewStringUTF("hello");
}

这个是JNI签名的方法,代表只有com.jerey.testndk包里面的MainActivity类才能调用这个函数

我们在这里直接返回一个”hello”字符串. 为什么 NewStringUTF 呢, 因为C与Java中的字符串编码是不一样的, java中一个字符2个直接,c与c艹中是一个字节,所以需要转换一下.

此时看我们的Activity文件. Java文件中只 System.loadLibrary ,即可在文件中调用Lib里面的方法. 可以看到我们打印了一下getNativeString. 至于传参,后面有用.

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.e(TAG, "getNativeString: " + getNativeString(this));
    }

    public native String getNativeString(Object obj);

    public void callBack(String s) {
        Log.i(TAG, "callBack: " + s);
    }
}

注意, 我们的cpp文件中的方法, 必须被 extern "C" { 包裹着,由于jni走的是c的入口, 若不extern c,会直接报Jni找不到这个方法的异常.

此时,我们的程序是可以打印出”hello”了.

C++回调Java

我们上边的getNativeString,传了自己过去, 这是我的java思想导致的.不过可以先这么用.

我们在getNativeString时,完全可以回调自己的callback方法

extern "C" {
JNIEXPORT jstring JNICALL
Java_com_jerey_testndk_MainActivity_getNativeString(JNIEnv *env, jclass type, jobject obj) {

    jobject mJObj = env->NewGlobalRef(obj);
    jclass output = env->GetObjectClass(mJObj);
    // 拿到callBack方法
    jmethodID callback = env->GetMethodID(output, "callBack",
                                          "(Ljava/lang/String;)V");
    jstring jresult = env->NewStringUTF("callback string");
    env->CallVoidMethod(mJObj, callback, jresult);
    env->DeleteLocalRef(jresult);
    return env->NewStringUTF("hello");
}
}

上面的代码, 通过jni GetMethodID拿到了我们java类的callBack方法,并回调传入了”callback string”. log如下

06-02 13:12:10.840 25538-25538/com.jerey.testndk I/MainActivity: callBack: callback string

06-02 13:12:10.840 25538-25538/com.jerey.testndk E/MainActivity: getNativeString: hello

本文作者:Anderson/Jerey_Jobs

博客地址 :http://jerey.cn/

简书地址 : Anderson大码渣

github地址 : https://github.com/Jerey-Jobs


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

释放潜能:平台型组织的进化路线图

释放潜能:平台型组织的进化路线图

穆胜 / 人民邮电出版社 / 2017-12 / 59.80元

传统的组织模式中,企业逃不出“员工动不起来”和“创新乏力”的宿命。互联网改变商业逻辑的同时也改变了组织逻辑。平台型组织是匹配互联网商业逻辑的组织模式,它赋予了基层员工更多的责权利,能够在需求侧灵敏获取用户刚需、在供给侧灵活整合各类资源、用“分好钱”的机制激活个体去整合各类资源满足用户刚需,形 成供需之间的高效连接。 打造平台型组织有两大主题:一是通过设计精巧的激励机制让每个人都能感受到市场的压力,......一起来看看 《释放潜能:平台型组织的进化路线图》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具