【问题标题】:Android New Build System, Experimental Plugin, JNI Library ModuleAndroid 新构建系统、实验性插件、JNI 库模块
【发布时间】:2016-02-18 21:19:57
【问题描述】:

我正在尝试将本机库添加到我现有的应用程序中。我的目标是使用插件在 Android Studio 中自己的模块中编译 C++ 库,而无需手动步骤(如果可能)。我尝试了许多建议,并得到提示,构建系统在将模块之间的库复制到构建中时存在问题。我没能解决这个问题。

以下是我设置的相关部分(和一些):

Android 工作室: Gradle 版本:2.10

项目文件结构:

myproject
+libmodule
| +src/main
| | +java
| | | `-MyWrapper.java
| | `jni
| |   `-MyJNI.cpp
| `-build.gradle
+appmodule
| +src/main
| | `java
| |   `-MyClass.java
| `-build.gradle
+gradle/wrapper
| `-gradle-wrapper.properties
+-build.gradle
`-settings.gradle

我的项目/settings.gradle:

include ':appmodule', ':libmodule'

我的项目/build.gradle:

buildscript {
    repositories {
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle-experimental:0.6.0-alpha9'
    }
}

allprojects {
    repositories {
        mavenCentral()
    }
}

gradle-wrapper.properties:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip

myproject/libmodule/build.gradle:

apply plugin: 'com.android.model.library'
model {
    android {
        compileSdkVersion =  23
        buildToolsVersion = "23.0.2"

        defaultConfig.with {
            minSdkVersion.apiLevel = 15
            targetSdkVersion.apiLevel = 23
        }
    }
    android.buildTypes {
        release {
            minifyEnabled = false
            proguardFiles.add(file("proguard-rules.txt"))
            proguardFiles.add(file("proguard-android.txt"))
        }
    }

    android.ndk {
        moduleName = "MyLibrary"
        stl = "gnustl_shared"

        cppFlags.add("-nostdinc++")
        cppFlags.add("-I\$(NDK)/sources/cxx-stl/stlport/stlport")
        cppFlags.add("-fexceptions")
        cppFlags.add("-frtti")
        cppFlags.add("-fpermissive")
        ldFlags.add("-nodefaultlibs")
        ldFlags.add("-Lsrc/main/jniLibs/armeabi-v7a")

        ldLibs.add("c")
        ldLibs.add("m")
        ldLibs.add("dl")
        ldLibs.add("log")
        ldLibs.add("gcc")
    }
    android.productFlavors {
        create("arm") {
            ndk.abiFilters.add("armeabi")
        }
        create("arm7") {
            ndk.abiFilters.add("armeabi-v7a")
        }
        create("arm8") {
            ndk.abiFilters.add("arm64-v8a")
        }
        create("x86") {
            ndk.abiFilters.add("x86")
        }
        create("x86-64") {
            ndk.abiFilters.add("x86_64")
        }
        create("mips") {
            ndk.abiFilters.add("mips")
        }
        create("mips-64") {
            ndk.abiFilters.add("mips64")
        }
        create("all")
    }

}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:23.1.1'
}

myproject/appmodule/build.gradle:

apply plugin: 'com.android.model.application'

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
    }
}

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    compile project(':libmodule')
    // Support Libraries
    // Maven Provided Libraries
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = '23.0.2'

        defaultConfig.with {
            applicationId = "com.me.myandroidapp"
            minSdkVersion.apiLevel = 15
            targetSdkVersion.apiLevel = 23
        }


    }
    android.dexOptions {
        jumboMode = true
    }


    android.packagingOptions {
      //Some specific removals for an included lib from maven
    }

    android.lintOptions {
        checkReleaseBuilds = false
        abortOnError = false
    }

    android.buildTypes {
        debug {
            debuggable = true
            minifyEnabled = false
            buildConfigFields.with {
                create() {
                    type = "boolean"
                    name = "SCREENSHOTS"
                    value = "true"
                }
            }
            buildConfigFields.with {
                create() {
                    type = "boolean"
                    name = "DEBUGGABLE"
                    value = "true"
                }
            }
            proguardFiles.add(file("proguard-rules.txt"))
            proguardFiles.add(file("proguard-android.txt"))
        }

        release {
            debuggable  = false
            minifyEnabled = true
            buildConfigFields.with {
                create() {
                    type = "boolean"
                    name = "SCREENSHOTS"
                    value = "false"
                }
            }
            buildConfigFields.with {
                create() {
                    type = "boolean"
                    name = "DEBUGGABLE"
                    value = "false"
                }
            }
            proguardFiles.add(file("proguard-rules.txt"))
            proguardFiles.add(file("proguard-android.txt"))
        }
    }
    android.productFlavors {
        create("prod") {
            applicationId = "com.me.myandroidapp"
        }

        create("dev") {
            applicationId = "com.me.myandroidapp"
        }

        create("beta") {
            applicationId = "com.me.myandroidapp"
        }

        create("staging") {
            applicationId = "com.me.myandroidapp"
        }
    }
}

if (project.hasProperty("MyProject.properties") && new File(project.property("MyProject.properties")).exists()) {
    // Get properties in the property file
    Properties props = new Properties()
    props.load(new FileInputStream(file(project.property("MyProject.properties"))))

    model {
        android {
            signingConfigs {
              //several configs here
            }
        }
        android.buildTypes {
            release {
                signingConfig  = signingConfigs.release
            }
        }
    }
}

MyWrapper.java:

package com.me.androidwrapper;

    public class MyWrapper {
        private native String doItNatively(String stringinput);

        public String doIt(String stringinput) {
            return doItNatively(stringinput);
        }

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

myjni.cpp:

extern "C" {

JNIEXPORT jstring JNICALL
Java_com_me_androidwrapper_MyWrapper_doItNatively(JNIEnv *env, jobject instance, jstring stringinput_) {
    // C++ happens here
}
}

MyClass.java:

// Weird behavior for IDE adding dependency module happens here:
import com.me.androidwrapper.MyWrapper; 

public class MyClass {
    public String makeItHappen(String inputstring) {

        MyWrapper mywrapper = new myWrapper();
        return mywrapper.doIt(inputstring);
    }
}

JNI 中没有 android.mk 文件。

从一个清理过的项目中,gradle 成功执行。当我在 appmodule 上运行 Make Module 时出现错误:

Error:(5, 37) error: package com.me.androidwrapper does not exist

...来自 MyClass.java 的 import 语句被突出显示。

如上所述,在 MyClass.java 的代码中,Android Studio 提供了一个快速修复,包括对模块“libmodule”的依赖,如果我选择它,IDE 会删除错误。如果我通过命令单击包、类或方法,IDE 会正确解析项目链接。

我在 StackOverflow 和插件组中关注了许多解决方案。有提到新的实验性插件和构建系统不会在其中几个模块之间复制本机库,我尝试了将 aar/jar 模块设置为中介的方法。我还尝试了手动将 aar 文件复制到模块库中并将其作为文件或 aar 引用的方法。大多数这些方法都不起作用,我得到的最好结果是成功构建,但是应用程序崩溃找不到 libMyLibrary.so

我已经通过使用 gradle 2.8 和 android 实验插件 0.4.0 将 JNI 直接包含到 appmodule 模块中成功地测试了该项目。这不是一个很好的解决方案,因为模块很复杂并且 C++ 代码是单独维护的。 0.4.0 插件作为多模块失败,库的 .so 不打包。

我对新的实验性插件的了解存在差距,我知道它有错误,它不完整,一些功能仍在讨论中。任何帮助追查我的错误,或为插件缺乏功能提供全面的解决方法将不胜感激。

【问题讨论】:

    标签: android android-studio android-ndk android-build


    【解决方案1】:

    如果您想在 Android Studio 中的现有应用程序中添加一些原生库,您可以通过三种标准方式来实现。请阅读此链接https://stackoverflow.com/a/35369267/5475941。在这篇文章中,我解释了如何在 Android Studio 中导入您的 JAR 文件,并通过屏幕截图逐步解释了所有可能的方法。希望对你有帮助。

    【讨论】:

    • 谢谢。该项目的设置类似于选项#2。选项 #1 并获得了更接近的结果,但它的手册。我认为问题出在新的构建系统和实验插件上。我没有尝试过选项#3。将库放入存档/存储库并从那里拉出可能可行,但我想尝试使本地构建工作。
    • 不客气,伙计,Android Studio 是基于 Maven 的。在 Maven 中,大多数库将像方法 3 一样添加。高级程序员搜索 search.maven.org 查找他们的库,然后将它们与 groupid、Artifactid 和版本一起添加到他们的项目中。尝试在那里找到你的图书馆。
    • 这个库是产品专有的,所以......你知道......我会在接下来的几天里尝试我们的内部存储库......我现在不得不把这个库放在同一个模块中并完成工作。几天后我会回去分离模块,让你知道它是怎么回事。对于 IDE 看不到其他模块的面包屑和我们懒惰的开发人员坚持的其他东西的问题,它仍然无济于事。我必须在检查东西之前解决这个问题,否则商店会抬起头来。我希望有实验插件经验的人可以提供帮助。
    猜你喜欢
    • 2015-10-22
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 2017-11-12
    • 2016-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多