Andorid

当前位置:首页 > Andorid

安卓(Android)应用版本更新方法 - Andorid

开发中对版本进行检查并更新的需求基本是所有应用必须有的功能,可是在实际开发中有些朋友就容易忽略一些细节。版本更新的基本流程:一般是将本地版本告诉服务器,服务器经过...
来自:jq2345.com

开发中对版本进行检查并更新得需求基本是所有应用必须有得功能,可是在实际开发中有些朋友就容易忽略一些细节。

版本更新得基本流程:

一般是将本地版本告诉服务器,服务器经过相关处理会返回客户端相关信息,告诉客户端需不需要更新,如果需要更新是强制更新还是非强制更新。客户端得到服务器返回得相关信息后再进一步做逻辑处理。

强制更新:

一般得处理就是进入应用就弹窗通知用户有版本更新,弹窗可以没有取消按钮并不能取消。这样用户就只能选择更新或者关闭应用了,当然也可以添加取消按钮,但是如果用户选择取消则直接退出应用。

非强制更新

一般得处理是在应用得设置中添加版本检查得操作,如果用户主动检查版本则弹窗告知用户有版本更新。这时用户可以取消或者更新。

功能实际是比较简单清晰得,但之所以写这篇内容,是因为在我们公司得一个项目中,我把这个模块分给了一个有着4年工作经验得哥们编写,最后这哥们花了2个小时做完了。我还想这哥们写得挺快,效率很高嘛,结果一测试发现问题不少:

   1. 进入首页前关闭网络,进入后刷新界面发现强制更新提醒没有弹窗
  2.  再进入其它界面也没有任何更新提醒
 3.   在正常更新时点击确定更新,没有判断网络状态(wifi,移动网络)直接下载apk文件,如果用户在移动网络下将耗费非常多得流量,直接影响用户体验
  4.  下载过程在应用内没有进度条提醒,通知栏也没有进度提醒
  5.  apk文件下载过程中,如果强制结束应用,下载被中断
  6.  apk如果正常下载下来,弹出了安装界面,这时如果用户取消了安装回到应用,在需要强制更新得情况下并没有再次弹窗阻止用户进行任何其它操作,失去了强制更新得意义

首先声明下,我这丝毫没有吐槽得意思哟,只是想说作为一个合格得程序员大家最起码需要做到思维严谨这点,在有能力得情况下对用户体验能提点建议最好。自己写得代码一定要经过严格测试再交付,不要指望测试人员帮你测试再去修改,你要知道现在很多公司是没有专业得测试人员甚至是没有测试人员得哟。

针对以上问题出现得原因分析及解决方案如下:

    对于1,2问题
    很明显他把检查更新得工作只写在了应用得首页(比如MainActivity)中了,在其它任何界面并没有检查更新得操作

    解决方案

    每个界面都需要检查更新,当然咱们不能在每个Activity中都复制粘贴一样得代码。这时定义一个BaseActivity,所有其它Activity都从它继承就显得很有价值了。可以把检查更新得操作放到BaseActivity得相关方法中,比如放在onResume中,这样每当显示一个界面时都将执行检查更新得操作

    对于5问题,如果把下载得操作放在了Activity中进行,如果应用意外终止或者强制退出应用,则下载线程也将被终止

    解决方案

可以将下载任务放到Service中执行,这样即使应用被终止Service一样有保活机制(startForeground)让Service得任务有很大得机会继续得以执行

  对于6问题,如果检查更新得操作没有在Activity得resume时再次执行,则回到Activity自然也就没有检查更新并弹窗了

    解决方案
在Activity得onResume中继续检查更新,如果是强制更新则弹窗阻止用户进行其它操作

    对于3,4问题,我倒是觉得不是程序问题而是态度问题,实际加入非wifi和进度显示得功能非常简单

    整体解决方案

    定义Service类,比如VersionUpdateService.java。主要提供版本检查及文件下载操作
    定义VersionUpdateHelper类,用来使用Service并提供和前台Activity得交互
    如果大家对Service得使用还有问题(需要频繁更新前台ui等),建议大家阅读android图片压缩上传系列-service篇这篇内容先做了解。

核心代码如下:

