------- 源自梦想永远是你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事业的好友、只是勇敢地说出我学到! ----------

Android小项目之四 自动更新检查的逻辑的更多相关文章

  1. Android应用程序的自动更新升级(自身升级、通过tomcat)(转)

    Android应用程序的自动更新升级(自身升级.通过tomcat) http://blog.csdn.net/mu0206mu/article/details/7204746 刚入手android一个 ...

  2. Android小项目之十 应用程序更新的签名问题

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...

  3. Android小项目之十二 设置中心的界面

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...

  4. [android] 手机卫士关闭自动更新

    保存数据的四种方式,网络,广播提供者,SharedPreferences,数据库 获取SharedPreferences对象,通过getSharedPreferences()方法,参数:名称,模式 例 ...

  5. 如何一键部署项目&&代码自动更新

    my-deploy : 由nodejs写的一个自动更新工具,理论支持所有语言(php.java.c#)的项目,支持所有git仓库(bitbucket.github等). Github 效果如何? 如果 ...

  6. Android小项目之七 应用程序的更新安装

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...

  7. Android小项目之十一 应用程序的主界面

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...

  8. Android小项目之八 界面细节

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...

  9. Android小项目之五 splash动画效果

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...

随机推荐

  1. 进入GRUB改root用户密码

    开机读取倒计时时按任意键----e---->选择第二行 kernel ---->按e, 再按空格 >输入1----回车--->选择kernel输入b----> passw ...

  2. I/O小总结

    //判断不存在就创建目录 ,然后拷贝文件 DirectoryInfo di = null; if (!Directory.Exists(n.Attribute("value").V ...

  3. How Tomcat Works(十一)

    本文接下来分析tomcat的类载入器,tomcat需要实现一个自定义的载入器,而不能使用系统类载入器 (1)限制serlvet访问当前运行的java虚拟机中环境变量CLASSPATH指明的路径下的所有 ...

  4. 乱侃c++

    就在刚才我感觉c++真的好复杂,函数重载,多态,虚函数,虚函数表,模版,继承等一大坨东西好恶心,c++既然完全支持C语言,当然是把它的优缺点统统接下了,C语言中指针本身并不太难,是C语言的精华,当年刚 ...

  5. C#和JavaScript的区别

    Strong and Loose Typing: 强弱比较 // C# var customer = new Customer(); //var is compiler inferred //Java ...

  6. php涉及数据库操作时响应很慢。

    症状描述: 网站是php开发的,大部分页面响应很慢. 本地开发时响应速度很快,但是部署到生产环境后大部分响应很慢. 通过谷歌浏览调试发现PHP页面加载很慢,有个别的php请求的响应时间甚至超过10秒, ...

  7. java中导入常量

    import关键字除了导入包之外,还可以导入静态成员,这时JDK5.0以上版本提供的新功能.导入静态成员可以是程序员编程更为方便. 使用import导入静态成员的语法为: import static ...

  8. ANDROID FRAMENT的切换(解决REPLACE的低效)

    http://www.cnblogs.com/android-joker/p/4414891.html 在项目中切换Fragment,一直都是用replace()方法来替换Fragment.但是这样做 ...

  9. java面试笔试试题http://www.jobui.com/mianshiti/it/java/6827/

    一.判断题(每题1分,共10分)1.Applet是一种特殊的Panel,它是Java Applet程序的最外层容器.()2.Java的源代码中定义几个类,编译结果就生成几个以.class为后缀的字节码 ...

  10. C#读写者线程(用AutoResetEvent实现同步)

    转载自 http://blog.csdn.net/livelylittlefish/article/details/2735440 本博客(http://blog.csdn.net/livelylit ...