在Android下使用jni

在前面的博客中介紹的都是使用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>


第三步:在創建好的android工程下新建一個jni文件夾


第四步:在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)


第六步:編譯android ndk程序

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程序


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章