簡體   English   中英

Android Studio,生成 Ormlite 配置文件(ormlite.txt),gradle 抱怨“JavaExec.main 屬性已被棄用。”

[英]Android Studio, generate Ormlite Configuration File (ormlite.txt), gradle complains "The JavaExec.main property has been deprecated."

Ormlite是一個對 sqlite 進行面向對象訪問的庫。 它要求我們生成一個ormlite.txt文件,其中包含我的 android 項目中數據庫對象的處理配置。

除了將實際啟動 Android 應用程序的 Android 運行配置之外,我還創建了一個應用程序運行配置來僅執行 main() 方法。 這就是我5年來一直這樣做的方式。 但是,更新 gradle 后,我收到以下錯誤:

> Configure project :app
The JavaExec.main property has been deprecated. This is scheduled to be removed in Gradle 8.0. 
Please use the mainClass property instead. See 
https://docs.gradle.org/7.3.3/dsl/org.gradle.api.tasks.JavaExec.html#org.gradle.api.tasks.JavaExec:main 
for more details.

既然 gradle 7 不會讓我像以前那樣運行我的 main() 方法,我應該使用什么代碼來讓我運行它,我應該把那個代碼放在哪里?

我不知道 gradle 的實際工作原理,我只是按照說明將片段復制/粘貼到我的 build.gradle 中,當我包含諸如 crashlytics 之類的東西時,我被告知要這樣做。 因此,當我 go 查看它建議的文檔時,我不知道應該將它告訴我添加的代碼放在哪里。 我已經用一百萬個 Android Studios 嘗試了一百萬只猴子來嘗試猜測正確的位置,但我無法讓它工作。

我以前不需要添加任何 build.gradle 代碼,它只會運行 Android Studio 運行配置,它引用了我的app:類路徑的模塊。

它以前的工作方式......在 Android Studio 中,我只需要使用 main() 方法創建一個簡單的 class ,該方法將調用正確的 ormlite function 來生成文件:

public class DatabaseConfigUtil extends OrmLiteConfigUtil {

    public static void main(String[] args) throws SQLException, IOException {
        writeConfigFile("ormlite_config.txt"); // NON-NLS
    }
}

然后在“應用程序”類型的 Android Studio 中創建運行配置並選擇 class。 然后,當我運行該配置時,它會將我項目中的所有類添加到類路徑中,然后運行 ​​main() 方法。 該代碼可以讀取類路徑中的所有類並生成ormlite.txt文件。

Android Studio 運行配置截圖

既然 gradle 7 不會讓我像以前那樣運行我的 main() 方法,我應該使用什么代碼來讓我運行它,我應該把那個代碼放在哪里?

這是我的應用程序模塊 build.gradle 文件:

buildscript {
    repositories {
        mavenCentral()
        // jcenter()
        maven {
            url 'https://maven.google.com/'
            name 'Google'
        }
        google()
    }
}

repositories {
    mavenCentral()
    mavenLocal()
    maven {
        url 'https://maven.google.com/'
        name 'Google'
    }
}

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'

dependencies {
    // a bunch of stuff

}


android {
    // API 31 = Android 12.0 Snow Cone
    compileSdkVersion 31

    defaultConfig {
        applicationId "com.mydomain.myapp"
        minSdkVersion 19
        targetSdkVersion 31

        versionCode 459

        versionName "3.9"

        // Enabling multidex support.
        multiDexEnabled true

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

        vectorDrawables.useSupportLibrary = true

        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [
                        "androidManifestFile": "$projectDir/src/main/AndroidManifest.xml".toString()
                ]
            }
        }

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    buildFeatures {
        viewBinding true
    }


}

我花了最后一天學習關於 gradle 的在線課程,以便嘗試了解這里出了什么問題。 畢竟,我確信這實際上是 Android Studio 中的一個錯誤。 當我在 Android Studio 中配置“運行配置”時,真正發生的是它正在后台創建一個 gradle 腳本,該腳本將為我創建的運行配置實現 gradle 任務。

並且生成的 gradle 腳本是錯誤的。 它正在使用已棄用的屬性,因此 gradle 構建失敗。

它正在創建 JavaExec 類型的JavaExec任務,並將main屬性設置為包含我的 main() 方法的 class 名稱,但main屬性已重命名為mainClass ,因此生成的代碼不正確,因此失敗。

我還沒有找到解決方法,但我會嘗試看看我是否可以自己創建一個 gradle 任務並手動運行它。


更新:我終於找到了一種解決方法,並且能夠生成我的 ormlite 配置文件。 系上。

我的問題的核心是,當我運行 main() 方法時,我的類路徑中需要所有基於 android 的類。 Normally, if you have a java gradle project, that is trivial because the standard output of a java gradle project is a jar (or some classes). 但是,android 項目的 output 是一個不包含您的類的apk ,它包含.dex文件。

我無法找到一種方法來構建 android 項目並跳過 dexing 步驟(即構建所有需要的類而不將它們粉碎成.dex文件。

但我確實找到了一種方法來取消dex 文件: https://github.com/pxb1988/dex2jar

我下載了 dex2jar 代碼並按照安裝說明為 dex2jar 工具構建了所有各種代碼和腳本。 我喜歡生成的dex-tools目錄到我的用戶主目錄,這樣我就可以在一個中心位置使用它。 這給了我一個名為d2j-dex2jar.sh的腳本,它將一個.dex文件轉換回一個.jar文件,其中充滿了.class文件,這正是我所需要的。

然后我將以下內容添加到我的app/build.gradle文件中:

def userhome = System.properties['user.home']
def dex2jaroutputdir = "$buildDir/intermediates/fulljar"


task convertdextojars {
    dependsOn('bundleDebug')

    doLast {

        def dexdir = "$buildDir/intermediates/dex/debug/mergeDexDebug"
        def dex2jar = "$userhome/dex-tools/d2j-dex2jar.sh"

        mkdir(dex2jaroutputdir)

        fileTree(include: ['*.dex'], dir: dexdir).each {
            def filename = it

            exec {
                workingDir dex2jaroutputdir
                commandLine dex2jar, '--force', "$filename"
            }
        }
    }

}

此任務取決於 android 任務bundleDebug ,它將構建app-debug.apk我並不真的需要使用apk本身,因為用於構建 apk 的中間文件是可用的,所以我可以使用它們。 將添加到 apk 的.dex文件存儲在$buildDir/intermediates/dex/debug/mergeDexDebug中。 我有classes.dexclasses2.dexclasses3.dex ,但你的里程可能會有所不同。

上面的convertdextojars任務將創建一個 output 目錄來保存我的 jars,然后使用fileTree()來獲取dexdir中與*.dex匹配的所有文件名的集合。 然后對於這些文件中的每一個,它將執行 shell 命令來對文件進行 de-dex。 我將 exec 工作目錄設置為我的dex2jaroutputdir ,因為d2j-dex2jar.sh腳本會將 output jar 生成到當前工作目錄。 我將--force標志添加到命令行,以便它將覆蓋 jars(如果它們已經存在)。

這會給我一套 jars,其中幾乎包含我需要的所有代碼。 它將包括我所有的 android 代碼,我的所有依賴項的代碼,但它不包括 android.os.* 運行時類。

接下來,我將此代碼添加到我的app/build.gradle文件中:

task gendbconfig(type: JavaExec) {
    dependsOn('convertdextojars')

    doFirst {
        println "++++++++++++++++++++++++++++++++++++++++"
        fileTree(include: ['*.jar'], dir: dex2jaroutputdir).each {
            println "jar: $it"
        }

    }

    mainClass = 'com.kenny.stuff.DatabaseConfigUtil'
    classpath = fileTree(include: ['*.jar'], dir: dex2jaroutputdir)
    classpath = classpath.plus(files(android.getBootClasspath()[0]))
    workingDir = "$projectDir/src/main"

}

doFirst()閉包不是必需的,但它有助於確保我傳入的 jar 文件符合我的預期。

mainClass是包含我的main()方法的 class 。

第一個classpath行構建了我們剛剛生成的那些 jars 的集合,這讓我幾乎得到了我需要的東西,但是它缺少 android 運行時類本身。 這就是第二條classpath行的作用。 android.getBootClasspath()[0]在我的系統上解析為/Users/kenny/Library/Android/sdk/platforms/android-31/android.jar

作為旁注,我嘗試使用符號classpath +=而不是classpath = classpath.plus()但 gradle 構建失敗,因為一些 object 類型問題。

我將workingDir設置為$projectDir/src/main (這意味着app/src/main ,因為生成配置文件的 ormlite 代碼將嘗試自動將配置文件寫入您的res/raw/目錄,如果它可以找到作為工作目錄的子目錄。

最后,我在 Android Studio 中打開了終端 window,它自動將我放入頂部項目文件夾(比app模塊/項目高的一個文件夾。我運行了命令./gradlew app:gendbconfig ,它告訴 Z8ED1A771BC236C287AD93Cgen 中的gendbconfig app模塊。

瞧。

將配置寫入 /path/to/my/android/project/app/src/main/./res/raw/ormlite_config.txt

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM