织梦CMS - 轻松建站从此开始!

罗索

当前位置: 主页>杂项技术>.NET(C#)>

智能手机程序在线更新

jackyhwei 发布于 2010-09-15 16:54 点击:次 
最近刚完成一个在线更新的东西。因为智能手机应用没有Clickonce之类的更新程序,所以自己动手写一个。(其实clickonce也并不好用,自己动手写一个更方便).更新程序后台用webservice,httphandler都行,这里不多讲,主要讲讲前台设计。
TAG:

最近刚完成一个在线更新的东西。因为智能手机应用没有Clickonce之类的更新程序,所以自己动手写一个。(其实clickonce也并不好用,自己动手写一个更方便).更新程序后台用webservice,httphandler都行,这里不多讲,主要讲讲前台设计。
更新程序分为4个步骤:

1.下载服务器版本及更新列表,对比本地的版本,是否需要更新;

2.下载服务器的更新版本;

3.覆盖本地版本;

4.重新启动主应用程序;

如果用传统的设计,4个步骤很简单,定义一个枚举分别对应每个步骤;

// <summary>
// 系统自动升级步骤
// </summary>
public enum AutoUpdateStep
{
// <summary>
// 正在获取服务器版本
// </summary>
SeeingServerEdition = 1,
// <summary>
// 正在下载服务器端文件
// </summary>
DownLoadingServerFiles = 2,
// <summary>
// 服务器文件保存完毕
// </summary>
ServerFilesDownloaded = 3,
// <summary>
// 更新完毕
// </summary>
Finished = 4,
// <summary>
// 未知状态
// </summary>
Unknow = 0
}

然后if…else…判断步骤,执行相应的步骤。但是这样如果想在中间插入一个步骤,都会很麻烦。考虑过后,如果引入命令模式,则很方便的实现各个步骤。

定义各个步骤的基类:

public abstract class UpdateCommand
{
protected Context _context;
 
public UpdateCommand(Context context)
{
this._context = context;
}
 
#region abstract Method
public abstract void Execute();
#endregion
}
 
获取服务端版本及更新列表:

public class GetServerVersionCommand : UpdateCommand
{
public GetServerVersionCommand(Context context)
: base(context)
{
 
}
 
public override void Execute()
{
 //实现略……
}
}
 
 
下载服务端新版本:

public class DownloadDataCommand : UpdateCommand
{
public DownloadDataCommand(Context context)
: base(context)
{
 
}
 
public override void Execute()
{
//实现略……
}
}

其它2个步骤,更新本地版本,完成更新重启主程序类似,SaveDownloadDataCommand,FinishDownloadCommand。

Context 是用来和主界面交互的中间层,有点中介者的味道,主要定义了一系列事件,用于实现和主界面的交互。这样可以实现主界面与各个命令的解藕。

public sealed class SmartUpdateManager 
{
#region Properties
private List<UpdateCommand> Commands = null;
private int Index = 0;
 
private Context _context = null;
public Context UpdateContext
{
get
{
if (this._context == null)
{
_context = new Context();
}
return this._context;
}
}
 
#endregion
 
public SmartUpdateManager()
{
InitHandleUpdate();
}
 
private void InitHandleUpdate()
{
Commands = new List<UpdateCommand>();
GetServerVersionCommand cmd1 = new GetServerVersionCommand(UpdateContext);
DownloadDataCommand cmd2 = new DownloadDataCommand(UpdateContext);
SaveDownloadDataCommand cmd3 = new SaveDownloadDataCommand(UpdateContext);
FinishDownloadCommand cmd4 = new FinishDownloadCommand(UpdateContext);
 
Commands.Add(cmd1);
Commands.Add(cmd2);
Commands.Add(cmd3);
Commands.Add(cmd4);
}
 
#region Public Method
public void Execute()
{
  InnerHandExecute();
}
 
private void InnerHandExecute()
{
try
{
 if (this.Index < this.Commands.Count)
{
this.Commands[this.Index].Execute();
this.Index++;
}
}
catch (Exception)
{
}
}
#endregion
}

客户界面调用,很方便,主界面订阅SmartUpdateManager中Context的事件用于更新进度条,提示信息等交互信息。

private SmartUpdateManager manager = null;
private void InitUpdateManager()
{
manager = new SmartUpdateManager();
manager.UpdateContext.ApplicationExit += new ApplicationExitHandler(manager_onApplicationExit);
manager.UpdateContext.EnabledChanged += new EnabledChangedHandler(manager_onEnabledChanged);
manager.UpdateContext.ProcessBarValueChanged += new ProgressarValueChangedHandler(manager_onProcessBarValueChanged);
manager.UpdateContext.PromptMsgChanged += new PromptMsgChangedHandler(manager_onPromptMsgChanged);
manager.UpdateContext.TextChanged += new TextChangedHandler(manager_onTextChanged);
manager.UpdateContext.VisiableChanged += new VisiableChangedHandler(manager_onVisiableChanged);
manager.UpdateContext.WorkingTipMessageChanged += new WorkingTipMessageChangedHandler(manager_onWorkingTipMessageChanged);
manager.UpdateContext.CancelEnableChanged += new CancelEnableChangedHandler(manager_onCancelEnabled);
}
 
void btnNext_Click(object sender, EventArgs e)
{
try
{
this.psbDownload.Value = 0;
this.btnNext.Enabled = false;
this.manager.Execute();
//Application.DoEvents();
}
catch (Exception)
{
//………
}
}

 

这样的设计很容易实现向导,实际上我实现的就是向导式的更新。一步一步提示用户。如果想在中间增加一个环节,比如增加一个欢迎环节,一个校对文件的环节。那么我们只需要更改SmartUpdateManager中的代码。我们新增2个WelComeCommand, ValidateCommand.

private void InitHandleUpdate()
{
Commands = new List<UpdateCommand>();
//_context = new Context();
 
GetServerVersionCommand cmd1 = new GetServerVersionCommand(UpdateContext);
DownloadDataCommand cmd2 = new DownloadDataCommand(UpdateContext);
SaveDownloadDataCommand cmd3 = new SaveDownloadDataCommand(UpdateContext);
FinishDownloadCommand cmd4 = new FinishDownloadCommand(UpdateContext);
 
//注意这是新增的环节,欢迎环节。
WelComeCommand cmdNew1 = new WelComeCommand(UpdateContext);
//插入另一个新环节,校对下载的文件。。。。
ValidateCommand cmdNew2 = new ValidateCommand(UpdateContext);
 
Commands.Add(cmdNew1);  //插到第一个环节;
Commands.Add(cmd1);
Commands.Add(cmd2);
Commands.Add(cmdNew2);  //插入另一个环节,校对文件环节。
Commands.Add(cmd3);
Commands.Add(cmd4);
}
这样的需求变更,客户端的调用不需要任何改动。

(michael-zhangyu)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201009/10165.html]
本文出处:博客园 作者:michael-zhangyu
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容