安卓NDK——原生开发工具包

NDK

(Native Development Kit )

概述

NDK是一个集成了Android交叉编译环境的工具集,并提供了一套比较方便的Makefile,可以帮助开发者快速开发C或者C++的动态库,并自动的将so和java程序打包成apk,在Android上运行。

原生开发工具包 (NDK) 是一套工具,允许您为 Android 使用 C 和 C++ 代码,并提供众多平台库,您可用其管理原生 Activity 和访问物理设备组件,例如传感器和触摸输入。NDK 可能不适合大多数 Android 编程初学者,这些初学者只需使用 Java 代码和框架 API 来开发应用。然而,如果您需要完成一或多个以下事项,那么 NDK 就能派上用场:

  • 进一步提升设备性能,以实现低延迟时间,或运行计算密集型应用,如游戏或物理模拟。
  • 重复使用您自己或其他开发者的 C 或 C++ 库。

优势 

  • C/C++的效率比较高
  • C/C++对涉及硬件操作的支持好

配置NDK开发环境

要为您的应用编译和调试原生代码,您需要以下组件:

  • Android 原生开发工具包 (NDK):这套工具允许您为 Android 使用 C 和 C++ 代码。
  • CMake:一款外部构建工具,可与 Gradle 搭配使用来构建原生库。如果您只计划使用 ndk-build,则不需要此组件。
  • LLDB:一种调试程序,Android Studio 使用它来调试原生代码。

下载

在较新版本的Android Studio中可以通过 Tools > Android > SDK Manager 方便的下载LLDBCMake 和 NDK

也可以通过?面的网站下载

https://developer.android.google.cn/ndk/downloads/index.html

目前:最新稳定版本 (r19c)、最新测试版 (r20 Beta 1)

官方也提供了demo的下载?

https://github.com/googlesamples/android-ndk

下载完毕后点击

如果是通过Android Studio下载的,点击Select defaul NDK即可自动填充路径

然后是环境变量

首先建一个...其实不建直接加path也可以,变量值为NDK的路径

JNI

JNI是Java Native Interface的缩写,译为JAVA本地调用。

Java Native Interface(JNI)标准从Java1.1开始成为java平台一部分,它允许java代码和其他语言写的代码进行交互。

JNI is the Java Native Interface. It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++). JNI is vendor-neutral, has support for loading code from dynamic shared libraries, and while cumbersome at times is reasonably efficient.

更多可以参考https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html

JNI程序实现步骤

  1. 编写带有native声明方法java类
  2. 使用javac命令编译所编写的java类
  3. 然后利用javah+java类名生成扩展名为h的头文件
  4. 使用C/C++实现本地方法
  5. 将C/C++编写的文件生成动态链接库
  6. 加载动态链接库文件,调用native方法,测试

 

 

 


案例

布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".MainActivity">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        android:gravity="center"
        android:id="@+id/number1"
        android:hint="第一个数字"/>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/number1"
        android:gravity="center"
        android:id="@+id/number2"
        android:hint="第二个数字"/>

    <Button
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toBottomOf="@+id/number2"
        android:text="求和"
        android:onClick="sum_button"
        android:id="@+id/sum_button"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@+id/sum_button"
        android:gravity="center"
        android:text="结果将显示在这里"
        android:textSize="20sp"
        android:id="@+id/sum_text"/>

</android.support.constraint.ConstraintLayout>

初步主体代码

package com.example.ndk;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private EditText number1, number2;
    private TextView sum_text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        number1 = findViewById(R.id.number1);
        number2 = findViewById(R.id.number2);
        sum_text = findViewById(R.id.sum_text);
    }

    //声明一个本地方法,该方法由C、C++实现
    public native int add(int num1, int num2);

    //按钮点击事件
    public void sum_button(View view) {
        String num1 = number1.getText().toString();
        String num2 = number2.getText().toString();
        //调用本地方法
        int result = add(Integer.parseInt(num1), Integer.parseInt(num2));
    }

}

JAVAH命令

java环境默认已经配好

打开终端,先通过一系列cd命令到项目的java路径下

粗体这段是你的包名

输入javah -jni com.example.ndk.MainActivity

md...很尴尬了

下面是探索解决过程的办法

https://blog.csdn.net/nishigesb123/article/details/90024821

但是最终还是没能解决,多方求助也还是未果

考虑到我的JDK版本和SDK比较新,怀疑是版本更新改了什么东西

试着去添加v4 v7包到classpath发现无论哪个版本的v4 v7包总会提示少个什么类

 

这篇文章永久性施工中——开工时间待定

 

部分参考:

https://developer.android.google.cn/training/articles/perf-jni

https://developer.android.google.cn/ndk/guides/ 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云无心鸟知还

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值