当前位置: 代码迷 >> Android >> Android项目 手机安全卫士(代码最全,诠释最详细)之四 自动更新检查的逻辑
  详细解决方案

Android项目 手机安全卫士(代码最全,诠释最详细)之四 自动更新检查的逻辑

热度:30   发布时间:2016-04-28 08:06:27.0
Android项目 手机安全卫士(代码最全,注释最详细)之四 自动更新检查的逻辑
------- 源自梦想、永远是你IT事业的好友、只是勇敢地说出我学到! ----------

按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点也都能说出了123来,但是这些孤立的点终究显得太零散了,因此,我想从今天开始,以最经典的手机安全卫士项目为例,自己锻炼一下,也是想和大家交流交流,希望大家都能给出见解,共同进步。


四、自动更新检查的逻辑


3个软件:everything、size、color(GBR需转换成RGB)

版本的检测
会弹出对话框:最新版本的版本号,新版本的描述信息,是(下载路径)、否

1.新版本,在服务器端创建出来(可在Tomcat):
写一个update.xml文件,代码如下:

			<?xml version="1.0" encoding="UTF-8"?>			<infos>				<version>2.0</version>				<description>最新版手机卫士,坚决为您的手机服务,快下载吧,手机杀毒送月饼,下载就开始啦!!</description>				<apkurl>http://192.168.1.206/phonesafe2.0.apk</apkurl>			</infos>


开启tomcat服务器,检验xml文件是否能打开。
2.自动更新的逻辑:
1连接服务器去读取服务器的配置文件
2比对客户端和服务器端的版本,看是否相同
若相同,进入应用程序的主UI
若不相同,转3
3升级提醒对话框,看用户是否选择升级?
若否,进入应用程序的主UI
若是,下载新版本替换安装,转1

3.连接服务器,检查更新信息
联网权限:Internet
在values文件夹中单独创建一个config.xml文件,不写死路径,并在其中
增加服务器路径serverurl的String值为http://localhost/Android/update.xml

checkVersionTask()方法(在新线程中检查更新信息)
new Thread(){public void run(){...}}.start();
URL构造函数
连接网络、设置请求方式和超时时间,当响应码为200时,联网成功,否则出错,用Message给出出错信息,使用Handler()获取信息
定义一个Message:
Message msg =Message.obtain();	//Message类

				msg.what = SERVER_ERROR;				msg.what = URL_ERROR;				msg.what = NETOWRK_ERROR;

				protected static final int SERVER_ERROR = 0;				protected static final int URL_ERROR = 1;				protected static final int NETOWRK_ERROR = 2;




若没有产生异常的话,则走code == 200:
获取服务器中的输入流,也就是xml文件:

解析xml文件:
属于一个业务方法,建立一个包:com.dondong.phonesafe.engine
在这个包中建立一个业务类(UpdateInfoParser),类里面有一个方法:getUpdateInfo(InputStream is),
返回的是UpdateInfo的bean类对象,即返回解析后的更新信息。新建一个UpdateInfo类(bean类),放在domain包下。
类中有version、description、apkurl三个属性.
具体代码:
						public class UpdateInfo {							private String version;							private String description;							private String apkurl;							public String getVersion() {								return version;							}							public void setVersion(String version) {								this.verison = version;							}							public String getDescription() {								return description;							}							public void setDescription(String description) {								this.description = description;							}							public String getApkurl() {								return apkurl;							}							public void setApkurl(String apkurl) {								this.apkurl = apkurl;							}						}	



