zoukankan      html  css  js  c++  java
  • 呕心沥血Android studio使用JNI实例

    发现网上很多JNI的使用教程,也很详细,不过有的地方有些缺漏,导致很多小问题难以解决的,今天就来总结一下。

    准备工作:下载NDK。

    简单的说,要用到C/C++,就要用NDK。直接百度搜索然后去官网下载就行,位置可以随便放。

    1、新建一个类,声明native方法。这个类是java与C/C++交互的中介,方法由java声明,由C/C++实现。

    不在Activity类里面写是为了避免编译时报错:找不到android.support.v7.app.AppCompatActivity

    public class myJNI {
    
      //加载so库
    static { System.loadLibrary("JniTest"); }   //native方法 public static native String sayHello(); }

    2、打开android studio终端,使用javac编译上述文件,生成class文件。

    命令:

    D:AndroidStudioProject	estJNIappsrcmainjavacomexampleinbin	estjni>javac myJNI.java

    3、确认自己类的包名!然后在上一级的位置使用javah生成.h头文件

    一定要在上一级哦,不然不会报错:找不到xxx类

    比如我的myJNI.class在

    D:AndroidStudioProject	estJNIappsrcmainjavacomexampleinbin	estjni

    我的包名是:

    package com.example.binbin.testjni;

    所以我的javah命令应该这么写:

    D:AndroidStudioProject	estJNIappsrcmainjava>javah -jni com.example.binbin.testjni.myJNI

    然后就能看到生成了一个h文件。

    4、新建一个jni文件夹,新建main.c,把.h里面的内容复制进去,并实现里面的函数。

    生成的h文件

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_example_binbin_testjni_myJNI */
    
    #ifndef _Included_com_example_binbin_testjni_myJNI
    #define _Included_com_example_binbin_testjni_myJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_example_binbin_testjni_myJNI
     * Method:    sayHello
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_example_binbin_testjni_myJNI_sayHello
            (JNIEnv *, jclass);
    
    #ifdef __cplusplus
    }
    #endif
    #endif

    拷贝修改后的main.c

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_example_binbin_testjni_myJNI */
    
    #ifndef _Included_com_example_binbin_testjni_myJNI
    #define _Included_com_example_binbin_testjni_myJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_example_binbin_testjni_myJNI
     * Method:    sayHello
     * Signature: ()Ljava/lang/String;
     */

    //就实现了个函数 JNIEnv的用法可以自行百度,这里就不展开了 JNIEXPORT jstring JNICALL Java_com_example_binbin_testjni_myJNI_sayHello (JNIEnv *env, jclass jobj){
      //返回一句话
    return (*env)->NewStringUTF(env,"JNI hahahahahahahaha"); } #ifdef __cplusplus } #endif #endif

    还要在jni文件夹下添加一个空白的util.c文件,不然会报错,我也不知道为什么。

    5、配置NDK

    打开Project的local.properties文件添加NDK路径

      

      

    打开app Module的build.gradle文件,在defaultConfig节点里添加以下代码
    注意这里的moduleName,是我们在之前自己编写的类里面加载的so库名
     ndk {
                moduleName "JniTest"
                ldLibs "log", "z", "m"
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }

      

    还要在gradle.properties里面加上这么一句话:
    android.useDeprecatedNdk=true

    6、生成SO库

    完成以上步骤之后,我们rebuild一下就可以生成so库了

    在项目的appuildintermediates dkdebuglib路径下

    7、配置so库

    在srcmain下新建文件夹jniLIB,并将生成的SO文件拷贝到该文件夹下

    8、使用JNI

    因为native方法声明成了静态的方法,在Activity里面直接调用myJNI类就行

      protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
            text = (TextView)findViewById(R.id.text);
         //调用 text.setText(myJNI.sayHello()); } }

     

    ok!

    总结一下流程:

    编写静态方法(用java声明)-->编译生成class文件--->编译生成h文件---->编写C文件(用C/C++实现)

    ---->配置NDK---->配置so库---->在Activity调用(Java调用C/C++)。

    android studio虽然很多小问题,但也算很方便了,mk文件编辑器帮你弄好了,直接可以生成so库。

    
    
    
    
    
  • 相关阅读:
    客户端技术的一点思考(数据存储用SQLite, XMPP通讯用Gloox, Web交互用LibCurl, 数据打包用Protocol Buffer, socket通讯用boost asio)
    自绘LISTVIEW的滚动条(Delphi实现)
    文字滚屏控件(SliderPanel)
    自动注册服务NET Core扩展IServiceCollection
    Three.js基础
    Cordova+Asp.net Mvc+GIS
    Netty
    TagHelper
    jQuery、实例大全
    React和Angular
  • 原文地址:https://www.cnblogs.com/wzben/p/5733571.html
Copyright © 2011-2022 走看看