AndroidManifest 是什么命浴,對(duì)不起娄猫,我不需要 ^-^

前言

在寫(xiě) Android 應(yīng)用時(shí),當(dāng)你新建一個(gè) Activity生闲,Service媳溺,ContentProviderBroadcast(著名的四大組件)時(shí)跪腹,你是不是經(jīng)常性的寫(xiě)完就直接運(yùn)行褂删,然后程序就崩潰了,通過(guò)查看日志冲茸,你才發(fā)覺(jué)原來(lái)忘記在 AndroidManifest.xml 中進(jìn)行注冊(cè)屯阀。甚至于缅帘,當(dāng)我們代碼運(yùn)行需要某些權(quán)限時(shí),你也要跳轉(zhuǎn)到 AndroidManifest.xml 中進(jìn)行權(quán)限聲明难衰,然后代碼才能正確運(yùn)行钦无,而這些操作,我們往往都會(huì)忘記盖袭。

筆者個(gè)人認(rèn)為失暂,導(dǎo)致我們經(jīng)常性忘記在 AndroidManifest.xml 中進(jìn)行注冊(cè)的一個(gè)主要的原因就在于編寫(xiě)代碼和進(jìn)行注冊(cè)是發(fā)生在兩個(gè)文件中的,也就是我們需要進(jìn)行文件切換鳄虱,這種切換操作對(duì)于我們正在編寫(xiě)程序的思路起到了切斷作用弟塞,所以我們往往在專(zhuān)注于寫(xiě)代碼的時(shí)候,就會(huì)忘記進(jìn)行組件注冊(cè)拙已。

基于以上原因决记,筆者開(kāi)發(fā)了一套開(kāi)源框架:InjectManifest,這套框架致力于解決上面我們提到的編寫(xiě)代碼和進(jìn)行組件注冊(cè)需要進(jìn)行文件切換的不便倍踪,框架提供注解進(jìn)行注冊(cè)系宫,讓我們?cè)诰帉?xiě)相關(guān)需要進(jìn)行注冊(cè)的代碼的同時(shí),可以很方便地直接使用注解進(jìn)行相關(guān)內(nèi)容的注冊(cè)建车,再也無(wú)需切換到 AndroidManifest.xml 去做這些事扩借。

優(yōu)點(diǎn)

  • 采用編譯期注解與自定義 Gradle 插件完成注冊(cè)過(guò)程,對(duì)程序運(yùn)行無(wú)任何影響缤至;
  • 支持注解和原生 AndroidManifest.xml 協(xié)同工作潮罪,最終會(huì)將兩者結(jié)合起來(lái),保留不一致的元素凄杯,相同的元素只保留一份错洁;
  • 對(duì)支持的標(biāo)簽的所有屬性配置均支持;

缺點(diǎn)

  • 在每次使用注解注冊(cè)后戒突,需要 rebuild 一下才能生成新的 AndroidManifest.xml文件,如果采用注解注冊(cè)后描睦,直接運(yùn)行程序膊存,可以看到新的 AndroidManifest.xml 也生成了,但是程序此時(shí)使用的是舊的(也就是原生的)AndroidManifest.xml配置忱叭。這個(gè)地方的原因我猜測(cè)應(yīng)該是 processDebugManifest/processReleaseManifest 運(yùn)行在 新的 AndroidManifest.xml 生成前隔崎,所以這個(gè)問(wèn)題我猜測(cè)是不是可以有什么辦法把processDebugManifest/processReleaseManifest 放到文件生成后再執(zhí)行····這個(gè)地方我暫時(shí)也沒(méi)找出什么辦法進(jìn)行解決,如果有誰(shuí)知道怎么解決這個(gè)問(wèn)題的韵丑,麻煩跟我講下爵卒,謝謝。
  • 目前只支持 manifest,application,activity,service,receiver,provider,uses-permission 標(biāo)簽的解析撵彻,對(duì)于其他標(biāo)簽钓株,無(wú)法進(jìn)行融合实牡,在新生成的 AndroidManifest.xml 中這些元素不會(huì)被保留;

示例

  1. manifest 標(biāo)簽注冊(cè)
@InjectManifest(
        pkName = "com.yn.injectmanifest",
        installLocation = INTERNAL_ONLY,
        sharedUserId = "android.uid.system"
)

