標籤:
《Android進階》之第一篇 在Java中調用C庫函數
這一篇列舉的方法是在NDK沒有出來時候用的方式
在Android發布NDK之後,可以這樣使用
一、首先下載android-ndk 下載後把壓縮包解壓出來,例如:D:\android-ndk-r10e,目錄下的ndk-build.cmd就是用來編譯的批處理命令。
為了編譯方便,推薦添加環境變數
Path目錄下添加D:\android-ndk-r10e;
以NDK內建的例子\samples\hello-jni為例
將例子匯入安卓工程:
HelloJni.java如下:
/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.hellojni;import android.app.Activity;import android.widget.TextView;import android.os.Bundle;public class HelloJni extends Activity{ /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* Create a TextView and set its content. * the text is retrieved by calling a native * function. */ TextView tv = new TextView(this); tv.setText( stringFromJNI() ); setContentView(tv); } /* A native method that is implemented by the * ‘hello-jni‘ native library, which is packaged * with this application. */ public native String stringFromJNI(); /* This is another native method declaration that is *not* * implemented by ‘hello-jni‘. This is simply to show that * you can declare as many native methods in your Java code * as you want, their implementation is searched in the * currently loaded native libraries only the first time * you call them. * * Trying to call this function will result in a * java.lang.UnsatisfiedLinkError exception ! */ public native String unimplementedStringFromJNI(); /* this is used to load the ‘hello-jni‘ library on application * startup. The library has already been unpacked into * /data/data/com.example.hellojni/lib/libhello-jni.so at * installation time by the package manager. */ static { System.loadLibrary("hello-jni"); }}
觀察上面代碼會發現:
有個匯入 System.loadLibrary的過程
還定義了兩個Nativie函數
在查看其中的c源檔案
/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */#include <string.h>#include <jni.h>/* This is a trivial JNI example where we use a native method * to return a new VM String. See the corresponding Java source * file located at: * * apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java */jstringJava_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ){#if defined(__arm__) #if defined(__ARM_ARCH_7A__) #if defined(__ARM_NEON__) #if defined(__ARM_PCS_VFP) #define ABI "armeabi-v7a/NEON (hard-float)" #else #define ABI "armeabi-v7a/NEON" #endif #else #if defined(__ARM_PCS_VFP) #define ABI "armeabi-v7a (hard-float)" #else #define ABI "armeabi-v7a" #endif #endif #else #define ABI "armeabi" #endif#elif defined(__i386__) #define ABI "x86"#elif defined(__x86_64__) #define ABI "x86_64"#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */ #define ABI "mips64"#elif defined(__mips__) #define ABI "mips"#elif defined(__aarch64__) #define ABI "arm64-v8a"#else #define ABI "unknown"#endif return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");}因為我們是拿這個c源碼檔案來使用,如果遷就Java_com_example_hellojni_HelloJni_stringFromJNI函數名的話,在我們的android工程中java類的聲明就要是:com/example/hellojni/HelloJni.java。 二、編譯,開啟cmd命令列視窗
D:\>cd D:\android-ndk-r10e\samples\hello-jni\jniD:\android-ndk-r10e\samples\hello-jni\jni>ndk-build[arm64-v8a] Gdbserver : [aarch64-linux-android-4.9] libs/arm64-v8a/gdbserver[arm64-v8a] Gdbsetup : libs/arm64-v8a/gdb.setup[x86_64] Gdbserver : [x86_64-4.9] libs/x86_64/gdbserver[x86_64] Gdbsetup : libs/x86_64/gdb.setup[mips64] Gdbserver : [mips64el-linux-android-4.9] libs/mips64/gdbserver[mips64] Gdbsetup : libs/mips64/gdb.setup[armeabi-v7a] Gdbserver : [arm-linux-androideabi-4.8] libs/armeabi-v7a/gdbserver[armeabi-v7a] Gdbsetup : libs/armeabi-v7a/gdb.setup[armeabi] Gdbserver : [arm-linux-androideabi-4.8] libs/armeabi/gdbserver[armeabi] Gdbsetup : libs/armeabi/gdb.setup[x86] Gdbserver : [x86-4.8] libs/x86/gdbserver[x86] Gdbsetup : libs/x86/gdb.setup
編譯成功會在D:\~\samples\hello-jni\libs\armeabi目錄下產生libhello-jni.so檔案。
不光是armeabi 其他所有平台都會產生.so檔案
現在程式就能運行啦
stringFromJNI()其實調用的是.so檔案中的方法
程式運行結果:
《Android進階》之第七篇 NDK的使用