如何在Java Android Studio项目中使用.so共享库
过去几天我一直在研究这个问题。我正在尝试使用C/C++流媒体服务器live555(),作为Java Android Studio项目中的库。我已经能够使用ndk build创建一组.so文件,但是我找不到任何文档说明如何在Java应用程序中使用该库。以下是我的设置:如何在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
- Windows 8.1 64位
- OracleJDK1.8
- Android Studio 1.5.1
- 渐变1.5.0
- 构建工具23.0.2
$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”,不清楚问题是什么。是否有错误消息?代码编译失败了吗?你确定头文件的路径正确吗?请参阅我上面更新的帖子。我的理解力有了进一步的提高,但我不能进去