android呼叫第三方庫——第一篇
阿新 • • 發佈:2019-01-09
0:前言:
- 這兩天一直在研究用android的jni呼叫第三方庫,上網搜方法,但是都是泛泛而談,沒有demo,經過我幾番折磨,寫了n多的helloword工程,總是不成功,工程名字也就由helloowrd轉到shithelloword再轉到fuckhelloword再轉到bitchhelloword再轉到ganhelloword再轉到helloword,在最後成功了!yeah,記錄下來,為自己和他人方便
- 不得不吐槽一下我的破電腦,ubuntu下eclipse開啟後,cpu佔用率直接飆到180%,然後ubuntu就把eclipse給kill掉了,然後eclipse就退出了,後來總結原因是我的eclipse的工程中有android系統的整個檔案系統的原始碼,然後把他close project後就好多了,不會被ubuntu給kill掉了
- 篇幅介紹:
- 第一篇:主要是介紹從頭建立一個hello的工程,這裡面建立庫libhello.so然後在java程式中呼叫他,有一個相對來說一氣呵成的步驟
- 第二篇:主要是介紹用android程式直接呼叫第三方庫
- 第三篇:主要是介紹用android程式整合第三方庫到自己的庫中,
- 在這三篇中,避免枯燥,作者會設定一定的場景,
- 如果作者有說的不對的地方,請指出,因為作者也是剛弄“明白”
1:場景:甲方非軟體公司要做一個android客戶端,功能主要是“人臉識別”,然後找到乙方軟體公司(該公司人臉識別比較牛逼,主要是用C++程式碼實現人臉識別,但是這個公司沒有做android程式的,長遠考慮招一個會android的程式設計師,臨時考慮的話,把android程式外包給丙方軟體公司)
2:分析:乙方C++公司現在的主要任務是做自己的業務邏輯庫,然後把庫交給丙方android公司來做android程式,然後交差拿錢。第一篇都是以乙方C++公司為主體來做程式,作者以hello模擬
3:前提:
- ubuntu64位系統
- android-ndk-r8e已經安裝好,並且配置到eclipse裡面
- android-sdk-linux已經安裝好,並且配置到eclipse裡面
4:搞起:
- 新建一個android專案(這裡乙方C++公司新建的是android程式,後期會轉化為C++程式),名稱為hello;報名為com.hello.hello如圖,圖中的jni和libs和obj資料夾不要管他,他們是後來自動生成的。
- 專案hello右鍵-》Android Tools-》Add Native Support-》填寫你需要生成的庫名稱,這裡寫hello就行,確定之後就自動生成了jni檔案夾了,裡面有hello.cpp和Android.mk
- 在HelloActivity.java中新增程式碼如上圖
package com.hello.hello; import android.app.Activity; import android.app.AlertDialog; import android.os.Bundle; public class HelloActivity extends Activity { static { System.loadLibrary("hello"); } public static native String sayHello(); // 本地庫函式 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); new AlertDialog.Builder( this ).setMessage( sayHello() ).show(); } }
- 利用javah生成標頭檔案,而且利用eclipse整合javah的方式,比較方便,萬一我的java檔案有修改的地方,利用這種方式顯示出極大的方便性,請尊駕移布[]
- 編寫jni資料夾下的hello.cpp檔案
#include <string.h> #include <jni.h> #include "com_hello_hello_HelloActivity.h" /* * Class: com_hello_word_HellowordActivity * Method: sayHello * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_hello_hello_HelloActivity_sayHello(JNIEnv *env, jclass){ return env->NewStringUTF("hello"); } jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint result = -1; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { return result; } return JNI_VERSION_1_4; }
- 編寫jni資料夾下的Android.mk檔案
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello LOCAL_SRC_FILES := hello.cpp include $(BUILD_SHARED_LIBRARY)
- 修改專案的編譯選項:專案右鍵-》Properties-》C/C++ Build-》Build command中填寫你的android-ndk的根目錄;Behaviour選項卡中的Build為空,
- 編譯專案,專案右鍵-》build project,會看到控制檯輸出,說明我們的是正確的,good!
**** Build of configuration Default for project hello **** /opt/EmbedSky/android-ndk-r8e/ndk-build Compile++ thumb : hello <= hello.cpp SharedLibrary : libhello.so Install : libhello.so => libs/armeabi/libhello.so
- 執行android專案,會看到下圖,說明是正確的,至此我們編寫的庫檔案能夠被正確的被自己的程式呼叫,
- 現在專案完成,把專案中用的標頭檔案com_hello_hello_HelloActivity.h和生成的哭檔案libhello.so(在libs/armeabi 資料夾下)和介面文件交給專案經理,然後專案經理再轉交給丙方android公司