#前言

本篇介绍Android-studio下的ndk的配置教程

#正文

1.下载ndk和CMake

如果下载很慢的话,可以单独的去下载

Android 设备dtb 路径 android ndk路径_#include

2.进行sdk和ndk的配置

这个ndk就是之前下载的ndk的地址


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ni4C8UNr-1648545699501)(http://upload-images.jianshu.io/upload_images/9374751-ccce63f7a4db856d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)] 如果在SDK location里面设置了sdk和ndk的路径,那么在local.properties中就不用配置了,它会自动配置,否则就要在local.properties配置相关sdk和ndk的路径

Android 设备dtb 路径 android ndk路径_Android 设备dtb 路径_02

配置gradle.properties文件

android.useDeprecatedNdk=true

Android 设备dtb 路径 android ndk路径_ndk_03

3.建立jni目录

可以直接建立jni和jniLibs的文件夹

Android 设备dtb 路径 android ndk路径_ndk_04

4.配置build

配置ndk的moduleName,生成的so库的名称就是lib+daoshuriwidget+.so

ndk {
            moduleName "daoshuriwidget"
            abiFilters "armeabi", "x86","armeabi-v7a"
            ldLibs "log"
        }

Android 设备dtb 路径 android ndk路径_jni_05

配置jni和jniLibs的目录,c文件放在jni中,生成的so库放在jniLibs中

Android 设备dtb 路径 android ndk路径_Android 设备dtb 路径_06

5.编写Native方法
public class LittleWidgetWatcher {
    static {
        System.loadLibrary("daoshuriwidget");//导入so库
         //导入在jniLibs下面的so库,名称和build中配置moduleName名称相同
    }

   //此方法就是用于调用c++的方法,要加上native
    public native void openLittleWidgetWatcher(int uId);
}
6.生成.h文件

找到AS的Terminal然后cd进入app目录

输入javah -classpath build/intermediates/classes/meizu/debug -jni com.pybeta.daymatter.service.LittleWidgetWatcher

Android 设备dtb 路径 android ndk路径_ndk_07

生成的.h文件就在根目录里面

Android 设备dtb 路径 android ndk路径_jni_08


如果你想要生成的.h文件在制定的文件件下面那么就在命令上面加上 -d,那么生成的.h文件就在jni目录下面

Android 设备dtb 路径 android ndk路径_ndk_09

7.开始编写C++代码

在jni文件夹下面新建C++代码
修改.h名称,并将.h复制到jni文件夹下面
将.h生成的方法复制到C++文件中

//.h文件夹生成的代码
#ifndef _Included_com_fanao_daoshuri_ndkprotect_LittleWidgetWatcher
#define _Included_com_fanao_daoshuri_ndkprotect_LittleWidgetWatcher
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_fanao_daoshuri_ndkprotect_LittleWidgetWatcher
 * Method:    openLittleWidgetWatcher
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_fanao_daoshuri_ndkprotect_LittleWidgetWatcher_openLittleWidgetWatcher
  (JNIEnv *, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif

因为.h生成的方法没有新参名称,所以要手动加上新参的名称

//c++下面的代码
JNIEXPORT void JNICALL
Java_com_fanao_daoshuri_ndkprotect_LittleWidgetWatcher_openLittleWidgetWatcher(JNIEnv *env,jobject instance, jint userId) {
//父进程 也就是小插件的进程
     user_id = userId;
/* sigaction用于信号处理,sa.sa_flags=SA_RESTART:使被信号打断的系统调用自动重新发起
 信号处理交给sig_handler处理的,当子进程挂了的时候会向其父进程发送一个SIGCHLD信号,
 父进程就会收到SIGCHLD信号,并且开始执行sig_handler方法,重生成子进程*/
     LOGI("开启进程\n");
     struct sigaction sa;
     sa.sa_flags = 0;
     sa.sa_handler = sig_handler;
     sigaction(SIGCHLD, &sa, NULL);
     create_child();
}

在c++文件夹下面导入.h文件

Android 设备dtb 路径 android ndk路径_AS下面ndk配置_10

导入相关的头文件(这头文件都在Common.h文件中)

#include <signal.h>
#include <sys/wait.h>
#include <android/log.h>
#include <sys/types.h>
#include <sys/un.h>
#include <errno.h>
#include <stdlib.h>
#include <linux/signal.h>
#include <android/log.h>
#define LOG_TAG "widget"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
void create_child();
void child_start_monitor();
8.编译生成so库,复制so库到jniLibs

点击编译按钮或者Ctrl+F9进行编译,生成so库

Android 设备dtb 路径 android ndk路径_#include_11

Android 设备dtb 路径 android ndk路径_#include_12

将这些so库(连同它的文件夹)同意复制到jniLibs中

Android 设备dtb 路径 android ndk路径_jni_13

9.使用jni方法,运行项目
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main );
        Intent intent = new Intent(this, LittleWidgetService.class);
        startService(intent);
    }