zoukankan      html  css  js  c++  java
  • Android studio,第一个生成,调用成功的jni(说多了都是泪)

    0x01 序言:

      泪从何处说起呢?其实很早以前就用过android studio写过c++,但是,但是一直没有成功生成过so文件,所以心中一直有一个纠结。。。为什么不成功呢。。。

    直到今天,由于工作的缘故不得不重新拾起,应该是昨天,昨天就在写了,不过,没成功。

    0x02 网上的一般性操作

      1、创建一个项目。

      包名姑且用:com.tangh.test_so2

      2、新建一个类,和jni方法。

    public class JniUtil {
        static {
            System.loadLibrary("hello");
        }
    
        public native String getString();
    }
    

      生成(build)一下,查看 项目名称appuildintermediatesclassesdebugcom angh est_so2JniUtil.class文件

      3、返回到 classesdebug下 shift+鼠标右键,在此处打开命令窗口

      4、执行命令:javah -jni com.tangh.test_so2.JniUtil  会在 debug下生成一个  com_tangh_test_so2_JniUtil.h文件。。。

      

    extern "C" {
    #endif
    /*
     * Class:     com_tangh_test_so2_JniUtil
     * Method:    getString
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_tangh_test_1so2_JniUtil_getString
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    

      方法名变了。在下划线前面加了一个数字,参考:https://blog.csdn.net/sambillyr/article/details/48864189

      5、然后写.cpp文件。实现它

    #include <jni.h>
    #include "com_tangh_test_so2_JniUtil.h"
    JNIEXPORT jstring JNICALL Java_com_tangh_test_1so2_JniUtil_getString
      (JNIEnv *env, jobject thiz){
         return env->NewStringUTF("hello jni!");
      }
    

      处于,好看,我把函数名字改动了一下,去掉了那个1,这就是引发了后续的一个问题了。。。。。

      6、在项目/src/app/main/下新建一个文件夹 jni。然后把.h文件.cpp文件,都存放进入,听过好像jni本身有bug,需要一个空的.c文件,于是我写了一个空的.cpp,空的.c文件

    empty.c 和 FixBug.cpp
     7、当然,我是一直没成功,于是手动创建了。Android.mk和一个Application.mk文件
    Android.mk
    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := hello
    LOCAL_SRC_FILES := com_tangh_test_so2_JniUtil.cpp  
    empty.c  
    FixBug.cpp
    
    include $(BUILD_SHARED_LIBRARY)
    

      Application.mk

    APP_PLATFORM = android-16
    APP_ABI := armeabi-v7a
    

      8、顺便改一下。build.gradle...

    defaultConfig {
            applicationId "com.tangh.test_so2"
            minSdkVersion 16
            targetSdkVersion 24
            versionCode 1
            versionName "1.0"
            ndk{
                moduleName "hello"
                abiFilters "armeabi-v7a", "x86"
            }
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
        sourceSets.main {
            jniLibs.srcDir '/src/main/jniLibs'
            jni.srcDirs = [] //disable automatic ndk-build call
        }
    
    // 部分内容省略了。
    

      。。。jni.srcDirs设置成空,意思就是手动生成so.

      给路径就是告诉ide,你来给我生成。当然,两种方法都试了。都有错误。那么不生成。要么我在jni目录下执行ndk-build命令。。报错 XXXXXXXXXXX Error 1..

    我一直以为是nkd的错误与,或者是我哪里配置没有弄好。。。。

      9、Q群求助。。结果别人居然可以编译,我就纳闷了,于是把ndk拷贝到,虚拟机,安装jdk,真的可以。。。。原谅我的PC机,他已经老了,可能年久失修,,,

      10,好吧,算解决了。但是 so生成了,拷贝回来了。放在了。目录/src/main/jniLibs/armeabi-v7a/libhello.so ....但是,编译之后没问题。

    运行起来,app退出了,找不到native函数,我用ida看了一下,有这个函数啊,,,,想到,函数名称,把“.”,变成了下划线"_"...难道是我的下划线。。。。

    突然心中一万只(XXX)飞过,好吧,百度一下。改回去,重新生成,重新。。。,,,成功了。。

      11.。真的成功了,突然成就感爆棚。。。。好吧,这个问题,我困扰我很久了。发个红包,庆祝一下。

    0x02 总结

      有时候,一个问题,不一定是代码的问题,环境也可能是一个困扰你不得其所的大问题。换个思路,让别人也试试,说不定你会有新发现。同时也告诉我们,作为一个程序员,应该有多个环境。

    一个干净的环境,能够更好地甄别问题所在,而不是像我的PC机一样,1T的硬盘,只有不到100G了,大多数软件都装了。。这么说吧。

    vs2010,2012,2013,2015都装了。。。。

  • 相关阅读:
    30岁的程序猿坐的太久,也要用一下脑子
    HIPO图
    CMake入门(二)
    hdu1711 Number Sequence
    EF架构~在ef中支持IQueryable级别的Contains被翻译成了Exists,性能可以接受!
    JS框架~Angularjs
    将不确定变为确定~transactionscope何时提升为分布式事务?(sql2005数据库解决提升到MSDTC的办法)
    SignalR实现服务器与客户端的实时通信
    基础才是重中之重~LazyInitializer.EnsureInitialized对属性实现化的性能优化
    [置顶] 电视机顶盒搜台原理和方法简析
  • 原文地址:https://www.cnblogs.com/Supperlitt/p/9188206.html
Copyright © 2011-2022 走看看