《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 */ jstring Java_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\jni D:\android-ndk-r10e\samples\hello-jni\jni>ndk-build [arm64-v8a] Gdbserver : [aarch64-linux-android-4.9] libs/arm64-v8a/gdbserve r [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/gdbs erver [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文件中的方法程序运行结果:
时间: 2024-10-27 07:46:28