1. 程式人生 > >Android開發中在JAVA中呼叫C/C++ native程式碼

Android開發中在JAVA中呼叫C/C++ native程式碼

Android 從Java呼叫C/C++

當無法用 Java 語言編寫整個應用程式時,JNI 允許您呼叫C/C++本機程式碼。在下列典型情況下,您可能決定使用本機程式碼:

  • 希望用更低階、更快的程式語言C/C++去實現對時間有嚴格要求的程式碼。

  • 希望從 Java 程式訪問舊程式碼或程式碼庫。

  • 需要標準 Java 類庫中不支援的依賴於平臺的特性。

我為什麼需要它?我的程式碼背景

我在安卓專案中,需要用到C++的soundtouch庫函式,因此必須將呼叫該庫的程式碼用C++編寫,然後再由java呼叫C++本機程式碼。

前提:已經配置好支援交叉呼叫的NDK(Native Development Kit,java與C/C++交叉呼叫的工具

),併為你的工程建立好builder,配置可參照另一篇博文:http://my.oschina.net/liusicong/blog/311886

問題及動機

網上有很多jni教程,但是對於安卓開發愛好者,如何在java程式碼中呼叫C/C++函式,實現我們想要的功能,卻沒有一個十分合適的教程,因此我寫下本文。

我要解決的問題:安卓前端有一個按鈕,點選該按鈕就可以實現“聲音特效處理”的功能。而這個功能的後臺實現的主要邏輯由C/C++程式碼編寫,因此需要從java呼叫C/C++程式碼。

須知:SWIG和javah的區別(強烈推薦)

我看了網上的關於 jni程式設計 的教程很多,但不盡相同,剛開始會犯迷糊。我想筆者往往忽略了一個關鍵點,那就是採用了什麼方式決定了步驟的流程。有兩種生成 jni的方式:一種是通過SWIG從C++程式碼生成過度的java程式碼;另一種是通過javah的方式從java程式碼自動生成過度的C++程式碼。兩種方式下的步驟流程正好相反

解決方案:從 Java 程式碼呼叫 C/C++ 的五個步驟

安卓開發中,從 Java 程式呼叫 C 或 C ++ 程式碼的過程由五個步驟組成。我們將在深入討論每個步驟,首先迅速地瀏覽一下,注意本文采用的方式是:SWIG 方式

  1. 在jni資料夾下編寫C/C++程式碼,實現我們想要實現的C/C++邏輯。

  2. 根據C/C++程式碼,編寫 Java 程式碼。我們將根據寫好的C/C++函式,編寫 Java 類,這些類執行三個任務:宣告將要呼叫的native本機方法;裝入包含本機程式碼的共享庫;然後呼叫該本機方法。

  3. 首先用javah生成C/C++ 標頭檔案(.h 檔案),然後去改寫這個標頭檔案的方法,將我們自己的東西新增進去

    。C/C++的標頭檔案將宣告想要呼叫的本機函式說明。然後,這個標頭檔案與 C/C++ 函式實現(請參閱步驟 4)一起來建立共享庫(請參閱步驟 5)。

  4. 寫一個Android.mk檔案,放在jni下的C/C++程式碼資料夾下

  5. 編譯執行 Java 程式。執行該程式碼,並檢視它是否有用。我們還將討論一些用於解決常見錯誤的技巧。

相關程式碼目錄結構(以我的程式碼結構為例)

src(放java程式碼)

   |_ org.tecunhuman. jni 包(自定義命名的包)

       |_ wrapperJNI.java (自己編寫的java程式碼,含native方法)

jni (放C/C++程式碼)

   |_ soundstrech包(我的C++程式碼)

             |_ gen包

                      |_ wrapper_wrap.cpp

             |_ Android.mk

             |_ RunParameters.cpp

             |_ RunParameters.h

             |_ SoundStrech.cpp

             |_ SoundStrech.h

             |_ WavFile.cpp

             |_ WavFile.h

             |_ wrapper.i

   |_ soundtouch 包

——————————————————————————————

步驟 1:編寫C/C++程式碼(.cpp檔案)放在下jni下的C/C++程式碼資料夾

我們首先編寫一個.cpp檔案,

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 //SoundStrech.cpp程式碼 #include <stdexcept>  #include <stdio.h> #include <string.h> #include "RunParameters.h" #include "WavFile.h" #include "SoundTouch.h" #include "BPMDetect.h" #include "SoundStretch.h" using namespace soundtouch;

相關推薦

JNI在被呼叫C/C++函式如何訪問Java程式的類,並編寫應用例項

1、在javah工具生成的C/C++函式宣告中的JNIEnv型別引數和jobject型別引數的介紹 JNIEXPORT void JNICALL Java_jni_TestNative_sayhell

Android開發之Webview原生與JS互動

文章目錄 概述 使用場景 互動方式 Java呼叫JS程式碼 JS呼叫Java程式碼 總結 概述 由於手機硬體資源的快速提升,使得采用混合開發的可能性逐漸成為現實並且流行起來。Android開發中

java便捷呼叫現成c/c++庫: cmake使用swig簡介

簡介 swig是個工具,能便捷地讓其它指令碼語言呼叫你使用C語言編寫的程式。更具體的請自己google一下相關資料(如果沒條件上google,用一下baidu應該也能查到點東西)。 在android應用開發中,可能java要大量地呼叫一個現成的c庫的時候,可以考慮用swig轉換一下。

