Android清單文件詳解(五)----<application>的屬性詳解
前面第三篇,第四篇博文雖然講解了application節(jié)點的幾個屬性,但是還不夠完全,本著對專業(yè)執(zhí)著的精神,有必要深挖下去。
1.android:allowBackup
它表示是否允許應用程序參與備份。如果將該屬性設置為false,則即使備份整個系統(tǒng),也不會執(zhí)行這個應用程序的備份操作,而整個系統(tǒng)備份能導致所有應用程序數據通過ADB來保存。該屬性必須是一個布爾值,或為true,或為false,其默認值為true。
現在,我們就對前面的HelloWorld實例進行修改。在工程的AndroidManifest.xml文件中添加allowBackup屬性,并將其設置為false。該屬性屬于
編譯并安裝應用程序,完成后運行應用程序。
單擊“myBackup”按鈕,并執(zhí)行adb shell bmgr run命令來執(zhí)行一次備份操作,這樣操作后看到的日志如下所示:
如上圖所示,我們沒有看到任何執(zhí)行應用程序備份的日志輸出,這說明android:allowBackup限制了備份的執(zhí)行。
2.allowTaskReparenting
android:allowTaskReparenting是任務調整屬性,它表明這個任務重新被送到前臺的時候,該應用程序所定義的Activity是否可以從被啟動的任務中轉移到有相同親和力的任務中。
這個屬性的數據類型是布爾型,它的取值只有true和false兩種。它不是必須指定的屬性,如果我們沒有顯示指定這個屬性,那么它將被指定為默認值false。
3.android:killAfterRestore
這個屬性是指在一個完整的系統(tǒng)恢復操作之后應用程序是否被終止。單個應用程序的恢復操作不會引起應用程序的終止。完整的系統(tǒng)恢復操作一般僅在手機首次安裝時才會發(fā)生一次。第三方應用通常都不需要使用該屬性。
該屬性的默認值為true,意為在完整的系統(tǒng)恢復期間,應用程序在結束處理其數據之后將被終止。
4.android:restoreAnyVersion
它指是否允許恢復任意版本的備份數據來恢復應用程序的數據,即使備份明顯來自于當前安裝在設備上的應用程序的更新版本。將該屬性設置為true,則將允許備份管理器嘗試恢復操作,有的時候版本不匹配表明數據是不兼容的,這個時候如果可以恢復到不同版本的數據,那么應用程序將承受很大的風險,所以請謹慎使用此屬性
它必須是布爾值,或為true,或為false,默認值為false。
5.android:debuggable
這是一個布爾型標志,它的取值是true或false,這個標志指示應用程序在用戶模式的設備上是否可以調試。如果為true,則表示應用程序可以被調試;如果為false,則表示應用程序不可以被調試。它的默認值是false。使用這個標志唯一需要注意的是,它只在用戶模式的機器上生效,用戶模式既是買著用的android手機,而虛擬機一般都是工程模式。
當你創(chuàng)建一個項目的時候,一般這個屬性沒有配置,但它有默認值,為false。
要發(fā)揮極客精神,就有必要對這個只是深挖,下面就來介紹這個標志是如何生效的。
首先,在安裝一個應用程序的APK到設備中時,包管理服務(PackageManagerService)會調用自己的解析器(PackageParser)去解析應用程序的"AndroidManifest.xml"文件,從而形成包信息。它的解析入口函數位于“/frameworks/base/core/java/android/content/pm/PackageParser.java”的parsePackage()方法中,該方法的關鍵代碼如下所示:
public Package parsePackage(File source,String destCodePath,DisplayMetrics metrics,int false){
.......
//打開AndroidManifest.xml文件
parser=assmgr.openXmlResourceParser(cookie,ANDROID_MANIFES_FILENAME);
........
try{
//開始解析AndroidManifest.xml文件
pkg=parserPackage(res,parser,flags,errorText);
}catch(Exception e){
......
}
//返回包信息
return pkg;
}
這里pkg=parserPackage(res,parser,flags,errorText);;負責解析整個AndroidManifest.xml文件。由于android:debuggable是
private boolean parseApplication(Package owner,Resources res,XmlPullParser parser,AttributeSet attrs,int flags,String[] outError)throws XmlPullParserException,IOException{
final ApplicationInfo ai=owner.applicationInfo;
final String pkgName=owner.applicationInfo.packageName;
.....
if(sa.getBoolean(com.android.internal.R.sytleable.AndroidManifestApplication_debuggable,false)){
ai.flags|=ApplicationInfo.FLAG_DEBUGGABLE;
}
.....
return true;
}
如果將android:debuggable設置為true,就將應用程序信息標志序列的第2位設置為1,這個標志對于應用程序的進程特征起了關鍵的作用。
最后,當我們試圖啟動這個應用程序時,這個標志序列中的一些位將轉換為參數信息來幫助孵化出應用程序的進程。關鍵代碼如下所示:
/dalvik/vm/native/dalvik_system_Zygote.cpp::enableDebugFeatures(u4 debugFlags)
static void enableDebugFeatures(u4 debugFlags){
......
#iifdef HAVE_ANDROID_OS
IF((debugFlags & DEBUG_ENABLE_DEBUGGER)!=0){
if(prct1(PR_SET_DUMPABLE,1,0,0,0)<0){
.......
}else{
.......
}
}
#endif
.......
}
其中prct1(PR_SET_DUMPABLE,1,0,0,0)設定了進程的可轉儲屬性為1。這樣設置之后,這個應用程序的進程就變?yōu)椤翱烧{試”狀態(tài)了。
6.android:description
這個屬性是描述應用程序的,它是一個用戶只讀的文本,比應用程序標簽android:label的描述更長,更詳細。但需要注意的是,這里必須配置為一個字符串資源的引用,不能像應用程序標簽那樣設置為一個字符串。它沒有默認值。
首先,我們要知道為什么Android要給這個限制(這里必須配置為一個字符串資源的引用),下面對比一下Android對android:label和android:description屬性的差異:
上面兩行代碼是對這兩個屬性的定義,其中l(wèi)abel的format為reference|string,這表示它支持資源引用和字符串兩種格式,而description的format僅為reference,這表示當配置android:description屬性時,它只能是一個引用。
7.android:enabled
默認情況下,Android系統(tǒng)會自行實例化每一個應用程序的組件,包括Android四大組件,但如果我們需要自己完成這些事情的話,就需要使用android:enabled屬性來限制Android系統(tǒng)的行為。這個屬性表明Android系統(tǒng)是否可以被實例化應用程序組件,如果其值為true,則說明應用程序組件可以被Android系統(tǒng)自動實例化;如果為false,則說明實例化組件的工作需要手工完成。該屬性的默認值為true。每一個組件都可以單獨定義自己的enabled屬性。如果這個屬性定義在
8.android:hasCode
該屬性表明應用程序是否含有代碼,若其值為true,表示應用程序含有代碼,false則表示其中沒有代碼。該屬性的默認值是true。當其值是false時,加載組件時系統(tǒng)不會嘗試加載任何應用程序的代碼。應用程序一般沒有它自己的任何代碼,除非它僅是由組件類構建而成的,比如Activity使用AliasActivity類,但這很少發(fā)生。
hasCode作為一個標志,被集成到包信息的flags標志中,以此來作為操作應用程序的參數,示例代碼如下所示:
if(sa.getBoolean(com.android.internal.R.sytleable.AndroidManifest
Application_hasCode,true)){
ai.flags|=ApplicationInfo.FLAG_HAS_CODE;
}
從以上代碼片段可以看出,這個標志被合到ai.flags的第3位上。
9.android:hardwareAccelerated
android:hardwareAccelerated標志指示硬件加速渲染功能是否對應用程序中的所有Activity和View啟用,如果啟用,則為true,否則為false,其默認值是false。
從Android 3.0開始,硬件加速的OpenGL渲染器對所有應用程序都有效,這樣做的目的是改善大多數2D圖形操作的性能。當硬件加速渲染器被啟用時,大多數操作(包括Canvas,Paint,Xfermode,ColorFilter,Shader和Camera)都會被加速,這樣產生的結果是更順滑的動畫效果,更順滑的滾動效果以及整體響應的改進。即使對于那些不能明確使用OpenGL庫的應用程序,其結果也一樣。
需要注意的是,不是所有的OpenGL操作都是被加速的。如果啟用硬件加速渲染器,就要先測試應用程序以便確保它可以無誤地使用渲染器。
對于Android框架來說,這個標志是這樣被打包成信息的:
boolean hardwareAccelerated=sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_hardwareAccelerated,
owner.applicationInfo.targetSdkVersion>=Build.VERSION_CODES.ICE_CREAM_SANDWICH);
.......
if(!receiver){
if(sa.getBoolean(com.android.internal.R.styleable.AndroidManifest
Activity_hardwareAccelerated,hardwareAccelerated)){
a.info.flags|=ActivityInfo.FLAG_HARDWARE_ACCELERATED;
}
.......
}else{
......
}
當沒有設置這個標志的時候,它的默認值取決于是否配置了android:targetSdkVersion。如果沒有配置,則Android默認將android:targetSdkVersion作為當前設備系統(tǒng)的SDK版本。當android:targetSdkVersion屬性的值大于或者等于當前系統(tǒng)版本時,則啟用硬件加速,反之則禁用硬件加速。
下面我們結合源代碼路徑/frameworks/base/core/java/androdi/app/Acti-vity.java,再來看看在Activity附加到窗口之前是如何使用這個標志的,代碼如下所示:
final vodi attach(Context context,ActivityThread aThread,Instrumentation instr,IBinder token,int ident,
Application application,Intent intent,ActivityInfo info,CharSequence title,Activity parent,String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config){
.....
mWindow.setWindowManager(null,mToken,mComponent,flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED)!=0)
}
建議: 如果不打算設置hardwareAccelerated標志,則盡量配置
10.android:label / android:icon
android:label和android:icon這兩個屬性分別是有關標簽和圖標的。先來看看android:label,它是Android標簽屬性,是應用程序全局的一個用戶可讀的標簽,也是該應用程序所有組件的默認標簽。在項目生成的時候,就已經定義了該屬性,它可以是一個字符串資源的引用,也可以是一個字符串。能這么做的原因是該標簽是這樣定義的:
此處,建議盡可以使用字符串資源的引用形式,因為這樣可以更好地支持國際化特性。在應用程序標簽被定義之后,它就會在諸如應用程序菜單,設置的應用程序信息等位置被使用,如下圖的位置:
在上圖,我們盾到紅色方框部分就是設置該屬性的效果圖。
接下來,我們再來看看另一個屬性android:icon,它是應用程序全局的一個圖標,也是該應用程序所有組件的默認圖標。這個屬性在Android框架中是這樣定義的:
可以看到,這里只能配置圖片資源的引用,例如@drawable/icon。當我們配置了這個屬性之后,它就會在應用程序菜單,設置的應用程序列表以及設置的應用程序詳情界面中顯示出來,通俗的說,就是應用程序圖標。
11.android:logo
android:logo屬性用于配置應用程序的商標。自Android3.0以后,應用程序窗口多了一個標題欄,而應用程序的logo將會出現在那里。對于Android框架而言,它是這樣定義這個屬性的:
這說明它能接受的只是一個圖片資源的引用。配置這個屬性后運行程序,會發(fā)現在啟動的每一個界面上都會看到這個圖標,如果同時設置了logo,icon,logo會覆蓋掉icon的圖標。
12.android:manageSpaceActivity
該屬性是一個Activity子類的全名,用戶使用它可以管理設備上該應用程序占有的內存。Activity也應該用
13.android:permission
該屬性是客戶端與應用程序交互所必須擁有的許可名,它是給應用程序的所有組件設置許可的便捷方式,可以被組件各自的許可屬性值所覆蓋。
14.android:persistent
該屬性用來表明應用程序是否應該在任何時候都保持運行狀態(tài),若為true,則表示應該,false則表示不應該,其默認值為false。通常,應用程序不應該設置本屬性,而持續(xù)模式僅僅對于某些系統(tǒng)應用程序才有意義。
在實際應用中就存在這樣的例子,例如電話模塊,它在系統(tǒng)啟動的時候就處于運行狀態(tài),這樣電話狀態(tài)發(fā)生變化時就會在系統(tǒng)產生相應的變化。如下面代碼所示:
android:persistent="true" android:label="@string/phoneAppLabel" android:icon="@drawable/ic_launcher_phone" ..... 15.android:process 該屬性是應用程序所有組件運行的進程名。每個組件都能夠設置自己的進程屬性,以此來覆蓋原來的默認值。 該屬性的默認值是當前的應用程序包名。當應用程序的第一個組件需要運行時,Android:就生成一個進程,所有的組件都將在該進程里運行。默認情況下,進程名與 該屬性設置為一個與其他應用程序共享的進程名,就可以將兩個應用程序的組件說運行在相同的進程里。能這樣做的前提是僅在兩個應用程序共享一個用戶ID并且被賦予相同證書時。 如果該屬性里設置的名字以冒號開頭(:),那么在需要的時候它將生成該應用程序的一個私有新進程。如果進程名以小寫字母開頭,則生成以該進程名命名的一個全局進程。全局進程可以用來與其他應用程序分享,以便降低資源消耗。 如果配置下面的代碼到新建的項目ApplicationTest里面,代碼如下: android:process=":jinggege" 會得到如下圖所示的結果: 如上圖所示,就是一個包名加上上面配置的屬性。 16.android:taskAffinity 它是應用程序所有Activity都適用的任務親和力,除了那些將不同任務親和力設置在自身taskAffinity屬性里的Activity。我們可以這樣理解這個屬性:該Activity更喜歡待在哪個任務中。 對于不同版本的Android SDK來說,框架對該屬性的處理是不一樣的。下面的代碼說明了還同處理中出現的一些問題: if(owner.applicationInfo.targetSdkVersion>=Build.VERSION_CODES.FROYO){ str=sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestApplication_taskAffinity,0); }else{ str=sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestApplication_taskAffinity); } ai.taskAffinity=buildTaskAffinityName(ai.packageName,ai.packageName,str,outError); 對于Android 2.2(Froyo)以后的版本,如果沒有設置這個屬性,則會采用默認值0,而之前的版本則不會提供默認值。 17.android:theme android:theme屬性為應用程序定義了一個整體風格。當開發(fā)一個商業(yè)應用程序時,風格是要考慮的重要因素之一。因此,為了保證應用程序的所有界面保持一定的風格標準,要盡量使用這個屬性為應用程序定義風格。 android:theme屬性是一個可以覆蓋的屬性。當我們需要對某個界面做一些特殊的處理時,只需要在對應的節(jié)點配置此屬性,就可以覆蓋掉應用程序配置的整體風格了。 對于框架而言,該屬性不是必須配置的。如果沒有配置,Android則會認為它的值為0,即無資源,如下代碼所示: ai.theme=sa.getResourceId(com.android.internal.R.styleable.AndroidManifestApplication_theme,0); 如果在 a.info.theme=sa.getResource(com.android.internal.R.styleable.AndroidManifestActivity_theme,0); 現在我們舉例說明如何使用這個屬性。例如,給 android:theme="@android:style/Animation.Dialog" 需要注意的是,這里的@android:style表示此資源位于“android”的空間中,也就是SDK預定義的那些資源。 剛剛說到增加的theme屬性指向Animation.Dialog風格,其中風格是這樣定義的: 這里規(guī)定了進入和推出的動畫效果。 除了使用SDK提供的風格資源以外,我們還可以使用自定義的風格資源,那么如何配置自定義風格呢?,大家可以按照下面的操作步驟自己動手實現。 ①定義自己的風格資源。在工程res/value/目錄下新建你的application_style.xml文件。 ②打開剛剛創(chuàng)建的文件,加入如下代碼: 18.android:uiOptions 該屬性用于開啟Activity UI附加的擴展導航欄。在配置這個屬性時,可供選擇的值必須是下表所示的兩個值中的一個。 需要說明的是,android:uiOption屬性是自Android4.0以后才提供的。因此,在需要使用該屬性的時候,孫弱保證使用Android4.0以后的SDK(API14) 下面舉例說明如何使用這個屬性。 ①就拿剛剛新建的AppilcationTest項目來說,在Androidmanifest.xml中的 android:uiOptions="splitActionBarWhenNarrow" ②在工程的/res.menu目錄下新建一個菜單配置文件my_menu_cfg.xml。在該文件中配置如下代碼:
需要注意的是,我們把要顯示為Action項的菜單項的android:showAsAction設置為always。
③新建一個Activity類,名為UIOptionActivity,實現onCreateOptionsMenu()方法加載my_menu_cfg.xml菜單布局,代碼如下:
public class UIOptionActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.my_menu_cfg,menu); return super.onCreateOptionsMenu(menu); } }
④編譯運行項目,運行結果如下圖。
可以發(fā)現,屏幕底部出現了狀態(tài)欄。
這樣剛剛配置的android:showAsAction的項目就顯示出來了,剩余部分包含在框中的超出菜單里,單擊它時才會顯示出來。大家可以自行嘗試一下去掉這個屬性的效果。
在不需要操作欄的時候,只需要把andriod:uiOption設置為none或者onCreateOptionmenu()方法空實現。
19.android:vmSafeMode
此屬性用于指示虛擬機是否在安全模式下運行,它是一個布爾值,當沒有配置它的時候,其默認值為false。示例代碼如下:
if(sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_vmsafeMode,false)){
ai.flags|=ApplicationInfo.FLAG_VM_SAFE_MODE;
}
20.android:largeHeap
此屬性指示應用程序是否使用一個比較大的堆創(chuàng)建,它是一個布爾值,在沒有配置的情況下,它的默認值是false,示例代碼如下:
if(sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_largeHeap,false)){
ai.flags|=ApplicationInfo.FLAG_LARGE_HEAP;
}
至此,我們介紹完了
要注意的是,作為應用程序的根節(jié)點,
Android
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。