Android 开发 DNK开发将.c文件打包成os

前言

  不废话太多,Java与C之间联系的JNI的概念,这个要了解可以参考下面这个博客:

  https://www.jianshu.com/p/87ce6f565d37

 

  此博客只说明如何将.C文件通过NDK打包成so库并且使用的一个简单demo.

 

第一步 创建用于引用本地os库的Java工具类

目录

工具类代码

package zq.ndkdemo;

public class NDKTools {

    static {
        System.loadLibrary("ndkdemomk-jni");//这里的"ndkdemomk-jni"是下面.mk文件里局部模块的值,这个到后面我会解释
    }

    public static native String getNDKcontent();//您在Java里调用so库的静态方法
}

 

第二步 将Java工具类打包成.h文件

打开Android studio的Terminal准备用javah打包.h文件, cd进入到app/src/目录下 然后输入 javah -o ndkdemoHFile.h -jni -classpath ./main/java/  zq.ndkdemo.NDKTools 命令.(下面会解释这条命令)

解释一下这行命令

javah -o ndkdemoHFile.h -jni -classpath ./main/java/  zq.ndkdemo.NDKTools
javah -o 你要打包的.h文件名加后缀 -jni -classpath 中间的路径  app包名+工具类名

输入这条命令后,如果没报错,你就会在src目录下获得您的.h文件,如下图:

打开.h可以看到:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class zq_ndkdemo_NDKTools */

#ifndef _Included_zq_ndkdemo_NDKTools
#define _Included_zq_ndkdemo_NDKTools
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     zq_ndkdemo_NDKTools
 * Method:    getNDKcontent
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_zq_ndkdemo_NDKTools_getNDKcontent
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

 

第三步 创建jni文件夹并且将.h文件移入

在main目录下创建一个jni文件夹

 

将我们打包好的.h文件移动到jni文件夹里

第四步 创建c语言函数文件

进入到jni文件夹里,点击创建任意名称加.c后缀的文件

打开写入代码如下:

#include "ndkdemoHFile.h" 

JNIEXPORT jstring JNICALL Java_zq_ndkdemo_NDKTools_getNDKcontent
  (JNIEnv *env, jobject obj){
     return (*env)->NewStringUTF(env,"Hellow World,这是NDK的第一行代码");
  }

 注意!代码里最好别写注释特别是中文注释.

#include "ndkdemoHFile.h" 

这行代码引用的就是.h文件名称

 JNIEXPORT jstring JNICALL Java_zq_ndkdemo_NDKTools_getNDKcontent 

这行代码中 jstring 为返回值

Java_zq_ndkdemo_NDKTools_getNDKcontent  为 Java + 路径 + 类名 + 方法名称

 

第五步 创建.mk文件

 在jni目录下创建一个叫Android.mk的文件

内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := ndkdemomk-jni

LOCAL_SRC_FILES := ndkdemoCFile.c

include $(BUILD_SHARED_LIBRARY)

LOCAL_PATH := $(call my-dir)

每个Android.mk文件必须以定义开始。它用于在开发tree中查找源文件。宏my-dir则由Build System 提供。返回包含Android.mk目录路径。

include $(CLEAR_VARS)

CLEAR_VARS变量由Build System提供。并指向一个指定的GNU Makefile,由它负责清理很多LOCAL_xxx。例如LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_STATIC_LIBRARIES等等。但不是清理LOCAL_PATH。这个清理是必须的,因为所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能便面相互影响。

LOCAL_MODULE := ndkdemomk-jni

LOCAL_MODULE模块必须定义,以表示Android.mk中的每一个模块。名字必须唯一且不包含空格。Build System 会自动添加适当的前缀和后缀。例如,demo,要生成动态库,则生成libdemo.so。但请注意:如果模块名字被定义为libabd,则生成libabc.so。不再添加前缀。 另外我们一开始写的Java工具类里的System. loadLibrary("ndkdemomk-jni"); 就是这个值

OCAL_SRC_FILES := ndkdemCFile.c

这行代码表示将要打包的C/C++源码。不必列出头文件,build System 会自动帮我们找出依赖文件。缺省的C++ 源码的扩展名为.cpp。

include $(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY是Build System提供的一个变量,指向一个GUN Makefile Script。它负责收集自从上次调用 include $(CLEAR_VARS)后的所有LOCAL_xxxxinx。并决定编译什么类型
  • BUILD_STATIC_LIBRARY:编译为静态库
  • BUILD_SHARED_LIBRARY:编译为动态库
  • BUILD_EXECUTABLE:编译为Native C 可执行程序
  • BUILD_PREBUILT:该模块已经预先编译

第六步 在build.gradle文件里添加部分代码

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "zq.ndkdemo"
        minSdkVersion 27
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        
        //需要添加的部分
        ndk{
            moduleName "ndkdemo-jni"
            abiFilters "armeabi-v7a", "x86"
        }


    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
        //需要添加的部分
        externalNativeBuild {
            ndkBuild {
                path 'src/main/jni/Android.mk'
            }
        }
        //需要添加的部分
        sourceSets.main {
            jni.srcDirs = []
            jniLibs.srcDirs = ['src/main/jniLibs']
        }
    }
    //需要添加的部分
    sourceSets{
        main {
            jni.srcDirs = []
        }
    }

}

第七步  检查Android studio是否已经下载配置过ndk

点击local.properties打开

 
查看是否有ndk
ndk.dir=/media/E/tools/SDK/androidsdklinux/ndk-bundle
sdk.dir=/media/E/tools/SDK/androidsdklinux

如果没有就需要进入到File >> Settings  里下载ndk

 

第八步 编译SO文件

在Android studio的工具栏里,点击Build >> clean Project  先清理一下之前的编译

在点击Build >> Rebuild Project  重新创建编译文件

然后可以打开下图所示路径,就可以看到我们的so文件了

第九步 调用工具类方法,run APP

public class MainActivity extends AppCompatActivity {
    private TextView mDemoText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDemoText = findViewById(R.id.demo_text);
        String content = NDKTools.getNDKcontent();
        mDemoText.setText(content);
    }
}

运行APP 即可.

 

posted on 2019-06-01 14:41  观心静 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/guanxinjing/p/10959567.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值