AndroidNDK初步之如何调用jni及.so和mk的配置

上节说了使用Eclipse安装NDK环境及JNI的配置,这节将说明AndroidNDK开发中如何调用JNI生成.so文件,其实想用3节的,还想连Android.mk的配置和如何在build时能够导出第三方的.so文件而不被删除的方法,但既然说了2节,那就在这一节一起说了吧,有福了哦~

        话说标题有字数限制,其实这节主要讲的是三点:

        1、如何调用jni生成.so文件;

        2、Android.mk配置;

        3、第三方so不被删除的方法。

工具/原料

  • java环境
  • eclipse、NDK、JNI

一、Android如何调用jni生成.so文件

  1. 1

    首先,先写Android代码,建立本地接口(实际上是一个类,相对jni而言是接口),为使程序中可以调用。

    public class EncryptJni {

        static{

            System.loadLibrary("encrypt_jni");

        }

        public native static int encrypt(int param);

    }

  2. 2

    然后,编写C/C++代码,这里注意新版本NDK中,JNI默认新建的C文件类型是.cpp的,所以要在写函数前后加上如下代码:

    extern "C"{

    }

    再extern "C"{}大括号里边写函数体,例如以下代码:

    #include 

    extern "C"{

        jint

        Java_com_tongleer_android_accountbook_jni_EncryptJni_encrypt( jint jparam )

        {

            return jparam^1;

        }

    }

    END

二、Android.mk的配置

  1. 1

    到这里你的Android程序中就能调用jni了,在项目中jni文件夹中的.cpp文件同级还有个Android.mk文件,它是存放jni文件配置信息的,一般由系统自动生成,但为确保正确,还是最好检查一遍,你的Android.mk大概是如图的样子:

    LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_MODULE    := encrypt_jni

    LOCAL_SRC_FILES := encrypt_jni.cpp

    include $(BUILD_SHARED_LIBRARY)

    END

三、第三方so不被删除的方法

  1. 如果你的项目中用到了第三方比如像友盟SDK,那么就会用到一些没有源码的.so文件,这是需要在Android.mk中配置,否则当你Build项目时是不会导出第三方的.so文件的,你可以进行如下操作:

    1、在Android.mk最后添加一句代码:

    include $(LOCAL_PATH)/prebuild/Android.mk

  2. 然后在项目的jni文件夹在新建一个文件夹,名称随意,比如叫prebuild,在里边新建Android.mk,打开Android.mk编写关联第三方.so文件的语句,参考如下方式编写:

    include $(CLEAR_VARS)

    LOCAL_MODULE := bspatch

    LOCAL_SRC_FILES := prebuild/libbspatch.so

    include $(PREBUILT_SHARED_LIBRARY)

    include $(CLEAR_VARS)

    LOCAL_MODULE := cocklogic

    LOCAL_SRC_FILES := prebuild/libcocklogic.so

    include $(PREBUILT_SHARED_LIBRARY)

    include $(CLEAR_VARS)

    LOCAL_MODULE := tnet-2.1.20.1-agoo

    LOCAL_SRC_FILES := prebuild/libtnet-2.1.20.1-agoo.so

    include $(PREBUILT_SHARED_LIBRARY)

    include $(CLEAR_VARS)

    LOCAL_MODULE := umeng_opustool

    LOCAL_SRC_FILES := prebuild/libumeng_opustool.so

    include $(PREBUILT_SHARED_LIBRARY)

    include $(CLEAR_VARS)

    LOCAL_MODULE := smssdk

    LOCAL_SRC_FILES := prebuild/libsmssdk.so

    include $(PREBUILT_SHARED_LIBRARY)

  3. 到这里,并且你还要把所需要的第三方.so文件放到prebuild文件夹下。

  4. 这是你就可以Build、执行或者导出apk项目了,但这只能讲.so文件导出到armeabi一个平台下,我们需要支持更多的平台,你需要在jni目录下新建Application.mk文件,并输入以下语句:

    APP_ABI := arm64-v8a armeabi armeabi-v7a# x86 mips mips64 x86_64

    APP_ABI := all

  5. 到以上为止,你可以顺利编译项目并将.so放到每个文件夹下了,但如果控制台报了一个说你APP_PLATFORM版本高于AndroidManifest.xml中的minSdkVersion,那你就在Application.mk中添加类似如下语句即可(让二者版本相同):

    APP_PLATFORM := android-17

  6.         最后,我这里目前遇到一个问题,就是友盟SDK的.so文件,比如友盟推送,他们是支持所有平台的,但我只要一build只会将.so导出到arm64-v8a、armeabi、armeabi-v7a这3个平台中,mips、mips64、x86、x86_64这4个平台会报错说不识别.so文件,不知道是友盟SDK的问题还是Google快要遗弃Eclipse的问题还是我需要改什么配置文件的问题(比如百度到的config.mk,至于它是什么,不知道,什么linux里的文件,不太懂~就不误导了~),这里需要大牛告诉我一下。

            面对这个问题,我只能这样解决:生成我自己写jni生成的.so后,把项目删掉C库,在没有jni的情况下,去把所有.so文件放到libs里,再进行操作,这样就没有问题了,但似乎有些麻烦了。

    END

注意事项

  • 以上已用最通俗的方式将Android中进行JNI开发会遇到的各种细节问题展现出来,这里需要注意Android.mk文件一般会将C++文件自动配置到里边,但最好还要检查一遍,以防出错,最后还要建议最好用Android Studio替代古老的Eclipse开发。
  • 最后遗留的问题可供讨论。

你可能感兴趣的:(日常积累)