public class App extends Application {
}

rebuild 一下轴合,你就可以看到 AndroidManifest.xml 變成這樣:

@InjectManifest

manifest 標(biāo)簽的其他屬性 @InjectManifest 均支持创坞。

  1. application 標(biāo)簽注冊(cè)
@InjectApp(
        name = ".App", //you can full class name or just simply using a .classSimpleName
        label = "i am app",
        debuggable = TRUE,
        metaData = @InjectMetaData(name = "app/meta-data")
)
public class App extends Application {
}

rebuild 一下,你就可以看到 AndroidManifest.xml 變成這樣:

@InjectApp

application 標(biāo)簽的其他屬性 @InjectApp 均支持受葛。

  1. activity 標(biāo)簽注冊(cè)
@InjectActivity(
        name = ".MainActivity",
        intentFilter = @InjectIntentFilter(
                action = {"android.intent.action.MAIN", "android.intent.action_whyn_test"},
                category = {"android.intent.category.LAUNCHER", "android.intent.category.whyn"},
                data = @InjectData(mimeType = "image/*")
        ))
public class MainActivity extends AppCompatActivity {}

rebuild 一下题涨,你就可以看到 AndroidManifest.xml 變成這樣:

@InjectActivity

activity 標(biāo)簽的其他屬性 @InjectActivity 均支持。

  1. service 標(biāo)簽注冊(cè)
@InjectService(
        enabled = TRUE,
        name = ".FirstService",
        label = "Inject Service test",
        intentFilter = @InjectIntentFilter(
                action = "com.yn.action.FirstService",
                category = "com.yn.category.serviceTest",
                data = @InjectData(
                        host = "sdcard",
                        mimeType = "video/mp4",
                        path = "/sdcard/1.MP4",
                        pathPattern = ".*\\.mp4",
                        pathPrefix = "/sdcard/",
                        port = "-2",
                        scheme = "file"
                )
        ),
        metaData = @InjectMetaData(name = "com.yn.meta-data.service")
)
public class FirstService extends Service {···}

rebuild 一下总滩,你就可以看到 AndroidManifest.xml 變成這樣:

@InjectService

service 標(biāo)簽的其他屬性 @InjectService 均支持纲堵。

  1. receiver 標(biāo)簽注冊(cè)
@InjectReceiver(
        name = ".FirstReceiver",
        label = "hi i am first receiver",
        process = ".remote",
        enabled = TRUE
)
public class FirstReceiver extends BroadcastReceiver {···}

rebuild 一下,你就可以看到 AndroidManifest.xml 變成這樣:

@InjectReceiver

receiver 標(biāo)簽的其他屬性 @InjectReceiver 均支持闰渔。

  1. provider 標(biāo)簽注冊(cè)
@InjectProvider(
        authorities = "com.yn.authorities",
        name = ".FirstProvider",
        label = "I am ContentProvider"
)
public class FirstProvider extends android.content.ContentProvider {···}
@InjectProvider

provider 標(biāo)簽的其他屬性 @InjectProvider 均支持婉支。

  1. uses-permission 標(biāo)簽注冊(cè)
    @InjectUsesPermission({
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.BLUETOOTH,
            Manifest.permission.ACCESS_WIFI_STATE,
    })
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

rebuild 一下,你就可以看到 AndroidManifest.xml 變成這樣:

@InjectUsesPermission

uses-permission 標(biāo)簽的其他屬性 @InjectUsesPermission 均支持澜建。

目前暫時(shí)就只支持以上所講的標(biāo)簽向挖,后續(xù)我有時(shí)間就會(huì)不定時(shí)更新下。

下載

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.whyn:injectmanifest-plugin:1.1.0'
    }
}

然后炕舵,apply 到你的 module

apply plugin: 'com.android.application'
apply plugin: 'com.whyn.plugin.injectmanifest'

注意事項(xiàng):

  • InjectManifest 默認(rèn)會(huì)將生成的 AndroidManifest.xml 替換掉原來(lái)的 AndroidManifest.xml何之,但在替換前,會(huì)將原來(lái)的 AndroidManifest.xml 保存為 AndroidManifest_old.xml咽筋,所以溶推,對(duì)于暫時(shí)未支持的 xml 標(biāo)簽,新生成的文件無(wú)法保留奸攻,那么你就可以從 AndroidManifest_old.xml 中找回蒜危。
    如果想更換上面的默認(rèn)行為,那就需要在 modulebuild.gradle 中增加下面的擴(kuò)展屬性:
