记录下 Android Studio 嵌入 C 代码的过程,使用 ndk-build.
当前环境:Android Studio 3.51 NDK 20.1

创建 JNI 文件夹
Android结构下,直接在项目右键,选择 New - Folder - JNI Folder ,对话框直接点击 Finish 即可方便地在默认位置创建 jni 文件夹用于存放 c 源码。默认位置在 app/src/main/jni.
Android Studio 3.5 JNI (ndk-build)_第1张图片
创建 Java 类

package cn.sh.changxing.myled;public class JniLib {    static {        System.loadLibrary("JniLib");    }    public native int led_open();    public native int led_close();    public native int ledIoctl(int num, int en);}

生成头文件 (.h)
Android Studio 3.5 JNI (ndk-build)_第2张图片
这边可以在External Tools中配置:
每次都这样搞一遍很麻烦,我们可以配置一下扩展工具,这样一劳永逸。

点击File - Setting - Tools - External Tools 打开外部工具配置页,点击 + 新建一个工具。

先起个名字叫,这里叫做 javah.

Program: J D K P a t h JDKPath JDKPath\bin\javah.exe
Arguments: -classpath . -jni -d M o d u l e F i l e D i r ModuleFileDir ModuleFileDir\src\main\jni F i l e C l a s s FileClass FileClass
Working directory: M o d u l e F i l e D i r ModuleFileDir ModuleFileDir\src\main\Java
(上面三行直接复制添加)点击 OK 保存后就新建了一个工具。此时我们右击 JniTest.java,在菜单中选择 External Tools - javah 就可以快速生成头文件并放到 jni 目录。

/* DO NOT EDIT THIS FILE - it is machine generated */#include /* Header for class cn_sh_changxing_myled_JniLib */#ifndef _Included_cn_sh_changxing_myled_JniLib#define _Included_cn_sh_changxing_myled_JniLib#ifdef __cplusplusextern "C" {#endif/* * Class:     cn_sh_changxing_myled_JniLib * Method:    led_open * Signature: ()I */JNIEXPORT jint JNICALL Java_cn_sh_changxing_myled_JniLib_led_1open  (JNIEnv *, jobject);/* * Class:     cn_sh_changxing_myled_JniLib * Method:    led_close * Signature: ()I */JNIEXPORT jint JNICALL Java_cn_sh_changxing_myled_JniLib_led_1close  (JNIEnv *, jobject);/* * Class:     cn_sh_changxing_myled_JniLib * Method:    ledIoctl * Signature: (II)I */JNIEXPORT jint JNICALL Java_cn_sh_changxing_myled_JniLib_ledIoctl  (JNIEnv *, jobject, jint, jint);#ifdef __cplusplus}#endif#endif

编写 c 代码

//// Created by cheng on 2019/10/26.//    #include     #include     #include     #include     #include     #include     #include     #include     #include     #include     #include     #include     #include "cn_sh_changxing_myled_JniLib.h"    #undef  TCSAFLUSH    #define TCSAFLUSH  TCSETSF    #ifndef _TERMIOS_H_    #define _TERMIOS_H_    #endif    int fd=0;        JNIEXPORT jint JNICALL Java_cn_sh_changxing_myled_JniLib_led_1open          (JNIEnv *env, jobject obj)          {            if(fd<=0)fd = open("/dev/leds", O_RDWR|O_NDELAY|O_NOCTTY);            if(fd <=0 )__android_log_print(ANDROID_LOG_INFO, "serial", "open /dev/leds Error");            else __android_log_print(ANDROID_LOG_INFO, "serial", "open /dev/leds Sucess fd=%d",fd);          }        /*         * Class:     com_topeet_ledtest_led         * Method:    Close         * Signature: ()I         */        JNIEXPORT jint JNICALL Java_cn_sh_changxing_myled_JniLib_led_1close          (JNIEnv *env, jobject obj)          {            if(fd > 0)close(fd);          }        /*         * Class:     com_topeet_ledtest_led         * Method:    Ioctl         * Signature: ()I         */        JNIEXPORT jint JNICALL Java_cn_sh_changxing_myled_JniLib_ledIoctl          (JNIEnv *env, jobject obj, jint num, jint en)          {            ioctl(fd, en, num);          }

创建 mk 文件
mk 文件用于告诉 ndk-build 该如何编译 c 源码,详情见官方指南。
在 jni 目录下创建 Android.mk:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_LDLIBS += -llogLOCAL_LDLIBS +=-lmLOCAL_MODULE := JniLibLOCAL_SRC_FILES =: JniLib.cinclude $(BUILD_SHARED_LIBRARY)

其中 LOCAL_SRC_FILES 列出了所有要编译的 c 源码文件
然后创建 Application.mk:

APP_MODULES := JniLibAPP_ABI := all

在 module 的 build.gradle 里,amndroid.defaultConfig 下加入下面配置:
Android Studio 3.5 JNI (ndk-build)_第3张图片
代码:

        ndk{            moduleName "JniLib"            //abiFilters \"armeabi-v7a", "x86" //输出指定abi下的so库        }        sourceSets.main{            jni.srcDirs = []            jniLibs.srcDir "src/main/libs"        }

编译:
编译需要使用 ndk-build,其位于 ndk 目录下。如果要直接在命令行使用需要添加环境变量。类似的,为了方便我也添加了一个外部工具。
注意改成你自己的目录。

Program: D:\Android_sdk\ndk\20.0.5594570\build\ndk-build.cmdWorking directory: F:\android_project\Myled

任意找个第地方右击,选择 External Tools - ndk-build 即可编译 c 源码。成功后可以看见创建了 libs 目录,里面包含了不同平台下的 so 文件。

运行
最后修改下 Activity 的代码:

package cn.sh.changxing.myled;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.view.View;public class MainActivity extends AppCompatActivity {    private JniLib jniTest = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        jniTest = new JniLib();        jniTest.led_open();    }    public void led1_en(View view) {        //Toast.makeText(this, "test", Toast.LENGTH_SHORT).show();        jniTest.ledIoctl(0, 1);    }    public void led1_off(View view) {        jniTest.ledIoctl(0, 0);    }    public void led2_en(View view) {        jniTest.ledIoctl(1, 1);    }    public void led2_off(View view) {        jniTest.ledIoctl(1, 0);    }    }

参考:https://blog.csdn.net/slaughteryou/article/details/88235000

更多相关文章

  1. Android -- 消息处理机制源码分析(Looper,Handler,Message)
  2. Gears Android WIFI/基站定位源代码分析
  3. 安卓学习(初)第三章(2)(《第一行代码》)
  4. Android 国际化工具 Android Localizer
  5. 《第一行代码Android》阅读笔记
  6. Android源码阅读之MessageQueue
  7. 白话开发——Android Studio代码调试技巧篇
  8. Android 导入android源码有错,R.java文件不能自动生成解决方法

随机推荐

  1. 在eclipse中查看android SDK的源代码
  2. 高焕堂
  3. Android(安卓)Camera
  4. EditText的使用
  5. Android(安卓)输入法键盘和activity页面
  6. 让android支持RTSP(live555分析)
  7. Android(安卓)Animation动画 控制动画的
  8. Android图形合成和显示系统---基于高通MS
  9. Android(安卓)安全机制
  10. android studio 1.5.1 创建java项目