我在Eclipse中有一个完美的android项目,该项目包括NDK支持并使用Gstreamer。 当我将项目从Eclipse迁移到Android Studio时会弹出各种问题,而我只是无法成功编译项目。
我对我遇到的每一个错误进行了彻底的研究,但仍然无法在android studio上编译和运行该项目。
https://drive.google.com/file/d/0B_euzgSjTAqcQngwbzR1cXY0MkU/view?usp=sharing
工作Eclipse项目的链接,我希望有人能以正确的方式指导我。
这是导入摘要:
以下文件未被复制到新的Gradle项目中;您 应评估您的项目是否仍然需要这些以及是否 所以手动移动它们:
导入程序将以下.jar文件识别为第三方 库而是用Gradle依赖项替换它们。这有 知道更明确的版本信息的优点,以及 库可以自动更新。但是,有可能 项目中的.jar文件版本比版本旧 我们选择的依赖项,这可能导致项目无法编译。 您可以在导入向导中禁用jar替换,然后重试:
android-support-v4.jar => com.android.support:support-v4:23.3.0
Android Gradle项目使用与ADT不同的目录结构 Eclipse项目。以下是项目的重组方式:
您现在可以构建项目。 Gradle项目需要网络 连接下载依赖项。
如果由于某种原因您的项目没有构建,并且您确定了 这是由于Eclipse到Gradle导入程序的错误或限制, 请在http://b.android.com的类别中提交错误 组件的工具。
(此导入摘要仅供参考,可以删除 导入后,如果您对结果感到满意。)
的build.gradle:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "com.gst_sdk_tutorials.tutorial_4"
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 22
}
}
android.ndk {
moduleName = "tutorial-4"
cppFlags.addAll(["-I${file("src/main/jni/Common/native_app_glue")}".toString(),
"-I${file("src/main/jni/Common/cpufeatures")}".toString(),
"-I${file("src/main/jni/Common/ndk_helper")}".toString()])
ldLibs.addAll(["android", "EGL", "GLESv2", "dl", "log", "atomic"])
stl = "c++_static"
}
// jni is the default dir; config this if yours is in different directory
android.sources {
main {
jni {
source {
srcDirs 'src/main/jni'
}
}
}
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
}
}
// Turn on hard float support in armeabi-v7a
android.abis {
create("armeabi-v7a") {
cppFlags.addAll(["-mhard-float", "-D_NDK_MATH_NO_SOFTFP=1", "-mfloat-abi=hard"])
ldLibs.add("m_hard")
ldFlags.add("-Wl,--no-warn-mismatch")
}
}
android.productFlavors {
create ("arm7") {
ndk.abiFilters.add("armeabi-v7a")
}
create ("arm8") {
ndk.abiFilters.add("arm64-v8a")
}
create ("x86-32") {
ndk.abiFilters.add("x86")
}
// for detailed abiFilter descriptions, refer to "Supported ABIs" @
// https://developer.android.com/ndk/guides/abis.html#sa
// build one including all productFlavors
create("fat")
}
}
dependencies {
compile 'com.android.support:support-v4:23.3.0'
compile files('libs/javacpp.jar')
compile files('libs/javacv.jar')
}
local.properties:
ndk.dir=C\:\\Users\\wiz\\Downloads\\android-ndk-r9d
sdk.dir=D\:\\sdk
.c文件:(因字符限制而未完成)
#include <string.h>
#include <jni.h>
#include <android/log.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
#include <gst/video/video.h>
#include <pthread.h>
GST_DEBUG_CATEGORY_STATIC (debug_category);
#define GST_CAT_DEFAULT debug_category
/*
* These macros provide a way to store the native pointer to CustomData, which might be 32 or 64 bits, into
* a jlong, which is always 64 bits, without warnings.
*/
#if GLIB_SIZEOF_VOID_P == 8
# define GET_CUSTOM_DATA(env, thiz, fieldID) (CustomData *)(*env)->GetLongField (env, thiz, fieldID)
# define SET_CUSTOM_DATA(env, thiz, fieldID, data) (*env)->SetLongField (env, thiz, fieldID, (jlong)data)
#else
# define GET_CUSTOM_DATA(env, thiz, fieldID) (CustomData *)(jint)(*env)->GetLongField (env, thiz, fieldID)
# define SET_CUSTOM_DATA(env, thiz, fieldID, data) (*env)->SetLongField (env, thiz, fieldID, (jlong)(jint)data)
#endif
/* Do not allow seeks to be performed closer than this distance. It is visually useless, and will probably
* confuse some demuxers. */
#define SEEK_MIN_DELAY (500 * GST_MSECOND)
/* Structure to contain all our information, so we can pass it to callbacks */
typedef struct _CustomData {
jobject app; /* Application instance, used to call its methods. A global reference is kept. */
GstElement *pipeline; /* The running pipeline */
GMainContext *context; /* GLib context used to run the main loop */
GMainLoop *main_loop; /* GLib main loop */
gboolean initialized; /* To avoid informing the UI multiple times about the initialization */
ANativeWindow *native_window; /* The Android native window where video will be rendered */
GstState state; /* Current pipeline state */
GstState target_state; /* Desired pipeline state, to be set once buffering is complete */
gint64 duration; /* Cached clip duration */
gint64 desired_position; /* Position to seek to, once the pipeline is running */
GstClockTime last_seek_time; /* For seeking overflow prevention (throttling) */
gboolean is_live; /* Live streams do not use buffering */
} CustomData;
/* playbin2 flags */
typedef enum {
GST_PLAY_FLAG_TEXT = (1 << 2) /* We want subtitle output */
} GstPlayFlags;
/* These global variables cache values which are not changing during execution */
static pthread_t gst_app_thread;
static pthread_key_t current_jni_env;
static JavaVM *java_vm;
static jfieldID custom_data_field_id;
static jmethodID set_message_method_id;
static jmethodID set_current_position_method_id;
static jmethodID on_gstreamer_initialized_method_id;
static jmethodID on_media_size_changed_method_id;
/*
* Private methods
*/
/* Register this thread with the VM */
static JNIEnv *attach_current_thread (void) {
JNIEnv *env;
JavaVMAttachArgs args;
GST_DEBUG ("Attaching thread %p", g_thread_self ());
args.version = JNI_VERSION_1_4;
args.name = NULL;
args.group = NULL;
if ((*java_vm)->AttachCurrentThread (java_vm, &env, &args) < 0) {
GST_ERROR ("Failed to attach current thread");
return NULL;
}
return env;
}
/* Unregister this thread from the VM */
static void detach_current_thread (void *env) {
GST_DEBUG ("Detaching thread %p", g_thread_self ());
(*java_vm)->DetachCurrentThread (java_vm);
}
/* Retrieve the JNI environment for this thread */
static JNIEnv *get_jni_env (void) {
JNIEnv *env;
if ((env = pthread_getspecific (current_jni_env)) == NULL) {
env = attach_current_thread ();
pthread_setspecific (current_jni_env, env);
}
return env;
}
导入前的android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := tutorial-4
LOCAL_SRC_FILES := tutorial-4.c
LOCAL_SHARED_LIBRARIES := gstreamer_android
LOCAL_LDLIBS := -llog -landroid
include $(BUILD_SHARED_LIBRARY)
ifndef GSTREAMER_SDK_ROOT
ifndef GSTREAMER_SDK_ROOT_ANDROID
$(error GSTREAMER_SDK_ROOT_ANDROID is not defined!)
endif
GSTREAMER_SDK_ROOT := $(GSTREAMER_SDK_ROOT_ANDROID)
endif
GSTREAMER_NDK_BUILD_PATH := $(GSTREAMER_SDK_ROOT)/share/gst-android/ndk-build/
include $(GSTREAMER_NDK_BUILD_PATH)/plugins.mk
GSTREAMER_PLUGINS := $(GSTREAMER_PLUGINS_CORE) $(GSTREAMER_PLUGINS_PLAYBACK) $(GSTREAMER_PLUGINS_CODECS) $(GSTREAMER_PLUGINS_NET) $(GSTREAMER_PLUGINS_SYS) $(GSTREAMER_PLUGINS_NET_RESTRICTED)
GSTREAMER_EXTRA_DEPS := gstreamer-interfaces-0.10 gstreamer-video-0.10
include $(GSTREAMER_NDK_BUILD_PATH)/gstreamer.mk
答案 0 :(得分:0)
我建议转移到AS,但保持NDK构建“传统方式”。我捍卫这种方法的主要论点是实验插件仍然是一个“移动目标”:DSL一直在变化,其局限性需要随着实验插件的每个版本而变化的变通方法。第二个原因是像Fabric这样的3个 rd 派对工具不适用于实验性插件。
对于非实验性插件,您可以在 build.gradle 中使用以下部分:
def ndkBuild = android.ndkDirectory
import org.apache.tools.ant.taskdefs.condition.Os
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
ndkBuild += '.cmd'
}
task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
commandLine '$ndkBuild', 'NDK_PROJECT_PATH="$jniSrc/..'
}
task cleanNative(type: Exec, description: 'Clean JNI object files') {
commandLine '$ndkBuild', 'clean', 'NDK_PROJECT_PATH="$jniSrc/..'
}
clean.dependsOn 'cleanNative'
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
tasks.all {
task -> if (task.name.contains('compileDebugNdk') || task.name.contains('compileReleaseNdk')) task.enabled = false
}