关于app更新升级的方法

        App的更新升级是所有移动开发人员都要去了解的东西,这篇文章只是留给自己的笔记,希望能帮到大家。在这里总共描述了基本的三种更新方式:本地、第三方更新、热更新。

1.本地更新: 其实就是在app启动的时候通过向后台请求数据获取服务器中的apk版本号以及下载地址,如果获取到的apk版本号比本地j的versionCode要高,那么就弹出更新提示开启server进行下载,在现在结束的时候开启广播通知安装提示.
 
  

2.第三方更新: 其实和上一种方式基本相同需要集成第三方,仅仅是减少了我们的工作量,但是也有缺点,就是延时的问题 更新不会及时生效。

3.热更新:这种方式会在用户察觉不到的情况下更新完成,它只会下载新版本和上一版不同的地方,一般在apk有紧急bug的时候使用。否则频繁的提示用户更新去下载全量的apk文件,对用户的体验是有非常大的影响的。它的局限性也比较大,接下来的文章会提到。

本地更新

首先请求接口获取到版本号,比较版本号大小。这一片代码比较简单我就不贴了。
需要更新的话就弹出Dialog提示更新 在更新更新按钮上设置开启服务DownLoadServerice,记得服务要在清单文件中注册

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();

下面是DownLoadServerice的内容 需要重写onBind() onStartCommand()  onDestroy()三个方法

 @Override
 public IBinder onBind(Intent intent) {
        return null;
 }
 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
 }
 @Override
 public void onDestroy() {
       super.onDestroy();
 }
在onStartCommand中 进行权限的申请
这里需要在Gradle中配置

    compile 'io.reactivex:rxjava:1.3.3'
    compile 'io.reactivex:rxandroid:1.2.1'
    compile 'com.tbruyelle.rxpermissions:rxpermissions:0.7.0@aar'

RxPermissions.getInstance(this)
 // 申请权限                
	.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
        .subscribe(new Action1() {
                    @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'

配置清单文件










在清单文件中加入Bulay的Activity  
在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.上传补丁包之前一定要运行基准包否则会报错

       这就是三种不同的更新方式,如果你想直接使用后两种更新方法,建议还是先看一下本地更新,自己写过的才是自己的。

你可能感兴趣的:(Android移动开发,知识点)