06-NDK开发简介

NDK开发教程

Java世界 <-> JNI层 <-> Native世界

JNI : Java Native Interface,通常翻译为JAVA本地接口

NDK即Naive Development Kit

  • NDK是一系列工具的集合
    • NDK提供了工具链,帮助开发者快速开发以及调试C(或C++)的动态库
  • NDK提供了一份稳定、功能有限的API库
    • 不同于linux的glibc,Android采用的是 Google Bionic Libc,大部分api是一致的
  • 一些重要逻辑、算法可以采用C/C++、甚至是汇编的形式通过NDK的工具链最终编译生成动态库,最后通过JNI完成和Dalvik/ART虚拟机环境中的Java代码的交互
  • 使用NDK开发的so不再具有跨平台特性、需要编译提供不同平台支持ABI:Application Binary Interface
ABI支持的指令集备注
armeabi-v7aarmeabi与ARMv5/v6设备不兼容
Thumb-2
VFPv3-D16
armeabi-v8aAArch64
x86x86(IA-32)不支持MOVBE或SSE4
MMX
SSE/2/3
SSSE3
x86_64x86-64
MMX
SSE/2/3
SSSE3
SSE4.1、4.2
POPCNT

NDK 支持的架构详细信息可以在如下网页中查看

https://developer.android.google.cn/ndk/guides/abis?hl=zh_cn

如何创建一个NDK程序

File -> New -> New Project -> Native C++ , 就可以创建一个NDK程序

看一下默认创建的文件

MainActivity.java

package com.showme.ndk01;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // 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);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

app/src/main/cpp/native-lib.cpp

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_showme_ndk01_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

JNI函数特征一览

extern “C” : 由于C++支持重载,C++l类中的函数会有name mangling,后面会详细介绍为什么这里必须要有extern “C”

jni函数的参数问题(参数至少是两个):JNIEnv* 和jobject(非静态函数) 以及JNIEnv *和jclass(静态函数) 从第三个参数开始,才是java层传递的自己的参数

JNICALL : 空宏,只是确定一个规则,可以被删除

JNIEXPORT:__ attribute __((visibility(“default”))),代表当前函数符号需要导出,与之对应为hidden隐藏符号信息

android studio默认生成的函数名很长,如Java_com_example_jni_1enc_jni_String_StringFromJNI,以下划线分割

public native String stringFromJNI();
public static native String StringStatic();
extern "C" JNIEXPORT jstring JNICALL
Java_com_showme_myapplication_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_showme_myapplication_MainActivity_StringStatic(
        JNIEnv* env,
        jclass ) {
    std::string hello = "StringStatic Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

JNI可以使用C和CPP开发(extern “C”)

使用C语言编写程序,并在cpp中使用

testc.c

#include "testc.h"
int add_c(int a,int b){
    return a+b;
}

testc.h

#ifndef ABC_TESTC_H
#define ABC_TESTC_H

#include<stdio.h>
int add_c(int a,int b);

#endif ABC_TESTC_H
在cpp中使用testc.c中的函数,需要以extern "C"的方式引入头文件
extern "C" {
#include "testc.h"
}
需要将testc.c添加到CMakeList.txt文件中
add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED
             testc.c
             # Provides a relative path to your source file(s).
             native-lib.cpp )

JNI开发-日志

#include <android/log.h>

__android_log_print(int prio, const char* tag, const char* fmt, ...);

JNI当中的基本数据类型

Java类型本地类型(Native Type)描述
booleanjbooleanC/C++无符号8位整形 (unsigned char)
bytejbyteC/C++带符号8位整形(char)
charjcharC/C++无符号16位整形(unsigned short)
shortjshortC/C++带符号16位整形(short)
intjintC/C++带符号32位整形(int)
longjlongC/C++带符号64位整形(long)
floatjfloatC/C++32位浮点型(float)
doublejdoubleC/C++64位浮点型(double)
public native int IntFromJNI(int a);
extern "C" JNIEXPORT jint JNICALL
Java_com_showme_myapplication_MainActivity_IntFromJNI( JNIEnv* env, jobject /* this */, jint a) {
   returnu a + 1;
}
android-ndk-r18是Android软件开发工具包(NDK)的一个版本。NDK允许开发者使用C、C++和其他本地语言来开发Android应用程序。使用NDK开发者可以编写高性能和可移植的代码,并与Java代码进行混合编程。 android-ndk-r18是NDK的第18个稳定版本。这个版本包含了一些新的特性和改进,以提升开发者的开发体验和应用性能。其中一些特性包括: 1. 支持新的架构:android-ndk-r18引入了对新的CPU架构的支持,如ARMv8、x86和x86_64。开发者可以利用这些新的架构特性来编写更高效的代码,并为不同的平台提供最佳的性能。 2. CMake支持:这个版本引入了对CMake构建系统的支持。CMake是一个流行的开源构建系统,它可以帮助开发者更轻松地管理和构建复杂的项目。使用CMake,开发者可以更快速地配置和构建他们的NDK项目。 3. OpenMP支持:android-ndk-r18增加了对OpenMP并行程序设计的支持。OpenMP是一种面向共享内存多线程编程的API,可以帮助开发者更容易地编写和管理多线程应用程序。 4. LLVM更新:这个版本的NDK使用了最新的LLVM编译器,提供了更好的代码优化和性能。 总的来说,android-ndk-r18是一个强大的工具包,可以帮助开发者更好地开发高性能和可移植的Android应用程序。通过支持新的架构、引入CMake和OpenMP支持以及使用最新的LLVM编译器,这个版本提供了更多的工具和功能,以满足开发者的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值