manifestConfig {
    //the defautl AndroidManifest.xml path
    originManifestPath android.sourceSets.main.manifest.srcFile.absolutePath

    //the AndroidManifest.xml path generated by annotation processor
    genManifestPath "$project.buildDir/generated/source/apt/debug/Collections.xml"
    
    //to save the original AndroidManifest: true -- save,false -- not save
    saveOrigin false
}
  • 如果你在開(kāi)發(fā)過(guò)程中睹耐,要為注解處理器傳遞參數(shù)辐赞,請(qǐng)記住加上 + 號(hào),代表追加硝训,否則响委,會(huì)導(dǎo)致 gradle 插件里面默認(rèn)設(shè)置的注解參數(shù)失效,這樣就不會(huì)合并原生 AndroidManifest.xml 了窖梁。
android {
    defaultConfig{
    ···
    ···
        javaCompileOptions {
            annotationProcessorOptions {
                arguments += [xxxxx: 'yyyyy'] 
            }
        }
    }
}
  • 如果你對(duì) AndroidManifest.xml 的默認(rèn)路徑進(jìn)行了修改赘风,如果你還希望能合并 AndroidManifest.xml,那你需要手動(dòng)傳遞最新路徑給 annotation processor
android {
    defaultConfig{
    ···
    ···
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AndroidManifestPath: android.sourceSets.main.manifest.srcFile.absolutePath] 
            }
        }
    }
}

附錄

源碼傳送門(mén):InjectManifest
AndroidManifest.xml 應(yīng)用清單官方文檔: here

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末纵刘,一起剝皮案震驚了整個(gè)濱河市邀窃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌假哎,老刑警劉巖瞬捕,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鞍历,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡山析,警方通過(guò)查閱死者的電腦和手機(jī)堰燎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)笋轨,“玉大人秆剪,你說(shuō)我怎么就攤上這事【粽” “怎么了仅讽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)钾挟。 經(jīng)常有香客問(wèn)我洁灵,道長(zhǎng),這世上最難降的妖魔是什么掺出? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任徽千,我火速辦了婚禮,結(jié)果婚禮上汤锨,老公的妹妹穿的比我還像新娘双抽。我一直安慰自己,他們只是感情好闲礼,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布牍汹。 她就那樣靜靜地躺著,像睡著了一般柬泽。 火紅的嫁衣襯著肌膚如雪慎菲。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天锨并,我揣著相機(jī)與錄音露该,去河邊找鬼。 笑死琳疏,一個(gè)胖子當(dāng)著我的面吹牛有决,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播空盼,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼新荤!你這毒婦竟也來(lái)了揽趾?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤苛骨,失蹤者是張志新(化名)和其女友劉穎篱瞎,沒(méi)想到半個(gè)月后苟呐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俐筋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年牵素,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片澄者。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笆呆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出粱挡,到底是詐尸還是另有隱情赠幕,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布询筏,位于F島的核電站榕堰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏嫌套。R本人自食惡果不足惜逆屡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望踱讨。 院中可真熱鬧魏蔗,春花似錦、人聲如沸勇蝙。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)味混。三九已至产雹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間翁锡,已是汗流浹背蔓挖。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留馆衔,地道東北人瘟判。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像角溃,于是被迫代替她去往敵國(guó)和親拷获。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理减细,服務(wù)發(fā)現(xiàn)匆瓜,斷路器,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,506評(píng)論 25 707
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,748評(píng)論 6 342
  • 如有雷同,不是巧合驮吱。 大環(huán)境仍然是穩(wěn)定茧妒,國(guó)家政策是穩(wěn)健的貨幣政策和積極的財(cái)政政策,說(shuō)白了就是不放水左冬,搞...
    十二月的陽(yáng)光閱讀 169評(píng)論 0 0
  • 已經(jīng)過(guò)去十天了拇砰,距離蘇荷在網(wǎng)上發(fā)布籌款開(kāi)始梅忌。這期間,她每天都抱著那部有些破舊的手機(jī)查看銀行卡余額毕匀,然后將籌款一筆一...
    茶丁故事閱讀 922評(píng)論 6 23