Android新建系统,实验插件,JNI库模块

时间:2016-02-18 21:19:58

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

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

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

Android Studio: 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

的myproject / settings.gradle:

include ':appmodule', ':libmodule'

的myproject /的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提供了一个快速修复程序,用于包含Module“libmodule”的依赖项,如果我选择它,则IDE会删除错误。然后,如果我按命令单击包,类或方法,IDE将正确解析项目链接。

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

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

我对新实验插件的知识存在差距,我知道它有错误,它不完整,有些功能仍在讨论中。任何有助于追踪我的错误,或提供有关插件缺乏功能的全面工作的帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

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