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

还要基于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_H
extern 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-r8e
TOOLCHAIN_PATH = $(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin
CFLAGS = -I$(NDK_PATH)/platforms/android-8/arch-arm/usr/include
LDFLAGS = -L$(NDK_PATH)/platforms/android-8/arch-arm/usr/lib
CC = $(TOOLCHAIN_PATH)/arm-linux-androideabi-gcc
LD = $(TOOLCHAIN_PATH)/arm-linux-androideabi-ld

all: 
        $(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 

jint
Java_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.so		
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := libtwolib-first
LOCAL_MODULE    := libtwolib-second
LOCAL_SRC_FILES := second.c
include $(BUILD_SHARED_LIBRARY)
第二种方法,其实就是换种形式而已,都一样。在jni目录下创建一个prebuit文件夹,下面存放一个预处理的Android.mk文件和第三方动态库,如:
thinker@fans:~/android/android-ndk-r8e/samples/two-libs/jni/prebuilt$ ls
Android.mk  libtwolib-first.so
prebuilt目录下Android.mk就是申明一个模块的意思,内容如:
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libtwolib-first
LOCAL_SRC_FILES := libtwolib-first.so
include $(PREBUILT_SHARED_LIBRARY)
此时jni目录下的Android.mk文件不需要声明这个模块了,直接用就Ok了,具体如下:
LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libtwolib-second
LOCAL_SRC_FILES := second.c
LOCAL_SHARED_LIBRARIES := libtwolib-first
include $(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.so
Compile thumb  : twolib-second <= second.c
SharedLibrary  : libtwolib-second.so
Install        : libtwolib-second.so => libs/armeabi/libtwolib-second.so

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

再次记录下整个过程。



你可能感兴趣的:(android,NDK)