在前面的博客中介紹的都是使用java開發android應用,這篇博客將介紹java通過使用jni調用c語言做開發
爲了更加形象的介紹jni,先觀察下面的圖片,下圖表示的是整個android系統架構
圖中從上到下的結構依次是:
Application:表示應用層,其實就是指android手機上的應用
Application Framework:表示應用框架層,我們平時用java開發app就是使用應用框架層提供的API做開發
Libraries:android類庫,使用C/C++開發的android類庫
Android Runtime:android運行環境
Linux Kernel:Linux內核
通過上圖可知Android系統分爲五個部分,分別是Application(應用層)、Application Framework(應用框架)、Librarise(Android 類庫)、Android Runtime(Android 運行環境)、Linux Kernel(Linux內核),且android應用框架使用java開發的,android類庫使用c/c++開發的,爲了使得java開發應用框架能調用c/c++開發的android類庫,android中引入了一個jni,通過jni可以實現java調用c/c++,c/c++調用java
開發jni需要準備的工具:
Android ndk,Android NDK的下載地址是:http://blog.csdn.net/u010105970/article/details/45152629
下載完成後將ndk解壓的一個任意的目錄下,我解壓在D:\develop,建議文件目錄不要帶空格,解壓後將ndk所在的路徑添加到環境變量中
打開android ndk後,可以看到android ndk的目錄結構如下:
android ndk目錄結構介紹:
docs:幫助文檔
build/tools:linux的批處理文件
platforms:編譯c代碼需要使用的頭文件和類庫
prebuilt:預編譯使用的二進制可執行文件
sample:jni的使用例子
source:ndk的源碼
toolchains:工具鏈
ndk-build.cmd:編譯打包c代碼的一個指令
使用ndk實現一個簡單的Hello World程序
第一步:使用eclipse創建一個Android工程,並且將工程的名稱命名爲HelloJni
第二步:修改activity_main.xml文件,在佈局上添加一個按鈕點擊按鈕後調用c語言寫的代碼
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="調用c語言代碼"
android:onClick="click"/>
</RelativeLayout>
第四步:在jni文件夾下新建一個hello.c文件,並在hello.c文件中添加下面的代碼
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
/***
* 第一個參數:java虛擬機的內存地址
* 第二個參數:調用helloFromC方法的java對象
*/
Java_com_example_hellojni_MainActivity_helloFromC(JNIEnv* env, jobject obj) {
//創建一個c語言的字符串,並且初始化字符串
char* arr = "hello world jni !";
//把c語言的字符串轉換成java的字符串
jstring jstr = (*env)->NewStringUTF(env, arr);
//返回字符串
return jstr;
}
第五步:在jni文件夾下新建一個Android.mk文件,並在Android.mk中添加下面的代碼
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#編譯生成的文件的類庫叫什麼名字
LOCAL_MODULE := hello
#要編譯的c文件
LOCAL_SRC_FILES := Hello.c
include $(BUILD_SHARED_LIBRARY)
1、打開命令行,並且進入到jni所在的目錄
2、輸入ndk-build.cml命令編譯android ndk
3、看到下圖所示的提示表示android ndk編譯成功
4、此時打開libs文件夾下的armeabi文件夾,可以看到armeabi文件夾下生成了一個libhello.so文件,這個就是Android ndk編譯後生成的文件,在後面就可以直接使用libhello.so文件
最後一步:使用通過ndk編譯好的,修改MainActivity.java文件
package com.example.hellojni;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
static {
//加載打包完畢的so類庫
System.loadLibrary("hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//調用c語言代碼按鈕響應函數
public void click(View view) {
//使用吐司對話框顯示c語言代碼中的函數helloFromC()的返回值
Toast.makeText(this, helloFromC(), Toast.LENGTH_SHORT).show();
}
//定義一個本地方法,方法體由C語言實現
public native String helloFromC();
}
運行android程序後手機上會顯示下圖所示的界面
點擊按鈕後彈出吐司,並且在吐司中顯示"hello world jni !"表示Android成功的調用了c語言開發的jni程序