關於app更新升級的方法
阿新 • • 發佈:2018-11-12
App的更新升級是所有移動開發人員都要去了解的東西,這篇文章只是留給自己的筆記,希望能幫到大家。在這裡總共描述了基本的三種更新方式:本地、第三方更新、熱更新。
1.本地更新: 其實就是在app啟動的時候通過向後臺請求資料獲取伺服器中的apk版本號以及下載地址,如果獲取到的apk版本號比本地j的versionCode要高,那麼就彈出更新提示開啟server進行下載,在現在結束的時候開啟廣播通知安裝提示.
3.熱更新:這種方式會在使用者察覺不到的情況下更新完成,它只會下載新版本和上一版不同的地方,一般在apk有緊急bug的時候使用。否則頻繁的提示使用者更新去下載全量的apk檔案,對使用者的體驗是有非常大的影響的。它的侷限性也比較大,接下來的文章會提到。
本地更新
compile 'io.reactivex:rxjava:1.3.3'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.tbruyelle.rxpermissions:rxpermissions:[email protected]'
startDownload()方法中的內容 開啟系統的一個下載器進行下載 當然有的app這個下載器會自己寫
Tinker熱更新
文章看不懂的可以去看一下bugly平臺給的視訊教程。
首先匯入一個Android Studio的外掛
然後整合ndk 和上一種方式一模一樣,直接複製就可以了 加入一個分包工具
在Applaction中重寫attachBaseContext()
這就是三種不同的更新方式,如果你想直接使用後兩種更新方法,建議還是先看一下本地更新,自己寫過的才是自己的。
1.本地更新: 其實就是在app啟動的時候通過向後臺請求資料獲取伺服器中的apk版本號以及下載地址,如果獲取到的apk版本號比本地j的versionCode要高,那麼就彈出更新提示開啟server進行下載,在現在結束的時候開啟廣播通知安裝提示.
2.第三方更新: 其實和上一種方式基本相同需要整合第三方,僅僅是減少了我們的工作量,但是也有缺點,就是延時的問題 更新不會及時生效。
首先請求介面獲取到版本號,比較版本號大小。這一片程式碼比較簡單我就不貼了。 需要更新的話就彈出Dialog提示更新 在更新更新按鈕上設定開啟服務DownLoadServerice,記得服務要在清單檔案中註冊
下面是DownLoadServerice的內容 需要重寫onBind() onStartCommand() onDestroy()三個方法android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(MainActivity.this); builder.setTitle("四不四要更新?"); builder.setMessage("快點點搜"); builder.setPositiveButton("點我更新噻", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int i) { dialog.dismiss(); Intent intent = new Intent(MainActivity.this, DownLoadServerice.class); startService(intent); } }); builder.setNegativeButton("不更新滾", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int i) { dialog.dismiss(); } }); builder.create().show();
在onStartCommand中 進行許可權的申請 這裡需要在Gradle中配置@Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { } @Override public void onDestroy() { super.onDestroy(); }
compile 'io.reactivex:rxjava:1.3.3'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.tbruyelle.rxpermissions:rxpermissions:[email protected]'
RxPermissions.getInstance(this)
// 申請許可權
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean granted) {
if(granted){
//請求成功
startDownload(downloadUrl);
}else{
// 請求失敗回收當前服務
stopSelf();
}
}
});
//註冊廣播
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
install(context);
//銷燬當前的Service
stopSelf();
}
};
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
return Service.START_STICKY;
startDownload()方法中的內容 開啟系統的一個下載器進行下載 當然有的app這個下載器會自己寫
private void startDownload(String downUrl) {
//獲得系統下載器
dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
//設定下載地址
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downUrl));
//設定下載檔案的型別
request.setMimeType("application/vnd.android.package-archive");
//設定下載存放的資料夾和檔名字
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "versionupdate.apk");
//設定下載時或者下載完成時,通知欄是否顯示
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setTitle("下載新版本");
//執行下載,並返回任務唯一id
enqueue = dm.enqueue(request);
}
當下載完成之後通過隱式意圖安裝程式安裝下載好的apk檔案
public static void install(Context context) {
File file = new File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) , "versionupdate.apk");
Intent intent = new Intent(Intent.ACTION_VIEW);
// 由於沒有在Activity環境下啟動Activity,設定下面的標籤
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if(Build.VERSION.SDK_INT>=24) {
//判讀版本是否在7.0以上 7.0對檔案的許可權有了新的修改
Uri apkUri = FileProvider.getUriForFile(context, "com.hxtj.versionupdate.fileprovider", file);
//新增這一句表示對目標應用臨時授權該Uri所代表的檔案
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
}else{
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
}
context.startActivity(intent);
}
最後一定要記得在onDestroy()中反註冊掉廣播unregisterReceiver(receiver);
第三方更新
首先在騰訊的Bugly平臺註冊賬號然後新建自己的產品 在專案的gradle中配置ndk 引入bugly包
ndk { //設定支援的SO庫架構 abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a' }
compile 'com.tencent.bugly:crashreport_upgrade:latest.release' compile 'com.tencent.bugly:nativecrashreport:latest.release'
配置清單檔案
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
在清單檔案中加入Bulay的Activity
<activity android:name="com.tencent.bugly.beta.ui.BetaActivity" android:theme="@android:style/Theme.Translucent" android:configChanges="keyboardHidden|orientation|screenSize|locale"/>
在application中初始化Bulay
Bugly.init(getApplicationContext(), "你的appid", false);
然後在手機上跑一個1.0的版本,在製作一個2.0的版本包 將2.0上傳到bugly平臺上啟動。這樣的話就完成了,相對來說比第一種方法簡單了很多 ,如果對更新的樣式之類的需求不是很強烈的話 (bugly對開發者也提供了一些不同的彈出樣式以供選擇,還是很人性化的) 可以使用這種更新方式,在啟動之後會有幾分鐘的延遲效果才會生效。在接下來的熱更新中延時效果會更加明顯。
Tinker熱更新
文章看不懂的可以去看一下bugly平臺給的視訊教程。
首先匯入一個Android Studio的外掛
classpath‘com.tencent.bugly:tinker-support:1.1.1’
加入一個Glade外掛
apply from: 'tinker-support.grald'
新建一個glade檔案 tinker-support.grald 將官方文件的內容全部貼上進入 覆蓋之前的所有內容
然後整合ndk 和上一種方式一模一樣,直接複製就可以了 加入一個分包工具
compile "com.android.support:multidex:1.0.1"
初始化sdk
將tinker-support.grald中的enableProxyApplaction改為true
設定自動生成tinkerid : autoGenerateTinkerId=true
支援新增Activity : supportHotplugComponent=true
在Applaction中重寫attachBaseContext()
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
// you must install multiDex whatever tinker is installed!
MultiDex.install(base);
// 安裝tinker
Beta.installTinker();
}
在清單檔案的配置和第三方更新的配置一模一樣 直接看上邊的就可以了 這樣的話就接入完成 可以使用了
熱更新的平臺在使用的時候可以看到 它可以針對部分版本的apk進行更新 還可以限量進行更新 和 測試機更新
使用注意事項:
1.包分為基準包和補丁包
2.基準包的目錄要保證一致
3.上傳補丁包之前一定要執行基準包否則會報錯
這就是三種不同的更新方式,如果你想直接使用後兩種更新方法,建議還是先看一下本地更新,自己寫過的才是自己的。