如何在Java Android Studio项目中使用.so共享库

Rob*_*oid 7 c++ java android android-ndk android-studio

在过去的几天里,我一直在解决这个问题.我正在尝试使用live555(http://www.live555.com/),一个C/C++流媒体服务器,作为Java Android Studio项目中的库.我已经能够使用ndk-build来创建一组.so文件,但是我找不到任何关于如何在我的Java应用程序中使用该库的文档.这是我的设置:

  • Windows 8.1 64位
  • Oracle JDK 1.8
  • Android Studio 1.5.1
  • Gradle 1.5.0
  • 构建工具23.0.2

到目前为止我所采取的步骤:

  1. 使用Android Studio创建标准Android应用程序.
  2. 右键单击Project explorer中的app模块,然后选择New | 文件夹| 上下文菜单中的JNI文件夹.
  3. http://www.live555.com/liveMedia/public/下载live555来源,选择live555-latest.tar.gz文件.
  4. 将源解压缩到JNI文件夹,以便您现在拥有如下文件夹结构:
    $ PROJECT_DIR
    | --app
    | - | --src
    | - | - | --main
    | - | - | - | --jni
    | - | - | - | - | --live
    实时文件夹包含live555源.
  5. jni上面的文件夹中,创建Android.mkApplication.mk文件.该Application.mk文件包含:

    APP_OPTM := release
    APP_ABI := armeabi armeabi-v7a
    APP_PLATFORM := android-21
    APP_STL := stlport_shared
    
    Run Code Online (Sandbox Code Playgroud)

    Android.mk文件包含:

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := live555
    
    LOCAL_SRC_FILES := \
    live\BasicUsageEnvironment\BasicHashTable.cpp                \
    live\BasicUsageEnvironment\BasicTaskScheduler0.cpp           \
    ...All of the rest of the .c and .cpp files
    
    LOCAL_C_INCLUDES := \
        $(LOCAL_PATH)\live \
        $(LOCAL_PATH)\live\BasicUsageEnvironment\include \
        $(LOCAL_PATH)\live\BasicUsageEnvironment \
        $(LOCAL_PATH)\live\UsageEnvironment\include \
        $(LOCAL_PATH)\live\UsageEnvironment \
        $(LOCAL_PATH)\live\groupsock\include \
        $(LOCAL_PATH)\live\groupsock \
        $(LOCAL_PATH)\live\liveMedia\include \
        $(LOCAL_PATH)\live\liveMedia \
    
    LOCAL_CPPFLAGS += -fPIC -fexceptions -DXLOCALE_NOT_USED=1 -DNULL=0 -DNO_SSTREAM=1 -UIP_ADD_SOURCE_MEMBERSHIP
    
    include $(BUILD_SHARED_LIBRARY)
    
    Run Code Online (Sandbox Code Playgroud)
  6. 在我的$PROJECT_DIR\gradle.properties文件中,我已经包含了该行android.useDeprecatedNdk=true

  7. $PROJECT_DIR\local.properties,我有:

    ndk.dir=C\:\\Users\\user\\AppData\\Local\\Android\\ndk
    sdk.dir=C\:\\Users\\user\\AppData\\Local\\Android\\sdk
    
    Run Code Online (Sandbox Code Playgroud)
  8. 在我的$PROJECT_DIR\app\build.gradle档案中,我有:

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.2"
    
        defaultConfig {
            applicationId "com.company.android.myapp"
            minSdkVersion 21
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
    
            ndk {
                moduleName "live555"
            }
    
            sourceSets.main {
                jni.srcDirs = []
                jniLibs.srcDir "src\\main\\libs"
            }
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:23.1.1'
    }
    
    Run Code Online (Sandbox Code Playgroud)
  9. 然后我ndk-build$PROJECT_DIR\app\src\main\jni文件夹中运行.

ndk-build命令导致以下文件夹结构/文件输出:
$ PROJECT_DIR
| --app
| - | --src
| - | - | --main
| - | - | - | --libs
| - - | - | - | - | --armeabi
| - | - | - | - | - | --liblive555.so
| - | - | - | - | - | --libstlport_shared.so
| - | - | - | - | --armeabi-v7a
| - | - | - | - | - | --liblive555.so
| - | - - | - | - | - | --libstlport_shared.so
| - | - | - | --obj
| - | - | - | - | --local
| - | - - | - | - | - | --armeabi
| - | - | - | - | - | - | --objs
| - | - | - | - | - - | - | --liblive555.so
| - | - | - | - | - | - | --libstlport_shared.so
| - | - | - | - | - | --armeabi-v7a
| - | - | - | - | - | - | --objs
| - | - | - | - | - | - | --liblive555.所以
| - | - | - | - | - | - | --libstlport_shared.so

当我从Build |中构建项目时 创建项目菜单选项,我在Android视图中有一个项目结构,如下所示:
app
| --manife
| --java
| --jniLibs
| - | --armeabi
| - | - | --liblive555.so
| - | - | --libstlport_shared.so
| - | --armeabi-v7a
| - | - | --liblive555.so
| - | - | --libstlport_shared.so
| --res

我在我的项目中添加了一个Live555Ndk.java文件,从该文件开始引用live555库.它包含:

package com.company.android.myapp;

public class Live555Ndk {

    static {
        System.loadLibrary("live555");
    }

}
Run Code Online (Sandbox Code Playgroud)

但是,我不知道如何开始创建对象实例并在live555库上调用方法,因为我有共享对象.谁能指出我正确的方向?

感谢您的任何见解.

更新 02/15/2016

好的,我已ndk {}根据mcwise的以下建议从app\build.gradle文件中删除了该块.

我想我现在已经开始思考它是如何工作的,但我仍然无法引用live555库.我用一个活动和相应的布局文件开始了一个新的Android项目.我添加了一个jniLibs文件夹,并将armeabi\liblive555.so等文件复制到该文件夹​​中.我在前面提到的Live555Ndk.java文件中添加了静态构造函数并调用SystemloadLibrary("live555");.我还加了一个电话public native boolean isThisMediaSession();.然后我使用javah在文件jni夹中生成头文件.然后我创建了相应的.cpp文件来创建方法实现.但是,我不能包含liblive555.so中的任何头文件.这就像Android Studio甚至不知道live555库的存在.所以,我不能有这样的一条线#include <live555/MediaSession.hh>.我错过了一个额外的步骤吗?这个Android项目只有.so文件,而不是源文件.我是否需要将live555源添加到该jni文件夹?

Fra*_*zzi 4

查看 Google 开发的许多 Android NDK 示例。您可以在这里找到它们。

hello -gl2示例是一个很好的起点。

gl_code.cpp向您展示了如何创建可以从 Java 调用的 JNI 代码。特别注意这部分代码,它定义了两个方法并使它们对Java层可见:

extern "C" {
  JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env,
    jobject obj,  jint width, jint height);
  JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, 
    jobject obj);
};

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height)
{
  setupGraphics(width, height);
}

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj)
{
  renderFrame();
}
Run Code Online (Sandbox Code Playgroud)

GL2JNILib.java向您展示了如何从 Java 调用 gl_code.cpp 中定义的方法。

public class GL2JNILib {

  static {
    System.loadLibrary("gl2jni");
   }

  /**
   * @param width the current view width
   * @param height the current view height
   */
   public static native void init(int width, int height);
   public static native void step();
}
Run Code Online (Sandbox Code Playgroud)

更新:

要构建依赖于 live555 库的 C++ 模块,您需要将以下部分添加到 Android.mk:

include $(CLEAR_VARS)
LOCAL_MODULE := your_module
LOCAL_SRC_FILES := your_module_file.cpp
LOCAL_SHARED_LIBRARIES := live555
include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)

请参阅此文档以供参考: