2022-01-20 Android studio新建項目模板

背景

在使用AS創(chuàng)建新項目時跨跨,創(chuàng)建的項目中會生成很多預(yù)定的代碼,比如gradle囱皿、AndroidManifest.xml勇婴、.gitignore文件等。不同版本AS創(chuàng)建時生成的文件內(nèi)容都不同嘱腥,但是并不是所有的內(nèi)容都是我們想要的咆耿,比如gradle版本,這個尤其明顯爹橱。還有就是有些我們根據(jù)自己的編碼習(xí)慣會加一些東西進去,每次新建一個項目都要加很多東西窄做,是比較麻煩的愧驱,所以我們可以修改這些生成文件的模板,讓每次新建項目時創(chuàng)建的文件內(nèi)容是我們想要的椭盏。

以前筆者使用的是AS3.5组砚,這段時間因為換了個電腦下載了AS2020.3(白狐)版。白狐版過后默認(rèn)使用的是Java11掏颊,可是筆者一直使用的是Java8糟红,并且不想因為AS換成Java11,經(jīng)過一番折騰過后Java環(huán)境使用了主機中的Java8乌叶。但是在gradle文件中配置的gradle和gradle插件版本是7.0.4盆偿,這個gradle版本是很高的,筆者之前使用的是gradle5.4.1准浴,插件版本是3.5.2事扭。筆者也想嘗試使用一下7.0.4,但是沒那么簡單乐横,很多語法都不兼容求橄。筆者也沒有時間去研究gradle的變更。準(zhǔn)備修改AS白狐中的文件模板葡公,就是在AS白狐中使用原來的gradle不行嗎罐农?在準(zhǔn)備修改模板文件時發(fā)現(xiàn)AS這個變更非常大。特意在這里記錄下催什。

注意:筆者這里記錄的是AS新建項目時生成文件的模板涵亏,不是在使用AS時創(chuàng)建一個activity或者一個fragment時新建activity中內(nèi)容的模板。

AS3.5及以下

下圖中可以看出筆者安裝的是AS3.5.2,以及AS安裝目錄下的文件

2022-01-20_090637.png

進入AS安裝目錄/plugins/android/lib/templates/gradle-projects

2022-01-20_090955.png

這里面有AS中所有新建(項目溯乒、module等)內(nèi)容的模板夹厌,筆者確定要修改的是項目目錄下的gradle文件、app目錄下的gradle文件裆悄,所以找到NewAndroidProject和NewAndroidModule文件夾矛纹。

2022-01-20_091314.png

NewAndroidProject是新建項目中的配置文件,進入這個文件夾下的root文件夾光稼,有幾個ftl文件或南,就是模板文件了,根據(jù)命名可以看出有g(shù)radle艾君、ignore等文件采够。筆者在這里準(zhǔn)備修改gradle和ignore的模板,其他的你可以根據(jù)自己項目需要或者編碼習(xí)慣自己進行修改冰垄。在修改之前可以先拷貝一份蹬癌,以免有錯誤時可以恢復(fù)。

2022-01-20_091712.png

這里貼一下ignore文件修改前后的對比虹茶,左邊是默認(rèn)內(nèi)容逝薪,我們?nèi)绻蛔鲂薷牡脑捫陆椖亢蟮膬?nèi)容就是這樣,但是通常情況下我們都會修改蝴罪,這里直接修改模板文件董济,然后新建一個項目看看是否成功。

2022-01-20_091907.png

在上圖中可以看出新建項目的模板修改已經(jīng)成功要门,因此可以去修改更重要文件了虏肾。

在這里修改build.gradle文件

// Top-level build file where you can add configuration options common to all sub-projects/modules.
<#macro loadProperties>
<#if useOfflineRepo!false>
    Properties properties = new Properties()
    properties.load(project.rootProject.file("local.properties").newDataInputStream())
</#if>
</#macro>
<#macro useProperties>
<#if useOfflineRepo!false>
        properties.getProperty("offline.repo").split(",").each { repo ->
            maven { url repo }
        }
</#if>
</#macro>

