NDK(1)--体验NDK

      • NDK技术 是什么
      • 为什么使用NDK
      • 体验NDK怎么使用
          • 1 安装cygwin
          • 2 配置cygwin 的 ndk-build命令
          • 3 体验NDK 创建一个简单的 android 项目
    • 在AS中的简单调用

1. NDK技术 是什么

  • NDK就是AndroidJava代码去调用C/C++代码
  • NDK的本质就是JNI
  • JNI就是Java调用C/C++代码的一套编码规范
    D:\tz\android\NDK笔记\android-ndk-r12\platforms\android-21\arch-arm\usr\include\jni.h 这个目录下有对应的 规范

  • NDK技术基于JNI

2. 为什么使用NDK

  • 硬件
  • 性能(省略了中介过程)
  • 安全
    反编译微信的代码是找不到他的访问网络的代码就是访问网络的地址的代码,就是写到C函数里面去了.
  • C / JAVA(开源社区) 借助C/C++开源社区的类库

3. 体验NDK,怎么使用

  1. NDK 开发包(编译开发工具,示例程序,)
  2. 编译动态库的工具cygwin(Linux环境)

游戏引擎 cocos2d Unity3D
OpenGL 2d 3d图像引擎
OpenCV 图像识别 Face++(How old you ?)

1) 安装cygwin

本地安装 Daval Shalls
1. 如果没有本地安装文件的话,就去www.cygwin.com
2. 下载完之后就 双击打开,选择Download Without Installing
3. 然后他就会下载所需要的东西了, 不需要全部安装,只要安装DavalShalls 就可以了.
4. 然后再打开安装文件,选择从本地安装就可以了.

2) 配置cygwin 的 ndk-build命令

输入ndk-build 会提示:
-bash: ndk-build: 未找到命令

那跑到ndk的目录下去看看有没有这个命令

cd ..  -->  cd ..  -->  cd  cygdrive/ -->  cd c --> cd develop/ 

--> Users/LZQ/Desktop/NDK_Learning/android-ndk-r12/build --> ndk-build

(还是提示未找到命令,这就奇怪了,按理说应该是有的,反正我是试了很久都不行)

解决方法: 找到cygwin的安装目录C:\cygwin64\home\LZQ\.bash_profile在文件尾部加上

export ANDROID_NDK_HOME=/cygdrive/c/Users/LZQ/Desktop/NDK_Learning/android-ndk-r12/build
export PATH=$ANDROID_NDK_HOME:$PATH

重新打开cygwin, 输入ndk-build

Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
/cygdrive/c/Users/LZQ/Desktop/NDK_Learning/android-ndk-r12/build/core/build-local.mk:151: *** Android NDK: Aborting    。 停止。

这样就表示配置OK.

3) 体验NDK , 创建一个简单的 android 项目

CDT 高亮显示C关键字
C是弱类型语言(不规范)

    // 本地方法
    /** * 返回一个字符串 * @return */
    public native String getText();
#include <jni.h>
#include <string.h>

// jobject 就是当前调用本地方法的对象,就代表 MainActivity的对象
// 如果方法是static ,就要写成jclazz , 就代表当前的类
jstring Java_com_example_hellondk1_MainActivity_getText(JNIEnv* env,jobject obj){

    // NewStringUTF 一个产生UTF编码格式的字符串函数
    return (*env)->NewStringUTF(env,"hello ndk!");  // (**env).NewStringUTF()
}

建立一个jni文件夹

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := hello // 库的名称
LOCAL_SRC_FILES := hello.c // 需要编译的文件

include $(BUILD_SHARED_LIBRARY)
编译C文件报错
1. Android NDK: Host 'awk' tool is outdated. –> 直接删除android-ndk-r7\prebuilt\windows\bin\awk.exe文件
2. Android NDK: WARNING: APP_PLATFORM android-23 is larger than android:minSdkVersi –>在jni目录下创建Application.mk, 然后添加APP_PLATFORM := android-8 ,8替换为你项目的最小版本号
3. /bin/sh: NUL: Permission denied –>原因是编译的目录放在C盘,移动到其他盘编译即可