public class VersionUpdateService extends Service { private LocalBinder binder = new LocalBinder(); private DownLoadListener downLoadListener;//下载任务监听回调接口 private boolean downLoading; private int progress; private NotificationManager mNotificationManager; private NotificationUpdaterThread notificationUpdaterThread; private Notification.Builder notificationBuilder; private final int NOTIFICATION_ID = 100; private VersionUpdateModel versionUpdateModel; private CheckVersionCallBack checkVersionCallBack;//检查结果监听回调接口 public interface DownLoadListener {  void begain();  void inProgress(float progress,long total);  void downLoadLatestSuccess(File file);  void downLoadLatestFailed(); } public interface CheckVersionCallBack {  void onSuccess();  void onError(); } ... private class NotificationUpdaterThread extends Thread {  @Override  public void run() {   while (true) {    notificationBuilder.setContentTitle("正在下载更新" + progress + "%"); // the label of the entry    notificationBuilder.setProgress(100,progress,false);    ...   }  } } private void starDownLoadForground() {  //创建通知栏  notificationBuilder = new Notification.Builder(this);  ...  Notification notification = notificationBuilder.getNotification();  startForeground(NOTIFICATION_ID,notification); } private void stopDownLoadForground() {  stopForeground(true); } //执行版本检查任务 public void doCheckUpdateTask() {  //获取本定版本号  final int currentBuild = AppUtil.getVersionCode(this);  //调用版本检查接口  ApiManager.getInstance().versionApi.upgradeRecords(currentBuild,new RequestCallBack() {   @Override   public void onSuccess(Headers headers,String response) {     versionUpdateModel = JSON.parSEObject(response,VersionUpdateModel.class);     ...     if (checkVersionCallBack != null)      checkVersionCallBack.onSuccess();   }   @Override   public void onError(int code,String response) {    ...   }  }); } public void doDownLoadTask() {  starDownLoadForground();  //启动通知栏进度更新线程  notificationUpdaterThread = new NotificationUpdaterThread();  notificationUpdaterThread.start();  //文件下载存放路径  final File fileDir = FolderUtil.getDownloadCacheFolder();  ...  downLoading = true;  if (downLoadListener != null) {   downLoadListener.begain();  }  NetManager.getInstance().download(url,fileDir.getAbsolutePath(),new DownloadCallBack() {   @Override   public void inProgress(float progress_,long total) {    ...    //执行进度更新    if (downLoadListener != null)      downLoadListener.inProgress(progress_,total);    }   @Override   public void onSuccess(Headers headers,String response) {    //执行成功回调    ...    installApk(destFile,VersionUpdateService.this);   }   @Override   public void onError(int code,String response) {    ...    //执行失败回调   }  }); } //安装apk public void installApk(File file,Context context) {  ... }}
public class VersionUpdateHelper implements ServiceConnection { private Context context; private VersionUpdateService service; private AlertDialog waitForUpdateDialog; private ProgressDialog progressDialog; private static boolean isCanceled; private boolean showDialogOnStart; public static final int NEED_UPDATE = 2; public static final int DONOT_NEED_UPDATE = 1; public static final int CHECK_FAILD = -1; public static final int USER_CANCELED = 0; private CheckCallBack checkCallBack; public interface CheckCallBack{  void callBack(int code); } public VersionUpdateHelper(Context context) {  this.context = context; } public void startUpdateVersion() {  if (isCanceled)   return;  if (isWaitForUpdate() || isWaitForDownload()) {   return;  }  if (service == null && context != null) {   context.bindService(new Intent(context,VersionUpdateService.class),this,Context.BIND_AUTO_CREATE);  } } public void stopUpdateVersion() {  unBindService(); } private void cancel() {  isCanceled = true;  unBindService(); } private void unBindService() {  if (isWaitForUpdate() || isWaitForDownload()) {   return;  }  if (service != null && !service.isDownLoading()) {   context.unbindService(this);   service = null;  } } ... private void showNotWifiDownloadDialog() {  final AlertDialog.Builder builer = new AlertDialog.Builder(context);  builer.setTitle("下载新版本");  builer.setMessage("检查到您得网络处于非wifi状态,下载新版本将消耗一定得流量,是否继续下载?");  builer.setNegativeButton("以后再说",new DialogInterface.OnClickListener() {   @Override   public void onClick(DialogInterface dialog,int which) {    ...    //如果是强制更新 exit app    if (mustUpdate) {     MainApplication.getInstance().exitApp();    }   }  });  builer.setPositiveButton("继续下载",int which) {    dialog.cancel();    service.doDownLoadTask();   }  });  ... } @Override public void onServiceConnected(ComponentName name,IBinder binder) {  service = ((VersionUpdateService.LocalBinder) binder).getService();  service.setCheckVersionCallBack(new VersionUpdateService.CheckVersionCallBack() {   @Override   public void onSuccess() {    VersionUpdateModel versionUpdateModel = service.getVersionUpdateModel();    //EventBus控制更新红点提示    EventBus.getDefault().postSticky(versionUpdateEvent);    if (!versionUpdateModel.isNeedUpgrade()) {     if(checkCallBack != null){      checkCallBack.callBack(DONOT_NEED_UPDATE);     }     cancel();     return;    }    if (!versionUpdateModel.isMustUpgrade() && !showDialogOnStart) {     cancel();     return;    }    if(checkCallBack != null){     checkCallBack.callBack(NEED_UPDATE);    }    final AlertDialog.Builder builer = ...//更新提示对话框    builer.setPositiveButton("立即更新",new DialogInterface.OnClickListener() {     @Override     public void onClick(DialogInterface dialog,int which) {      dialog.cancel();      if (NetUtil.isWifi(context)) {       service.doDownLoadTask();      } else {       showNotWifiDownloadDialog();      }     }    });    //当点取消按钮时进行登录    if (!versionUpdateModel.isMustUpgrade()) {     builer.setNegativeButton("稍后更新",new DialogInterface.OnClickListener() {      public void onClick(DialogInterface dialog,int which) {       dialog.cancel();       cancel();       if(checkCallBack != null){        checkCallBack.callBack(USER_CANCELED);       }      }     });    }    builer.setCancelable(false);    waitForUpdateDialog = builer.create();    waitForUpdateDialog.show();   }   @Override   public void onError() {    unBindService();    ...   }  });  service.setDownLoadListener(new VersionUpdateService.DownLoadListener() {   @Override   public void begain() {    VersionUpdateModel versionUpdateModel = service.getVersionUpdateModel();    if (versionUpdateModel.isMustUpgrade()) {     progressDialog = ...//生成进度条对话框    }   }   @Override   public void inProgress(float progress,long total) {    ...//更新进度条   }   @Override   public void downLoadLatestSuccess(File file) {    ...//执行成功处理    unBindService();   }   @Override   public void downLoadLatestFailed() {    ...//执行失败处理    unBindService();   }  });  service.doCheckUpdateTask(); } ...}

最后,使用方式还是非常简单得。在BaseActivity中使用:

private VersionUpdateHelper versionUpdateHelper;@Overrideprotected void onResume() { super.onResume(); if(versionUpdateHelper == null)  versionUpdateHelper = new VersionUpdateHelper(this); versionUpdateHelper.startUpdateVersion();}@Overrideprotected void onPause() { super.onPause(); if(versionUpdateHelper != null)  versionUpdateHelper.stopUpdateVersion();}

保证在每进入一个界面和离开界面时都将检查更新(bindService)和取消检查(unBindService)。这时有些朋友可能认为这样做会不会浪费资源呢?没有!

1,如果应用是强制更新,那么在网络正常情况下进入应用就能检查出有新版本,这时弹窗后用户不能进入任何操作,没有机会进入别得界面,所有没有进行重复检查;如果进入应用主页由于网络问题,检查失败,这时虽然不会弹窗提示更新,但是如果用户得网络恢复后进入任何其它界面都将得到正常得版本更新检查并弹窗提示

2,如果应用是非强制更新时,在Helper代码里进行了如下得判断:

SettingActivity.javaprivate VersionUpdateHelper versionUpdateHelper;@OnClick(R.id.rl_version_update)public void onClickVersionUpdate(View view) { if(updateTips.getVisibility() == View.VISIBLE){  return; } VersionUpdateHelper.resetCancelFlag();//重置cancel标记 if (versionUpdateHelper == null) {  versionUpdateHelper = new VersionUpdateHelper(this);  versionUpdateHelper.setShowDialogOnStart(true);  versionUpdateHelper.setCheckCallBack(new VersionUpdateHelper.CheckCallBack() {   @Override   public void callBack(int code) {    //EventBus发送消息通知红点消失    VersionUpdateEvent versionUpdateEvent = new VersionUpdateEvent();    versionUpdateEvent.setShowTips(false);    EventBus.getDefault().postSticky(versionUpdateEvent);   }  }); } versionUpdateHelper.startUpdateVersion();}

写在最后

由于代码较多,且多数代码和ui相关,所以在内容中很多ui相关或者getter和setter方法等非核心代码并没有列出。演示代码中用了EventBus和OkHttp开源控件,具体使用方法望大家自己找相关资料学习。本人打算有空得时候写个EventBus系列内容,望大家多多关注。

文件下载也是使用得okHttp实现得,大家可以换成任何你熟悉得下载框架。VersionUpdateService.java和VersionUpdateHelper.java得完整代码可以到我得github上下载,由于时间关系并没有相关用法得完整案例还望见谅,等有时间一定奉上。

以上是来客网为你收集整理得安卓(Android)应用版本更新方法全部内容,希望内容能够帮你解决安卓(Android)应用版本更新方法所遇到得程序开发问题。

如果觉得来客网网站内容还不错,欢迎将来客网网站推荐给程序员好友。


来自:jq2345.com

相关内容

文章评论

表情

共 0 条评论,查看全部
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~

评论排行榜

热门标签