android NDK学习篇4之two-libs——使用(单个动态库)来生成动态库

来源:互联网 发布:龙卷风中心知乎 编辑:程序博客网 时间:2024/06/06 12:25

还要基于NDK提供的two-libs例子,来实现使用第三方动态库链接生成最终动态库(老感觉有点别扭)。

简单来说就是实现在so文件里面调用第三方的so文件中的方法。

1、建立android工程,编写java对应JNI层的本地接口(这里跟two-libs一样,就多了一个加载第三方库语句)。

package com.example.twolibs;import android.app.Activity;import android.widget.TextView;import android.os.Bundle;
public class TwoLibs extends Activity{    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        TextView  tv = new TextView(this);        int       x  = 1000;        int       y  = 42;        // here, we dynamically load the library at runtime        // before calling the native method.        //        int  z = add(x, y);        tv.setText( "The sum of " + x + " and " + y + " is " + z );        setContentView(tv);            }    public native int add(int  x, int  y);        static    {    System.loadLibrary("twolib-first");        System.loadLibrary("twolib-second");    }}


​JNI文件夹下的准备预备文件如下,其中用first.c和Makefile文件是用来生成所谓的第三方动态库文件libtwolib-first.so,具体操作见下:

Android.mk  first.c  first.h  Makefile  prebuilt  second.c

跟之前编写静态库文件方法类似,都是用NDK下的编译器生成的,只不过在这里写到Makefile文件中而已,具体操作见下:

first.h与first.c文件如:

#ifndef FIRST_H#define FIRST_Hextern int first(int  x, int  y);#endif /* FIRST_H */#include "first.h"int  first(int  x, int  y){    return x + y;}

Makefile文件如下:

NDK_PATH = /home/thinker/android/android-ndk-r8eTOOLCHAIN_PATH = $(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/binCFLAGS = -I$(NDK_PATH)/platforms/android-8/arch-arm/usr/includeLDFLAGS = -L$(NDK_PATH)/platforms/android-8/arch-arm/usr/libCC = $(TOOLCHAIN_PATH)/arm-linux-androideabi-gccLD = $(TOOLCHAIN_PATH)/arm-linux-androideabi-ldall:         $(CC) -O2 -fPIC -c $(CFLAGS) $(LDFLAGS) first.c -o twolib-first.o         $(LD) -o libtwolib-first.so twolib-first.o -shared           rm -rf twolib-first.o clean:         rm -rf libtwolib-first.so

跳转到jni目录下,执行make即可生成此libtwolib-first.so这个动态库,即所谓的第三方库。

2、就是编写JNI文件,在其中调用第三方库中的接口int first(int x,int y);具体如下:
#include "first.h"#include <jni.h>jintJava_com_example_twolibs_TwoLibs_add( JNIEnv*  env,                                      jobject  this,                                      jint     x,                                      jint     y ){    return first(x, y);}
3、编写Android.mk文件,就将第三方库链接到此动态库中来。此处有两种写法:
第一种:
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := libtwolib-first LOCAL_SRC_FILES := libtwolib-first.soinclude $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_SHARED_LIBRARIES := libtwolib-firstLOCAL_MODULE    := libtwolib-secondLOCAL_SRC_FILES := second.cinclude $(BUILD_SHARED_LIBRARY)
第二种方法,其实就是换种形式而已,都一样。在jni目录下创建一个prebuit文件夹,下面存放一个预处理的Android.mk文件和第三方动态库,如:
thinker@fans:~/android/android-ndk-r8e/samples/two-libs/jni/prebuilt$ lsAndroid.mk  libtwolib-first.so
prebuilt目录下Android.mk就是申明一个模块的意思,内容如:
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := libtwolib-firstLOCAL_SRC_FILES := libtwolib-first.soinclude $(PREBUILT_SHARED_LIBRARY)
此时jni目录下的Android.mk文件不需要声明这个模块了,直接用就Ok了,具体如下:
LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := libtwolib-secondLOCAL_SRC_FILES := second.cLOCAL_SHARED_LIBRARIES := libtwolib-firstinclude $(BUILD_SHARED_LIBRARY)include $(LOCAL_PATH)/prebuilt/Android.mk
4、生成动态库:
thinker@fans:~/android/android-ndk-r8e/samples/two-libs/jni$ /home/thinker/android/android-ndk-r8e/ndk-build/home/thinker/android/android-ndk-r8e/build/core/add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 3 in /home/thinker/android/android-ndk-r8e/samples/two-libs/AndroidManifest.xml    Prebuilt       : libtwolib-first.so <= jni/Install        : libtwolib-first.so => libs/armeabi/libtwolib-first.soCompile thumb  : twolib-second <= second.cSharedLibrary  : libtwolib-second.soInstall        : libtwolib-second.so => libs/armeabi/libtwolib-second.so

5、运行输出运算结果。OK。

再次记录下整个过程。



原创粉丝点击