[arm64-v8a x86_64 mips64 armeabi-v7a armeabi x86 mips] Cygwin         : Generating dependency file converter script
[arm64-v8a] Compile        : hello <= hello.c
[arm64-v8a] SharedLibrary  : libhello.so
[arm64-v8a] Install        : libhello.so => libs/arm64-v8a/libhello.so
[x86_64] Compile        : hello <= hello.c
[x86_64] SharedLibrary  : libhello.so
[x86_64] Install        : libhello.so => libs/x86_64/libhello.so
[mips64] Compile        : hello <= hello.c
[mips64] SharedLibrary  : libhello.so
[mips64] Install        : libhello.so => libs/mips64/libhello.so
[armeabi-v7a] Compile thumb  : hello <= hello.c
[armeabi-v7a] SharedLibrary  : libhello.so
[armeabi-v7a] Install        : libhello.so => libs/armeabi-v7a/libhello.so
[armeabi] Compile thumb  : hello <= hello.c
[armeabi] SharedLibrary  : libhello.so
[armeabi] Install        : libhello.so => libs/armeabi/libhello.so
[x86] Compile        : hello <= hello.c
[x86] SharedLibrary  : libhello.so
[x86] Install        : libhello.so => libs/x86/libhello.so
[mips] Compile        : hello <= hello.c
[mips] SharedLibrary  : libhello.so
[mips] Install        : libhello.so => libs/mips/libhello.so

生成so动态库(libhello.so) ,会自动 加上 前面lib前缀 后面.so后缀

   // 加载动态库
   static{
    System.loadLibrary("hello");
   }

在AS中的简单调用

以上的使用时在cygwin加上eclipse的情况下进行调用的过程,cygwin有好几个优点就是可以明确看到编译过程中的错误,有提示,其实在as接触的不深不太清楚,现在就在说说在as上面是怎么实现的,毕竟现在的主流是as

1.首先是配置环境了,当然这个也很简单,其实就是下载ndk bundle,如下图
NDK(1)--体验NDK_第1张图片

当你下载完成之后,你的local.properties 也会配置好。如下图
NDK(1)--体验NDK_第2张图片

2.在AS中新建一个Project。然后新建一个classJNIUtils 当然也可以直接写在MainActivity中,

public class JNIUtils {


    static {
        System.loadLibrary("MyTestJNI");     //这个其实是对应4、的 build.gradle,后面你会看到
    }
    public native  String getCLanguageString();

}

3.然后在MainActivity中


public class MainActivity extends AppCompatActivity {

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

        tv = (TextView)findViewById(R.id.tv);

        JNIUtils jni = new JNIUtils();
        tv.setText(jni.getCLanguageString());
    }
}

4.然后在build.gradle中配置

defaultConfig {
        ......

        ndk{
            moduleName "MyTestJNI"          //生成的so名字
        }
    }

5.然后在main包下新建一个jni目录,然后开始写C,简单点,不做复杂逻辑,如下, 名字随便叫,我叫jnitest.c

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

// jobject 就是当前调用本地方法的对象,就代表 MainActivity的对象
// 如果方法是static ,就要写成jclazz , 就代表当前的类
jstring Java_com_example_lzq_ndk1_JNIUtils_getCLanguageString(JNIEnv* env,jobject obj){

    // NewStringUTF 一个产生UTF编码格式的字符串函数
    return (*env)->NewStringUTF(env,"hello ndk fuck you!");  // (**env).NewStringUTF()
}

6.很简单就是build工程,直接运行就可以了,当然你可能会遇到错误 《$USE_DEPRECATED_NDK=true》,解决方法,直接在gradle.properties中添加$USE_DEPRECATED_NDK=trueOK
7.然后运行,在这之前,也许1中的getCLanguageString 会报错,不要紧是因为没有生成so文件。运行之后就不报错了.

so文件生成的路径在app/build/intermediates/ndk/

NDK(1)--体验NDK_第3张图片

你可能感兴趣的:(android,cygwin,NDK)