buildscript {<#if includeKotlinSupport!false>
    ext.kotlin_version = '${kotlinVersion}'</#if>
    <@loadProperties/>
    repositories {
        <@useProperties/>
        google()
        jcenter()
        <#if includeKotlinEapRepo!false>maven { url '${kotlinEapRepoUrl}' }</#if>
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:${gradlePluginVersion}'
        <#if includeKotlinSupport!false>classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"</#if>
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

def releaseTime() {
    return new Date().format("yyyy-MM-dd",java.util.TimeZone.getTimeZone("UTC"))
}

allprojects {
    <@loadProperties/>
    repositories {
        <@useProperties/>
        google()
        jcenter()

        maven { 
            url 'https://jitpack.io' 
        }
        <#if includeKotlinEapRepo!false>maven { url '${kotlinEapRepoUrl}' }</#if>
    }

    ext {
        compileSdkVersion = 30
        buildToolsVersion = "30.0.3"
        minSdkVersion = 19
        targetSdkVersion = 30
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

這個文件主要修改gradle插件版本、倉庫地址欢搜、還有一些自定義的配置封豪,筆者添加了編譯SDK的一些版本信息。在app的gradle文件中可以引用炒瘟。

app目錄中的模板文件主要想修改gradle文件和AndroidManifest.xml文件撑毛,進入NewAndroidModule婿牍,這個文件夾是新建Android module的模板文件毙驯。

2022-01-20_095402.png

gradle文件中要修改的有編譯版本信息引用項目目錄下的配置回右,添加一下編譯常用的配置供璧,打包信息妇穴,常用依賴庫的引用等熏迹。

<#import "./shared_macros.ftl" as shared>
<#import "root://activities/common/kotlin_macros.ftl" as kt>
<#if isInstantApp>
apply plugin: 'com.android.feature'
<#else>
  <#if isLibraryProject>
apply plugin: 'com.android.library'
  <#elseif isDynamicFeature>
apply plugin: 'com.android.dynamic-feature'
  <#else>
apply plugin: 'com.android.application'
  </#if>
</#if>
<@kt.addKotlinPlugins />

<@shared.androidConfig hasApplicationId=isApplicationProject applicationId=packageName isBaseFeature=isBaseFeature hasTests=true canHaveCpp=true canUseProguard=isApplicationProject||isBaseFeature||(isLibraryProject&&!isInstantApp)/>
dependencies {
    ${getConfigurationName("compile")} fileTree(dir: 'libs', include: ['*.jar'])
    <#if !improvedTestDeps>
    ${getConfigurationName("androidTestCompile")}('com.android.support.test.espresso:espresso-core:+', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    </#if>
    <@kt.addKotlinDependencies />
<#if isInstantApp||isDynamicFeature>
  <#if isBaseFeature>
    <#if monolithicModuleName?has_content>
    application project(':${monolithicModuleName}')
    <#else>
    // TODO: Add dependency to the main application.
    // application project(':app')
    </#if>
  <#else>
    implementation project(':${baseFeatureName}')
  </#if>
<#else>
  <@shared.watchProjectDependencies/>
  
    //自定義Android開發(fā)庫
    api 'com.gitee.premeditate:VenusAndroid:V1.0.22'
</#if>
}

在這里可以看到能加的只有dependencies的內(nèi)容船响,其他內(nèi)容是引用androidConfig文件的膜宋,也就是說這里的模板配置包含另一個文件內(nèi)容受啥。

找到該目錄下的shared_macros.ftl文件

<#import "root://gradle-projects/common/proguard_macros.ftl" as proguard>

<#-- Some common elements used in multiple files -->
<#macro watchProjectDependencies>
<#if WearprojectName?has_content && NumberOfEnabledFormFactors?has_content && NumberOfEnabledFormFactors gt 1 && Wearincluded>
    wearApp project(':${WearprojectName}')
    ${getConfigurationName("compile")} 'com.google.android.gms:play-services-wearable:+'
</#if>
</#macro>

<#macro generateManifest packageName hasApplicationBlock=false>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        <#if isDynamicInstantApp>
            xmlns:dist="http://schemas.android.com/apk/distribution"
        </#if>
        package="${packageName}"<#if !hasApplicationBlock>/</#if>><#if hasApplicationBlock>

        <#if isDynamicInstantApp>
        <dist:module
            dist:instant="true" />
        </#if>
    <application <#if minApiLevel gte 4 && buildApi gte 4>android:allowBackup="true"</#if>
        android:usesCleartextTraffic="true"
        android:label="@string/app_name"<#if copyIcons>
        android:icon="@mipmap/ic_launcher"<#if buildApi gte 25 && targetApi gte 25>
        android:roundIcon="@mipmap/ic_launcher_round"</#if><#elseif assetName??>
        android:icon="@drawable/${assetName}"</#if><#if buildApi gte 17>
        android:supportsRtl="true"</#if>
        android:theme="@style/AppTheme"/>
</manifest></#if>
</#macro>

<#macro androidConfig hasApplicationId=false applicationId='' hasTests=false canHaveCpp=false isBaseFeature=false canUseProguard=false>
android {
    compileSdkVersion parent.ext.compileSdkVersion
    <#if explicitBuildToolsVersion!false>buildToolsVersion parent.ext.buildToolsVersion</#if>

    <#if isBaseFeature>
    baseFeature true
    </#if>

    defaultConfig {
    <#if hasApplicationId>
        applicationId "${applicationId}"
    </#if>
        minSdkVersion parent.ext.minSdkVersion
        targetSdkVersion parent.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"

    <#if hasTests>
        testInstrumentationRunner "${getMaterialComponentName('android.support.test.runner.AndroidJUnitRunner', useAndroidX)}"
    </#if>
    <#if canUseProguard && (isLibraryProject!false)>
        consumerProguardFiles 'consumer-rules.pro'
    </#if>
    <#if canHaveCpp && (includeCppSupport!false)>

        externalNativeBuild {
            cmake {
                cppFlags "${cppFlags}"
            }
        }
    </#if>
        multiDexEnabled true
        
        //使用時可以打開這個注釋
        /*
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath = true
            }
        }
        */
    }
<#if javaVersion?? && (javaVersion != "1.6" && buildApi lt 21 || javaVersion != "1.7")>

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_${javaVersion?replace('.','_','i')}
        targetCompatibility JavaVersion.VERSION_${javaVersion?replace('.','_','i')}
    }
</#if>
<#if canUseProguard>
<@proguard.proguardConfig />
</#if>

    //編寫模板文件時,這些內(nèi)容添加進去創(chuàng)建項目時就會出錯,所以以注釋的形式寫在這里,創(chuàng)建項目后需要使用時可以打開注釋
    /*
    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }

    flavorDimensions 'build'

    productFlavors {
        huafeng {}
    }

    //APK文件名稱:outputFileName = "Android開發(fā)庫-美元符號{releaseTime()}-美元符號{variant.versionName}.apk"
    android.applicationVariants.all {
        android.applicationVariants.all {
            variant ->
                variant.outputs.all {
                    outputFileName = "請參照上面注釋修改發(fā)布APK文件的名稱,使用{美元符號}替換美元符號幾個文字.apk"
                }
        }
    }
    */
<#if canHaveCpp && (includeCppSupport!false)>
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }
</#if>
}
</#macro>

這個文件包含了Android編譯模塊的配置做个,可以添加一些關(guān)于編譯的信息鸽心。同時AndroidManifest.xml文件中的一些節(jié)點也包含在這里,所以在這個文件中可以同時修改居暖,筆者添加了android:usesCleartextTraffic="true"配置顽频,這個配置是聲明應(yīng)用允許使用http協(xié)議,因為Android11過后應(yīng)用程序默認(rèn)使用https太闺,所以需要加上這個配置糯景,筆者覺得是必須的,所以直接添加在了模板文件里面省骂。

注意:在這里配置一些關(guān)于編譯的內(nèi)容時蟀淮,有的還是不能識別,如果加的內(nèi)容不能識別钞澳,在新建項目時gradle文件的內(nèi)容會不全怠惶,新建的項目有錯誤,這不是我們所想的轧粟。但是也不知道為啥有的東西不能加策治,所以筆者把有錯誤的地方用注釋包起來,這樣在生成時兰吟,這一部分就會像注釋一樣加進去通惫,在新建項目這些內(nèi)容生成后成了注釋,我們可以打開這個注釋就能使用了揽祥。

AS2020.3及以上

在AS白狐中安裝目錄下沒有templates文件夾。修改模板的方式大變樣檩电,好像是模板文件被打包成了jar文件拄丰,筆者目前還沒有研究出來怎么修改,后面有時間了再補充~俐末!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末料按,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子卓箫,更是在濱河造成了極大的恐慌载矿,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件烹卒,死亡現(xiàn)場離奇詭異闷盔,居然都是意外死亡,警方通過查閱死者的電腦和手機旅急,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門逢勾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人藐吮,你說我怎么就攤上這事溺拱√颖矗” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵迫摔,是天一觀的道長沐扳。 經(jīng)常有香客問我,道長句占,這世上最難降的妖魔是什么沪摄? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮辖众,結(jié)果婚禮上卓起,老公的妹妹穿的比我還像新娘。我一直安慰自己凹炸,他們只是感情好戏阅,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著啤它,像睡著了一般奕筐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上变骡,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天离赫,我揣著相機與錄音,去河邊找鬼塌碌。 笑死渊胸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的台妆。 我是一名探鬼主播翎猛,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼接剩!你這毒婦竟也來了切厘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤懊缺,失蹤者是張志新(化名)和其女友劉穎疫稿,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鹃两,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡遗座,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了俊扳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片员萍。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拣度,靈堂內(nèi)的尸體忽然破棺而出碎绎,到底是詐尸還是另有隱情螃壤,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布筋帖,位于F島的核電站奸晴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏日麸。R本人自食惡果不足惜寄啼,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望代箭。 院中可真熱鬧墩划,春花似錦、人聲如沸嗡综。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽极景。三九已至察净,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盼樟,已是汗流浹背氢卡。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留晨缴,地道東北人译秦。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像击碗,于是被迫代替她去往敵國和親筑悴。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容