Android開發 在EditText關閉軟鍵盤

                1、EditText有焦點(focusable為true)阻止輸入法彈出  editText=(EditText)findViewById(R.id.txtBody);        editText.setOnTouchListener(new OnTouchListener

Android面試題——java引用型別都有哪些

java中引用型別都有哪些 Java中物件的引用分為四種級別,這四種級別由高到低依次為:強引用、軟引用、弱引用和虛引用。  強引用(StrongReference) 這個就不多說,我們寫程式碼天天在用的就是強引用。如果一個物件被被人擁有強引用,那麼垃圾回收器絕不會回收它。當

Android -Javabyte[]轉String問題

     最近的專案中要使用到把byte[]型別轉換成String字串然後通過網路傳送,但發現發現出去的字串和獲取的字串雖然是一樣的,但當用String的getBytes()的方法得到的byte[]跟原來的byte[]是不一樣的。 看如下程式碼: bytebytes

android開發在ScrollView的GridView顯示問題及原因

public static int getChildMeasureSpec(int spec, int padding, int childDimension) { int specMode = MeasureSpec.getMode(spec); int specSize = MeasureSpec.get

Android開發從相簿選取照片

最近專案在做一個功能:就是需要從使用者選擇頭像跳轉到相簿選擇圖片,這應該是一個很簡單的需求,但是在網上搜了一下有好多都講的很亂,其實用幾十行程式碼就可以實現的為什麼要說的那麼複雜呢,下面就簡單說一下嘍。 下面說兩種方法分別是直接選擇相簿返回,另外一種為選擇相簿之

Android開發之ScrollView巢狀ListView的解決方案

import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.BaseAdapter;

Android開發: Eclipse匯入專案前有紅叉提示但是專案檔案內容無錯誤的解決方法

 Eclipse中,Android專案名稱前有紅叉,但專案內所有檔案都無錯誤,通常發生在匯入專案時。 先可以去看一下幾個視窗的輸出內容,不同的錯誤日誌要採用不同的方法,要靈活使用各種方法! 1>選單路徑----Window/Show View/Console 2

Eclipsejava專案呼叫DLL

java工程路徑:D:\workspace vc 工程路徑D:\workspace_c JDK路徑:D:\jdk1.6.0_23 1、建立java專案 在Eclipse中建立java工程jnidemo,如圖1所示: 圖1 當儲存TestNative.java檔案時

如何在android開發使用ACTION_SEND共享圖片和文字

處理方法 你可以共享下面的程式碼: String shareBody = "Here is the share content body"; Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingInten

android開發環境搭建容易遇到的問題和疑惑

1.JDK是向下相容的,JDK安裝高版本,eclipse、ADT、SDK安裝低本版本是可以的。 2.eclipse的版本與ADT、SDK的版本必須是匹配的。無論是低版本的eclipse安裝高版本的ADT還是,高版本的eclipse安裝低版本的ADT,在安裝過程中都會出現co

android 開發 在oncreate()獲取到控制元件的高度和寬度值為0解決辦法

大家很多時候需要在activity或者fragment的oncreate()方法中獲取宣告的空間的高度或者寬度,進行位置移動或者其他操作,但是當呼叫view.getHeight()或者view.getWidth()獲取的竟然為0。。。黑人問號。。。 其實很容易

Android開發之drawable的命名問題

今天,應一個同事的請求,幫助他在我現有app的基礎上給他修改意見個app,用來測試他的後臺應用。我就順道從網上找了一個應景的圖片,修改之後直接新增進了drawable資料夾下,結果剛加進去就發現專案報錯了,wtf???本來好好的,怎麼會這樣?我各種翻騰,clean,都沒效果

android 開發串列埠遇到的許可權問題 (個人筆記)

在串列埠開發中 我所遇到的許可權問有三重關:第一關:5.1系統 真機在這裡已經沒有許可權了 (studio自帶模擬器可以5.1以下似乎都可以) 這時候 需要root手機 和找開發商給你開許可權Process su = Runtime.getRuntime().exec("/s

簡單的入門Android開發Java語言基礎[圖]

span 如何 都是 android 類繼承 try alt 不依賴 throw 簡單的入門Android開發和Java語言基礎[圖]前言:去年年底到今年年初,我做過簡單的智能家居,也實現過一些簡單的直連和遠程的智能家居。於是就將最簡單的通信發布出來:智能家居簡單實現—使用

Android 開發JAVA動態設定控制元件大小

在我們的實際android開發中,我們經常需要對控制元件進行設定。在xml中設計大小,我們大家都很熟悉。那麼,使用java動態設定控制元件大小,該如何寫呢。以下是我寫的方法: /** * 設定控制元件大小 * @param view 控制元件

Android開發之~java.lang.ClassNotFoundException: Didn't find class "android.view.x" on path: ...

Process: com.vincent.example, PID: 10424 java.lang.RuntimeException: Unable to s

Android開發多媒體應用之SoundPool的使用的程式碼

內容過程中,把寫內容過程中比較好的內容段記錄起來,下面的內容是關於Android開發多媒體應用之SoundPool的使用的內容,希望對各位也有用途。 public class MainActivity extends Activity { private Button button1; private