zoukankan      html  css  js  c++  java
  • android java层通过jni加载使用第三方的so库

    1、例如我们自己编译一个so库,我们的其他模块要加载如何操作了

    首先在c盘新建立一个文件夹sb,在sb下面新建立一个文件夹jni,如果你要使用ndk编译so库,必须需要有jni目录

    2、在jni目录下面建立下面几个文件

    我们来看看c文件

    //
    // Created by wei.yuan on 2017/11/2.
    //
    #include<jni.h>
    #include<logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI.h>
    #include <jni.h>
    #include <string.h>
    #include <pthread.h>
    JNIEXPORT jstring JNICALL Java_logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI_getStringFromC
      (JNIEnv *env, jobject obj){
        int *a = (int *) (NULL);
        *a = 1;
        return (*env)->NewStringUTF(env,"I'm comes from 5454552444444to Native Function!");
      }

    然后是头文件

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity */
    
    #ifndef _Included_logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity
    #define _Included_logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity
    #ifdef __cplusplus
    extern "C" {
    #endif
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ABOVE_CLIENT
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ABOVE_CLIENT 8L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ADJUST_WITH_ACTIVITY
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_AUTO_CREATE
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_AUTO_CREATE 1L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_DEBUG_UNBIND
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_DEBUG_UNBIND 2L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_IMPORTANT
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_IMPORTANT 64L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_NOT_FOREGROUND
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_NOT_FOREGROUND 4L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_WAIVE_PRIORITY
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_WAIVE_PRIORITY 32L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_IGNORE_SECURITY
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_IGNORE_SECURITY 2L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_INCLUDE_CODE
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_INCLUDE_CODE 1L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_RESTRICTED
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_RESTRICTED 4L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_APPEND
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_APPEND 32768L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_MULTI_PROCESS
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_MULTI_PROCESS 4L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_PRIVATE
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_PRIVATE 0L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_WORLD_READABLE
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_WORLD_READABLE 1L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_WORLD_WRITEABLE
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_WORLD_WRITEABLE 2L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_DIALER
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_DIALER 1L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_DISABLE
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_DISABLE 0L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SHORTCUT
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_CANCELED
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_CANCELED 0L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_FIRST_USER
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_FIRST_USER 1L
    #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_OK
    #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_OK -1L
    /*
     * Class:     logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity
     * Method:    getStringFromC
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI_getStringFromC
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif

    现在我们要生成so库,需要配置android.mk文件和application.mk文化

    android.mk文件内容如下所示:

    ROOT_PATH := $(call my-dir)
    
    LOCAL_PATH := $(ROOT_PATH)
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := sb_jni
    LOCAL_SRC_FILES := logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI.c
    LOCAL_CFLAGS :=  -Wl,-g  
    LOCAL_LDLIBS := -llog
    include $(BUILD_SHARED_LIBRARY)

    application.mk文件如下所示:

    APP_STL := stlport_static
    APP_ABI := all
    APP_CXXFLAGS := -std=c++11 -D__STDC_LIMIT_MACROS
    APP_PLATFORM := android-12

    有了上面的配置之后,我们就可以在cgwin环境中生成对应的so库文件了,cgwin进入到对应的jni目录,使用ndk-build命令

    编译成功之后会在jni的目录下产生下面的两个文件夹

    libs文件下面的so库就是可以提高给第三方使用的so库,obj目录下生成的so库就是具有调试信息的so库,当发现奔溃的时候,可以使用工具arm-linux-androideabi-addr2line.exe解决该obj目录下的so库来定位文件

    现在我们在android studio下面新建立一个工程

    我们将上面的libs目录拷贝到工程和src同级别的目录下

    然后在工程的gradle文件中配置下面的代码

    sourceSets {
    main {
    jniLibs.srcDirs = ['libs']
    }
    }
    完成的gradle代码如下
    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 24
        buildToolsVersion "24.0.2"
        defaultConfig {
            applicationId "cn.onlinecache.breakpad"
            minSdkVersion 9
            targetSdkVersion 24
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
        sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }
    }
    
    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
            exclude group: 'com.android.support', module: 'support-annotations'
        })
        compile project(':breakpad')
    
    
        compile 'com.android.support:appcompat-v7:24.2.1'
        compile 'com.jakewharton:butterknife:8.4.0'
        compile 'com.android.support.constraint:constraint-layout:1.0.2'
        testCompile 'junit:junit:4.12'
        annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
    }

    通过上面的配置,我们编译工程就会自动生成jNIlibs目录

     然后我们要在代码中使用so库中的函数,如何使用了

    JNIEXPORT jstring JNICALL Java_logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI_getStringFromC
      (JNIEnv *env, jobject obj){
        int *a = (int *) (NULL);
        *a = 1;
        return (*env)->NewStringUTF(env,"I'm comes from 5454552444444to Native Function!");
      }

    从c语言中我们可以看出,这个函数是 通过JNI编程规范编写的,必须要满足JNI的编程规范,通过
    JNIEXPORT jstring JNICALL Java_logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI_getStringFromC我们可以知道对应该函数的java层对应的
    包名是
    logback.ecmapplication.cetcs.com.myapplicationkldsk
    对应的类名是JNI,对应的函数名是
    getStringFromC
    所以我们在工程中应该要建立下面的这样一个文件
    package logback.ecmapplication.cetcs.com.myapplicationkldsk;
    
    /**
     * Created by wei.yuan on 2017/11/13.
     */
    
    public class JNI {
        public  native  String  getStringFromC();
        static {
            System.loadLibrary("sb_jni");
        }
    }

    在这个文件中加载so 库进行调用

    调用者:

     new JNI().getStringFromC()

    工程结构如下:

     工程项目代码如下所示:

    http://pan.baidu.com/s/1nvHuufB

  • 相关阅读:
    关于抽象类
    封装.继承.多态
    构造方法
    String
    无参方法与有参方法
    类和对象
    使用分层实现业务处理(二)
    使用分层实现业务处理(一)
    序列化Serializable接口
    用JSP从数据库中读取图片并显示在网页上
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/7825860.html
Copyright © 2011-2022 走看看