OverView:
程序 通過後臺每天檢查是否有最新版本,如果需要更新當前版本,將彈出對話框讓用戶選擇是否在當前通過Market來更新軟件 。
Knowledge Points:
- SharedPreferences: 一個輕量級的存儲方法,類似於經常使用的.ini文件,它也是通過檢索關鍵字來取得相應的數值。之所以是成爲輕量級,是因爲它所能應用 的數值類型有限,對於存儲較大數值,效率相對較低。官方參考
- System.currentTimeMillis:將當前時間以毫秒作爲單位來表示,用於比較兩個時間的先後順序。(其數值表示從1970-01-01 00:00:00直到當前時間的總毫秒數)官方參考
- 通過網絡 來讀取信息:在checkUpdate()方法中包含了通過制定的URL來讀取網絡資源。具體操作步驟,請參考源代碼 。
- Runnable: 在其內部的Run()方法中實現所要執行的任何代碼,當這個runnable interface被調用後可以視作爲新的線程。
Source Code:
分爲三個部分:
- 置於onCreate()方法中的程序用於判斷當前時間是否需要檢查更新(如果距離上次更新時間大於1天,將啓動檢查更新)
- 當以上條件滿足時,啓動checkUpdate來檢查當前程序是否爲最新版本。
- 如果確定版本已過期,那麼將登錄market,並直接指向當前程序頁面。
*******************************************************************************************
向上言:
本人在論壇 曾經發過一關於此問題的求助 帖,雖然大至的思路和上文差不多,關鍵點是在於程序如何更新,現在看到它這裏指出的更新方法居然是登錄market。不過以後發佈的程序都是在market中,問題就不存在。
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:your.app.id"));
- startActivity(intent);
大家都是在eclipse上開發 吧,在每次更新代碼,運行 模擬器 時,大家是否有注意到console的提示信息:
- [2009-06-06 19:53:50 - Hello] Android Launch!
- [2009-06-06 19:53:50 - Hello] adb is running normally.
- [2009-06-06 19:53:50 - Hello] Performing linhai.com.hello.hello activity launch
- [2009-06-06 19:53:50 - Hello] Automatic Target Mode: using existing emulator 'emulator-5554' running compatible AVD 'avd'
- [2009-06-06 19:53:50 - Hello] WARNING: Application does not specify an API level requirement!
- [2009-06-06 19:53:50 - Hello] Device API version is 3 (Android 1.5)
- [2009-06-06 19:53:50 - Hello] Uploading Hello.apk onto device 'emulator-5554'
- [2009-06-06 19:53:50 - Hello] Installing Hello.apk...
- [2009-06-06 19:54:05 - Hello] Application already exists. Attempting to re-install instead...
- [2009-06-06 19:54:31 - Hello] Success!
分析:
1。android 正常運行
2。通過配置文件AndroidManifest.xml中運行我們的程序
3。Uploading Hello.apk onto device 'emulator-5554' 這句是關鍵,更新我們的程序
4。Installing Hello.apk...
5。Application already exists. Attempting to re-install instead... //程序已經存在,嘗試重新安裝
所以如果我們的程序要自動更新,本人初步猜想是和上面的步驟是一樣的。
詳看logcat中的log
- 06-06 11:54:02.567: DEBUG/PackageParser(582): Scanning package: /data/app/vmdl12464.tmp
- 06-06 11:54:08.048: INFO/PackageManager(582): Removing non-system package:linhai.com.hello
- 06-06 11:54:08.187: DEBUG/PackageManager(582): Removing package linhai.com.hello
- 06-06 11:54:08.286: DEBUG/PackageManager(582): Activities: linhai.com.hello.hello
- 06-06 11:54:11.136: DEBUG/PackageManager(582): Scanning package linhai.com.hello
- 06-06 11:54:11.301: INFO/PackageManager(582): /data/app/vmdl12464.tmp changed; unpacking
- 06-06 11:54:11.626: DEBUG/installd(555): DexInv: --- BEGIN '/data/app/vmdl12464.tmp' ---
- 06-06 11:54:12.987: DEBUG/dalvikvm(7756): DexOpt: load 224ms, verify 265ms, opt 1ms
- 06-06 11:54:13.047: DEBUG/installd(555): DexInv: --- END '/data/app/vmdl12464.tmp' (success) ---
- 06-06 11:54:13.057: DEBUG/PackageManager(582): Activities: linhai.com.hello.hello
- 06-06 11:54:15.608: INFO/installd(555): move /data/dalvik-cache/data@[email protected]@classes.dex -> /data/dalvik-cache/data@[email protected]@classes.dex
- 06-06 11:54:15.737: DEBUG/PackageManager(582): New package installed in /data/app/linhai.com.hello.apk
關於此類的自動更新的第三方管理 軟件已經有了叫aTrackDog ,其原理就是使用上面的方式。
關於得到版本號,使用:
- int curVersion = getPackageManager().getPackageInfo("your.app.id", 0).versionCode;
程序版本號的是放在AndroidManifest.xml文件中:
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="linhai.com.hello" android:versionCode="2" android:versionName="2.0.1">
主點是關於:getPackageManager()在這個下面有很多方法,你可以通過它得,得到當前終端安裝的程序等。關於安裝包的函數是:getPackageManager().installPackage(packageURI)
動手試驗:
在dos狀態下運行:
查看logcat下的信息,大致和剛纔相同,分析流程:
- 06-06 12:18:58.827: INFO/jdwp(8368): received file descriptor 20 from ADB
- 06-06 12:19:02.546: DEBUG/PackageParser(582): Scanning package: /data/app/vmdl12465.tmp
- 06-06 12:19:07.738: INFO/PackageManager(582): /data/app/vmdl12465.tmp changed; unpacking
- 06-06 12:19:07.978: DEBUG/installd(555): DexInv: --- BEGIN '/data/app/vmdl12465.tmp' ---
- 06-06 12:19:09.617: DEBUG/dalvikvm(8378): DexOpt: load 254ms, verify 564ms, opt 3ms
- 06-06 12:19:09.697: DEBUG/installd(555): DexInv: --- END '/data/app/vmdl12465.tmp' (success) ---
- 06-06 12:19:11.907: INFO/installd(555): move /data/dalvik-cache/data@[email protected]@classes.dex -> /data/dalvik-cache/data@[email protected]@classes.dex
- 06-06 12:19:11.956: DEBUG/PackageManager(582): New package installed in /data/app/com.example.android.snake.apk
- 06-06 12:19:14.746: DEBUG/dalvikvm(8368): VM cleaning up
- 06-06 12:19:14.857: DEBUG/dalvikvm(8368): LinearAlloc 0x0 used 628420 of 4194304 (14%)
- 06-06 12:19:15.897: DEBUG/dalvikvm(582): GC freed 17704 objects / 903984 bytes in 615ms
- 06-06 12:19:15.936: DEBUG/HomeLoaders(625): application intent received: android.intent.action.PACKAGE_ADDED, replacing=false
- 06-06 12:19:15.936: DEBUG/HomeLoaders(625): --> package:com.example.android.snake
- 06-06 12:19:15.936: DEBUG/HomeLoaders(625): --> add package
1。接收數據,保存到臨時文件中/data/app/vmdl12465.tmp
2。解壓此文件,注意路徑/data/dalvik-cache/data@[email protected] @classes.dex
它是在data下的dalvik-cache下
3.安裝文件[這個步驟還包括查找程序是否已經安裝等]
4.使用GC清理內存
查看DDMS中的結構
看到此文件結構,應該可以想起linux下的文件系統 和它的權限管理,也就可以理解,爲什麼我們的程序無法在data下創建文件之類的問題了。
關於aTrackDog程序相關信息:http://atrackdog.a0soft.com/intro.php