Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java Android Studio项目中使用.so共享库_Java_Android_C++_Android Studio_Android Ndk - Fatal编程技术网

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

如何在Java Android Studio项目中使用.so共享库,java,android,c++,android-studio,android-ndk,Java,Android,C++,Android Studio,Android Ndk,过去几天我一直在研究这个问题。我正在尝试使用C/C++流媒体服务器live555(),作为Java Android Studio项目中的库。我已经能够使用ndk build创建一组.so文件,但是我找不到任何文档说明如何在Java应用程序中使用该库。以下是我的设置: Windows 8.1 64位 OracleJDK1.8 Android Studio 1.5.1 渐变1.5.0 构建工具23.0.2 到目前为止为达到我的目标所采取的步骤: 使用Android Studio创建标准的Andr

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

  • Windows 8.1 64位
  • OracleJDK1.8
  • Android Studio 1.5.1
  • 渐变1.5.0
  • 构建工具23.0.2
到目前为止为达到我的目标所采取的步骤:

  • 使用Android Studio创建标准的Android应用程序
  • 右键单击Project explorer中的应用程序模块,然后从关联菜单中选择新建|文件夹| JNI文件夹
  • 从选择live555-latest.tar.gz文件下载live555源代码
  • 将源文件解压缩到JNI文件夹,这样您现在就有了一个文件夹结构,如:
    $PROJECT|u DIR
    --app
    --src
    ----src--main
    ----JNI--JNI
    ----live文件夹包含live555源文件的地方
  • 在上面的
    jni
    文件夹中,创建
    Android.mk
    Application.mk
    文件。
    Application.mk
    文件包含:

    APP_OPTM := release
    APP_ABI := armeabi armeabi-v7a
    APP_PLATFORM := android-21
    APP_STL := stlport_shared
    
    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)
    
    package com.company.android.myapp;
    
    public class Live555Ndk {
    
        static {
            System.loadLibrary("live555");
        }
    
    }
    
    Android.mk
    文件包含:

    APP_OPTM := release
    APP_ABI := armeabi armeabi-v7a
    APP_PLATFORM := android-21
    APP_STL := stlport_shared
    
    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)
    
    package com.company.android.myapp;
    
    public class Live555Ndk {
    
        static {
            System.loadLibrary("live555");
        }
    
    }
    
  • 在我的
    $PROJECT\u DIR\gradle.properties
    文件中,我包含了行
    android.useDeprecatedNDDK=true

  • $PROJECT\u DIR\local.properties
    中,我有:

    ndk.dir=C\:\\Users\\user\\AppData\\Local\\Android\\ndk
    sdk.dir=C\:\\Users\\user\\AppData\\Local\\Android\\sdk
    
  • 在我的
    $PROJECT\u 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'
    }
    
  • 然后在
    $PROJECT\u DIR\app\src\main\jni
    文件夹中运行
    ndk build

  • ndk build
    命令生成以下文件夹结构/文件



    <

    <






















    ><<
    ><
    <><<
    ><<<
    ><<
    <<
    <>><<<<<
    >>>><
    <<<<
    >>>><>>><<<<>>><<<<<<>>7a
    |--|--|--|--|--|--liblive555.so
    |--|--|--libstport|u共享。so
    |--|--|--obj
    --|--libstport|--local
    |--|--|--|--|--|--(2004年???
    <
    <<
    <

    <<\span span span span>\span span><--------------------------------libstlport|u shared.so

    当我从build | Make project菜单选项构建项目时,Android视图中有一个项目结构,如下所示:
    app
    |--manifests
    |--java
    |--jniLibs
    |--armeabi
    |--liblive555.so
    |--libstlport|u共享。so
    |--armeabi-v7a
    --lib555.so
    --libstlport|--

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

    APP_OPTM := release
    APP_ABI := armeabi armeabi-v7a
    APP_PLATFORM := android-21
    APP_STL := stlport_shared
    
    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)
    
    package com.company.android.myapp;
    
    public class Live555Ndk {
    
        static {
            System.loadLibrary("live555");
        }
    
    }
    
    但是,既然我有了共享对象,我不知道如何开始在live555库上创建对象实例和调用方法。谁能给我指出正确的方向吗

    谢谢你的见解

    更新2016年2月15日

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


    我想我现在已经想好了这是如何工作的,但我仍然无法引用live555库。我用一个活动和相应的布局文件启动了一个新的Android项目。我添加了一个
    jniLibs
    文件夹,并将armeabi\liblive555.so etc文件复制到该文件夹中。我在前面提到的Live555Ndk.java文件中添加了静态构造函数,并调用了
    SystemloadLibrary(“live555”)。我还添加了对
    public native boolean isThisMediaSession()的调用。然后,我使用javah在
    jni
    文件夹中生成一个头文件。然后我创建了相应的.cpp文件来创建方法实现。但是,我不能包含liblive555.so中的任何头文件。就像Android Studio甚至不知道live555库的存在一样。因此,我不能有一行,比如
    #include
    。我是否错过了一个额外的步骤?这个Android项目只有.so文件,没有源文件。我是否需要将live555源代码添加到
    jni
    文件夹中?

    查看谷歌开发的许多Android NDK示例。你可以找到他们

    这个例子是一个很好的起点

    演示如何创建可从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();
    }
    
    演示如何从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();
    }
    
    更新:

    < >构建一个依赖于LIVE55库的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)
    
    请参阅本文档以获取参考:


    您的Android.mk和Application.mk内容已交换。也许,这只是本文中的内容,而不是现实生活中的内容。请检查是否解决了您的问题。底线是,您需要一些包装器来建立(Java)应用程序与live555库之间的通信。谢谢,@AlexCohn。我切换了文件名以正确反映内容。作为@bullsy正确答案的补充说明,build.gradle中的ndk{}块没有任何效果,因为您使用的是
    android.usedprecatedndk=true
    。重要的部分是Android.mk中的
    LOCAL_MODULE:=live555
    ,并且(正如您所正确做的那样)在loadLibrary调用中使用相同的模块名称。当您说“是的,我不能有一行,例如#include”,不清楚问题是什么。是否有错误消息?代码编译失败了吗?你确定头文件的路径正确吗?请参阅我上面更新的帖子。我的理解力有了进一步的提高,但我不能进去