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

时间:2016-02-12 17:42:31

标签: java android c++ android-studio android-ndk

过去几天我一直在解决这个问题。我正在尝试将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
    | - | - | - 主
    | - | - | - | --jni
    | - | - | - | - | --live
    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
    

    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)
    
  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
    
  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'
    }
    
  9. 然后我在ndk-build文件夹中运行$PROJECT_DIR\app\src\main\jni

  10. ndk-build命令导致以下文件夹结构/文件输出:
    $ PROJECT_DIR
    | --app
    | | - | --src
    | - | - | - 主
    | - | - | - | --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.so
    | - | - | - | - | - | - | --libstlport_shared.so

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

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

    package com.company.android.myapp;
    
    public class Live555Ndk {
    
        static {
            System.loadLibrary("live555");
        }
    
    }
    

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

    感谢您的任何见解。

    更新 02/15/2016

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

    我想我现在已经开始思考它是如何运作的,但我仍然无法引用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文件夹?

1 个答案:

答案 0 :(得分:3)

Check out the many Android NDK samples developed by Google. You can find them here.

The hello-gl2 example is a good place to start.

gl_code.cpp shows you how to create JNI code which can be called from Java. Pay particular attention to this part of the code, which defines two methods and makes them visible to the Java layer:

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();
}

GL2JNILib.java shows you how to call the methods defined in gl_code.cpp from Java.

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();
}

UPDATE:

To build a C++ module which relies on the live555 library, you'll need to add the following section to Android.mk:

include $(CLEAR_VARS)
LOCAL_MODULE := your_module
LOCAL_SRC_FILES := your_module_file.cpp
LOCAL_SHARED_LIBRARIES := live555
include $(BUILD_SHARED_LIBRARY)

See this documentation for reference: