1. 程式人生 > >android呼叫第三方庫——第一篇

android呼叫第三方庫——第一篇

0:前言:

  1. 這兩天一直在研究用android的jni呼叫第三方庫,上網搜方法,但是都是泛泛而談,沒有demo,經過我幾番折磨,寫了n多的helloword工程,總是不成功,工程名字也就由helloowrd轉到shithelloword再轉到fuckhelloword再轉到bitchhelloword再轉到ganhelloword再轉到helloword,在最後成功了!yeah,記錄下來,為自己和他人方便
  2. 不得不吐槽一下我的破電腦,ubuntu下eclipse開啟後,cpu佔用率直接飆到180%,然後ubuntu就把eclipse給kill掉了,然後eclipse就退出了,後來總結原因是我的eclipse的工程中有android系統的整個檔案系統的原始碼,然後把他close project後就好多了,不會被ubuntu給kill掉了
  3. 篇幅介紹:
    1. 第一篇:主要是介紹從頭建立一個hello的工程,這裡面建立庫libhello.so然後在java程式中呼叫他,有一個相對來說一氣呵成的步驟
    2. 第二篇:主要是介紹用android程式直接呼叫第三方庫
    3. 第三篇:主要是介紹用android程式整合第三方庫到自己的庫中,
    4. 在這三篇中,避免枯燥,作者會設定一定的場景,
  4. 如果作者有說的不對的地方,請指出,因為作者也是剛弄“明白”

1:場景:甲方非軟體公司要做一個android客戶端,功能主要是“人臉識別”,然後找到乙方軟體公司(該公司人臉識別比較牛逼,主要是用C++程式碼實現人臉識別,但是這個公司沒有做android程式的,長遠考慮招一個會android的程式設計師,臨時考慮的話,把android程式外包給丙方軟體公司)

2:分析:乙方C++公司現在的主要任務是做自己的業務邏輯庫,然後把庫交給丙方android公司來做android程式,然後交差拿錢。第一篇都是以乙方C++公司為主體來做程式,作者以hello模擬

3:前提:

  1. ubuntu64位系統
  2. android-ndk-r8e已經安裝好,並且配置到eclipse裡面
  3. android-sdk-linux已經安裝好,並且配置到eclipse裡面

4:搞起:

  1. 新建一個android專案(這裡乙方C++公司新建的是android程式,後期會轉化為C++程式),名稱為hello;報名為com.hello.hello如圖,圖中的jni和libs和obj資料夾不要管他,他們是後來自動生成的。
  2. 專案hello右鍵-》Android Tools-》Add Native Support-》填寫你需要生成的庫名稱,這裡寫hello就行,確定之後就自動生成了jni檔案夾了,裡面有hello.cpp和Android.mk
  3. 在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();
        }
    }
  4. 利用javah生成標頭檔案,而且利用eclipse整合javah的方式,比較方便,萬一我的java檔案有修改的地方,利用這種方式顯示出極大的方便性,請尊駕移布[]
  5. 編寫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;
    }
    
  6. 編寫jni資料夾下的Android.mk檔案
    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := hello
    LOCAL_SRC_FILES := hello.cpp
    
    include $(BUILD_SHARED_LIBRARY) 
    
  7. 修改專案的編譯選項:專案右鍵-》Properties-》C/C++ Build-》Build command中填寫你的android-ndk的根目錄;Behaviour選項卡中的Build為空,
  8. 編譯專案,專案右鍵-》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
  9. 執行android專案,會看到下圖,說明是正確的,至此我們編寫的庫檔案能夠被正確的被自己的程式呼叫,
  10. 現在專案完成,把專案中用的標頭檔案com_hello_hello_HelloActivity.h和生成的哭檔案libhello.so(在libs/armeabi 資料夾下)和介面文件交給專案經理,然後專案經理再轉交給丙方android公司