標籤:android apk 應用程式 安裝位置 外部儲存
從API Level 8(Android 2.2)開始,你可以將你的應用程式安裝到外部儲存上(例如,裝置的SD卡)。你可以在應用程式的manifest檔案中聲明android:installLocation屬性來使用這個可選的功能。如果你沒有聲明這個屬性,你的應用程式只能被安裝在內部儲存中,並且不能移動到外部儲存上。
允許系統將你的應用程式安裝到外部儲存上,你需要修改你的manifest檔案。在其中的<manifest>標籤下,添加android:installLocation屬性,並將值設定為“preferExternal”或者“auto”。例如:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" ... >
如果你聲明了“preferExternal”,這就表示請求系統將你的應用程式安裝到外部儲存中,但是系統不保證一定能將你的應用程式安裝到外部儲存上。如果外部儲存空間已經滿了,系統就會將應用程式安裝到內部儲存上。使用者同樣可以將你的應用程式在內部和外部儲存之間移動。
如果你聲明了“auto”,這表明你的應用程式可以安裝到外部儲存上,但是你沒有指定首選的安裝位置。系統會根據幾個因素來決定將你的應用程式安裝到什麼位置。使用者同樣可以將你的應用程式在內部和外部儲存之間移動。
當你的應用程式安裝在外部儲存上:
* 只要外部儲存一直掛載在裝置上,將應用程式安裝在外部儲存上對應用程式的效能沒有任何影響。
* .apk檔案會儲存在外部儲存上,但是所有使用者的私人資料、資料庫、最佳化過的.dex檔案,還有附加的本地代碼都會儲存在內部的裝置儲存空間上。
* 安裝了你的應用程式的特定儲存空間會使用一個隨機產生的key進行加密,這個key可以被原來安裝這個應用程式的裝置解密出來。因此,安裝在SD卡上的應用程式只能在一台裝置上運行。
* 使用者可以用過系統設定將你的應用程式移動到內部儲存上。
注意:當使用者啟用USD裝置儲存模式與電腦共用檔案,或者通過系統設定卸載了SD卡,外部儲存將會從裝置上被卸載下來,並且所有運行在外部儲存上的應用程式都會馬上結束被殺死。
1、向後相容性
只有運行API Level 8(Android 2.2)或者更高版本的裝置才允許將你的應用程式安裝到外部儲存上。已經存在的應用程式,如果是用低於API Level 8版本所編譯的,那麼這些應用程式只能一直安裝在內部儲存上,不能移動到外部儲存上(即使程式所安裝的裝置啟動並執行是Android 2.2或以上的版本)。然而,如果你的應用程式必須支援低於API Level 8的版本,你仍然可以為運行API Level 8或者更高版本的裝置提供這個功能,並且相容低於API Level 8版本的裝置。
為了允許應用程式安裝到外部儲存上,並且仍然相容低於API Level 8的版本,你需要:
1.1 在manifest檔案中的<manifest>標籤中添加android:installLocation屬性,並設定值為“auto”或者“preferExternal”。
1.2 繼續保持你的android:minSdkVersion屬性(低於版本8的值),並且確保你的應用程式的代碼只使用了相容這個版本的API。
1.3 為了能夠編譯你的應用程式,將你的android:targetSdkVersion修改為8或者更高的版本。這是必須的,因為舊的Android庫不能識別android:installLocation這個屬性,這會導致無法編譯你的應用程式。
當你的應用程式安裝到低於API Level 8版本的裝置上,android:installLocation這個屬性就會被忽略,應用程式會被安裝到內部儲存上。
警告:儘管像這樣的XML標籤在舊版本平台上會被忽略,但當你的minSdkVersion低於“8”時,你要小心不要在代碼中使用API Level 8版本才提供的API,除非你進行必要的工作以保證你的代碼能夠向後相容(進行版本判斷後再執行高版本API等)。
2、不應該安裝在外部儲存上的應用程式
當使用者啟用USB儲存模式與他們的電腦共用檔案(或者直接卸載和移除外部儲存空間),安裝在外部儲存上的應用程式會立即被殺死。系統會無法識別這些應用程式,直到USB儲存模式關閉並且外部儲存重新掛載到裝置上。除了殺死應用程式和讓使用者無法使用這些應用程式之外,這也可能會造成一些類型的應用程式產生更嚴重的後果。為了保持你的應用程式始終按照預期運行,如果你的應用程式使用了下面列出的功能,你就不應該將應用程式安裝在外部儲存上,以避免外部儲存被卸載的情況:
2.1 Services:你啟動並執行Service會被殺死,並且在外部儲存重新掛載後不會重新運行。當然,你也可以註冊ACTION_EXTERNAL_APPLICATIONS_AVAILABLE類型的Intent廣播,這將會在系統可以重新使用安裝在外部儲存上的應用程式時通知你的應用程式。接收到廣播後,你可以重啟的你的Service。
2.2 Alarm Services(鬧鐘/系統定時服務):你通過AlarmManager註冊的鬧鐘會被取消。你必須在外部儲存重新掛載之後手動再註冊這些鬧鐘。
2.3 Input Method Engines(IME,IME):你的IME將會被預設的IME代替。當外部儲存重新掛載後,使用者可以開啟系統設定重新啟用你的IME。
2.4 Live Wallpapers(動態壁紙):你啟動並執行動態壁紙將會被預設的動態壁紙替換。當外部儲存重新掛載後,使用者可以重新選擇你的動態壁紙。
2.5 App Widget(視窗小組件):你的視窗小組件將會從home介面上被移除。當外部儲存重新掛載後,你的視窗小組件對於使用者同樣不可使用,直到系統重設了home上面的應用程式(通常要等到系統重啟)。
2.6 Account Manager(帳號管理):使用AccountManager建立的帳號會消失,知道外部儲存重新掛載。
2.7 Sync Adapter(同步適配器):你的AbstractThreadedSyncAdapter和它的同步功能將會停止工作,直到外部儲存重新掛載上。
2.8 Device Administrators(裝置管理員):你的惡DeviceAdminReceive和它所有的系統管理權限都會被禁用,這對裝置功能可能造成不可預見的後果,並且在外部儲存重新掛載後可能還會持續下去。
2.9 監聽“裝置啟動完成”的廣播接收器:系統在外部儲存掛載到裝置上之前就會發布ACTION_BOOT_COMPLETED廣播。如果你的應用程式安裝在外部儲存上,它將無法接收到這個廣播。
如果你的應用程式使用上面列出的一些功能,你就不應該允許你的應用程式安裝到外部儲存上。預設情況下,系統不會允許你的應用程式安裝到外部儲存上,因此你不用擔心你已經發布完成的應用程式。然而,如果你需要確保你的應用程式永遠不會被安裝到外部儲存上,你可以清楚的聲明android:installLocation屬性,並賦值為“internalOnly”。儘管這不會改變預設的設定,但它可以明確你的應用程式只能安裝在內部儲存上,並提醒你自己或其他開發人員這一個決定。
3、應該安裝在外部儲存上的應用程式
簡單來說,任何沒有使用前面所列舉功能的應用程式安裝到外部儲存上都是安全的。大型遊戲通常都要允許安裝到外部儲存上,因為遊戲通常不會提供待機時啟動並執行服務。當外部儲存停用時候,遊戲進程會被殺死。當外部儲存重新可用並且使用者重啟了遊戲,在視覺介面上應該沒有什麼影響(假設遊戲通過標準的Activity生命週期正確儲存了它的狀態)。
如果你的應用程式需要幾個MB的APK檔案,你需要仔細考慮是否允許應用程式安裝到外部儲存上來為使用者節省內部儲存空間。
原文地址:http://developer.android.com/guide/topics/data/install-location.html
Android應用程式安裝位置(App Install Location)