业务类(UpdateInfoParser)具体代码:
					public class UpdateInfoParser {												/**						 * 解析xml文件,返回更新的信息						 * @param is	代表xml文件的输入流						 * @return	null 表示解析失败,否则返回UpdateInfo对象						 */						public static UpdateInfo getUpdateInfo(InputStream is){		//这个方法没有用到什么类的成员变量,加static,效率更高些							try {								XmlPullParser parser = Xml.newPullParser();								parser.setInput(is, "utf-8");																//getEventType()方法Returns the type of the current event (START_TAG, END_TAG, TEXT, etc.)								int type = parser.getEventType(); 								UpdateInfo updateInfo = new UpdateInfo();								while(type != XmlPullParser.END_DOCUMENT){									if(type == XmlPullParser.START_TAG){										if("version".equals(parser.getName())){											/*											 * nextText()方法:											 * If current event is START_TAG then 											 * if next element is TEXT then element content is returned 											 * or if next event is END_TAG then empty string is returned, 											 * otherwise exception is thrown.											 * After calling this function successfully parser will be positioned on END_TAG. 											 */											String version = parser.nextText();											updateInfo.setVersion(version);										}else if("description".equals(parser.getName())){											String description = parser.nextText();											updateInfo.setDescription(description);										}else if("apkurl".equals(parser.getName())){											String apkurl = parser.nextText();											updateInfo.setApkurl(apkurl);										}									}									type = parser.next();								}								is.close();								return updateInfo;							} catch (Exception e) {								e.printStackTrace();								return null;							}						}					}





那么什么时候发这个msg呢?try...catch一定会走finally,我们就在finally语句中发送信息:
handler.sendmessage(msg);


具体代码:
						private void checkVersionTask() {							new Thread(){								@Override								public void run() {									Message msg =Message.obtain();									try {										URL url = new URL(getString(R.string.serverurl));	//获取服务器链接url										HttpURLConnection conn = (HttpURLConnection) url.openConnection();	//链接网络										conn.setRequestMethod("GET");	//设置请求方式										conn.setConnectTimeout(5000);	//设置连接超时时限																				int code = conn.getResponseCode();	//获取响应码,只有在响应码为200时才连接成功										if(code == 200){											//请求成功										}else{											//请求失败											msg.what = SERVER_ERROR;										}									}catch (MalformedURLException e) {  //因为MalformedURLException继承了IOException										e.printStackTrace();										//url错误:This exception is thrown when a program attempts to create an URL from an incorrect specification.										msg.what = URL_ERROR;									} catch (IOException e) {	//若IOException在MalformedURLException前,则MalformedURLException读不到										e.printStackTrace();										//网络连接错误										msg.what = NETOWRK_ERROR;									}finally{										handler.sendMessage(msg); //发送后handleMessage(Message msg)就会得到msg									}								};															}.start();						}


这时候handleMessage(Message msg)就可以获得msg,然后我们经过switch判断是那种错误,并Toast错误信息。
具体代码:
						private Handler handler = new Handler(){							@Override							public void handleMessage(Message msg) {	//得到msg后,就可以做判断了								switch (msg.what){								case SERVER_ERROR:									Toast.makeText(getApplicationContext(), "服务器错误。。。", 0).show();									break;								case URL_ERROR:									Toast.makeText(getApplicationContext(), "更新的URL错误。。。", 0).show();									break;								case NETOWRK_ERROR:									Toast.makeText(getApplicationContext(), "网络错误,请检查连接。。。", 0).show();									break;								}							}													};


若code=200,即请求成功,则
							//解析成功,则检查版本是否一样,在主线程中执行							msg.what = PARSE_XML_SUCCESS;

并在Hanlder中:
						case PARSE_XML_SUCCESS:							checkVersion();							break;

下面建立一个checkVersion()方法,用于检查客户端与服务端的版本是否相同。
具体代码:
						/**						 * 对比客户端和服务端的版本是否一样						 */						protected void checkVersion() {							//分别得到客户端和服务端的版本							if(getVersion().equals(updateInfo.getVersion())){	//如果版本号相同,则直接进入主界面															}else{		//否则,给出升级提醒对话框								AlertDialog.Builder builder = new Builder(this);	//创建对话框								builder.setTitle("更新提醒:");								builder.setMessage(updateInfo.getDescription());								builder.setPositiveButton("立即更新", new OnClickListener(){									@Override									public void onClick(DialogInterface dialog, int which) {										//用户选择更新,则替换安装										Log.i(TAG, "版本号不同,下载新的apk,替换安装");									}								});								builder.setNegativeButton("下次再说", new OnClickListener(){																		@Override									public void onClick(DialogInterface dialog, int which) {										//用户选择不更新,则直接进入主界面										loadMainUI();											}								});								builder.show();							}						}


这里需要做一个演示的主界面(HomeActivity)。

由于上述各种情况都需要进入主界面,所以在这里抽取成一个方法:loadMainUI()
具体代码:
					/**					 * 进入主界面					 */					private void loadMainUI() {						Intent intent = new Intent(SplashActivity.this,HomeActivity.class);						startActivity(intent);						finish();	//关闭当前界面					}


------- 源自梦想、永远是你IT事业的好友、只是勇敢地说出我学到! ----------
  相关解决方案