Android studio,第一個生成,調用成功的jni(說多了都是淚)

0x01 序言:

  淚從何處提及呢?其實很早之前就用過android studio寫過c++,可是,可是一直沒有成功生成過so文件,因此心中一直有一個糾結。。。爲何不成功呢。。。java

直到今天,因爲工做的緣故不得不從新拾起,應該是昨天,昨天就在寫了,不過,沒成功。android

0x02 網上的通常性操做

  一、建立一個項目。c++

  包名姑且用:com.tangh.test_so2

  二、新建一個類,和jni方法。程序員

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

    public native String getString();
}

  生成(build)一下,查看 項目名稱\app\build\intermediates\classes\debug\com\tangh\test_so2\JniUtil.class文件app

  三、返回到 classes\debug\下 shift+鼠標右鍵,在此處打開命令窗口ide

  四、執行命令: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/48864189gradle

  五、而後寫.cpp文件。實現它ui

#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,這就是引起了後續的一個問題了。。。。。spa

  六、在項目/src/app/main/下新建一個文件夾 jni。而後把.h文件.cpp文件,都存放進入,聽過好像jni自己有bug,須要一個空的.c文件,因而我寫了一個空的.cpp,空的.c文件

empty.c 和 FixBug.cpp
 七、固然,我是一直沒成功,因而手動建立了。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

  八、順便改一下。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的錯誤與,或者是我哪裏配置沒有弄好。。。。

  九、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都裝了。。。。

相關文章
相關標籤/搜索