Android程序实现自动更新——Android模块化编程
2016-07-07 10:07
399 查看
当初做app更新时,网上找了很多方法,看了很多博客,都没有解决问题。别人的博文,大体只有两种内容。一种是把version.xml放到项目src目录下,如下方法,获得字符流,然后解析成包含version,name,url的HashMap。然后mHashMap.get("version")获得版本比较更新
。
InputStreaminStream=ParseXmlService.class.getClassLoader().getResourceAsStream("version.xml");
ParseXmlServiceservice=newParseXmlService();
mHashMap=service.parseXml(inStream);
这类博文没有解决问题,我们做更新,大都是从网上获取版本信息,而他没有写如何从网上获取version.xml。
还有一类,是这样:
try{
//把version.xml放到网络上,然后获取文件信息
URLurl=newURL(updateVersionXMLPath);
HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
conn.setReadTimeout(5*1000);
conn.setRequestMethod("GET");//必须要大写
InputStreaminputStream=conn.getInputStream();
//解析XML文件。
ParseXmlServiceservice=newParseXmlService();
hashMap=service.parseXml(inputStream);
}catch(Exceptione){
e.printStackTrace();
}
实测,不会得到hashMap。后来猜测,可能是inputStream的格式问题,查了各种字符流,无果。后来又试图把inputStream转成String,转成file。发现在HttpURLConnection这里,程序就跳出了。
废话不多说了,接下来是重点,告诉大家,我是如何解决的:(有没有写到的地方,就是别人写过的,建议有不懂的,可以先看下别人的博文)
首先,服务器上有一个xml文件:http://m.xylbh.cn/android.xml
上诉xml链接,大家可以直接用来测试。apk文件我出于安全考虑,我已混淆。
然后,我建了一个下载xml文件的线程,保存到sd卡(如果没有就是手机内存根目录),命名为android:
然后我会在程序打开,判断更新的时候,启动线程。
这里的serviceVersion我是在构造函数里传过来的
在MainAcitvity的onCreate方法中判断更新的时候,首先打开sd卡中的android文件,转化成String,然后获得version信息(这里方法特别笨,看下边):
onCreate方法中建线程,隔5秒再检查更新
重要的已经说完了,如果下载apk这块不懂,可以参考别人的博文,我不转载。如果有其他问题,请留言。
。
InputStreaminStream=ParseXmlService.class.getClassLoader().getResourceAsStream("version.xml");
ParseXmlServiceservice=newParseXmlService();
mHashMap=service.parseXml(inStream);
这类博文没有解决问题,我们做更新,大都是从网上获取版本信息,而他没有写如何从网上获取version.xml。
还有一类,是这样:
try{
//把version.xml放到网络上,然后获取文件信息
URLurl=newURL(updateVersionXMLPath);
HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
conn.setReadTimeout(5*1000);
conn.setRequestMethod("GET");//必须要大写
InputStreaminputStream=conn.getInputStream();
//解析XML文件。
ParseXmlServiceservice=newParseXmlService();
hashMap=service.parseXml(inputStream);
}catch(Exceptione){
e.printStackTrace();
}
实测,不会得到hashMap。后来猜测,可能是inputStream的格式问题,查了各种字符流,无果。后来又试图把inputStream转成String,转成file。发现在HttpURLConnection这里,程序就跳出了。
废话不多说了,接下来是重点,告诉大家,我是如何解决的:(有没有写到的地方,就是别人写过的,建议有不懂的,可以先看下别人的博文)
首先,服务器上有一个xml文件:
<?xmlversion="1.0"encoding="utf-8"?>
<update>
<version>8</version>
<name>测试1.0.1</name>
<url>http://m.xylbh.cn/xyl.apk</url>
</update>
上诉xml链接,大家可以直接用来测试。apk文件我出于安全考虑,我已混淆。
然后,我建了一个下载xml文件的线程,保存到sd卡(如果没有就是手机内存根目录),命名为android:
privateclassdownloadXmlThreadextendsThread{
@Override
publicvoidrun(){
//TODOAuto-generatedmethodstub
try{
//判断SD卡是否存在,并且是否具有读写权限
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//获得存储卡的路径
Stringsdpath=Environment.getExternalStorageDirectory()+"/";
mSavePath=sdpath+"download";
URLurl=newURL("http://m.xylbh.cn/android.xml");
//创建连接
HttpURLConnectionconn=(HttpURLConnection)url.openConnection();
conn.connect();
//创建输入流
InputStreamin=conn.getInputStream();
Filefile=newFile(mSavePath);
//判断文件目录是否存在
if(!file.exists()){
file.mkdir();
}
FilexmlFile=newFile(mSavePath,"android");
FileOutputStreamfos=newFileOutputStream(xmlFile);
//缓存
bytebuf[]=newbyte[1024];
//写入到文件中
do{
intnumread=in.read(buf);
if(numread<=0){
//下载完成
break;
}
//写入文件
fos.write(buf,0,numread);
}while(!cancelUpdate);//点击取消就停止下载
fos.close();
in.close();
}
}catch(MalformedURLExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
然后我会在程序打开,判断更新的时候,启动线程。
/**
*检查软件是否有更新版本
*/
privatebooleanisUpdate(){
//下载xml
downloadXml();
intversionCode=getVersionCode(mContext);
if(serviceVersion>versionCode){
returntrue;
}
returnfalse;
}
privatevoiddownloadXml(){
newdownloadXmlThread().start();
}
这里的serviceVersion我是在构造函数里传过来的
publicUpdateManager(Contextcontext,intserviceVersion){
this.mContext=context;
this.serviceVersion=serviceVersion;
}
在MainAcitvity的onCreate方法中判断更新的时候,首先打开sd卡中的android文件,转化成String,然后获得version信息(这里方法特别笨,看下边):
privateintgetVersionFromString(){//获得版本信息
Stringxml=readFromFile();
Strings1="0";
if(xml.length()>60){
s1=xml.substring(58,59);//第58到59的数是版本(-_-!)
}
intversion=Integer.parseInt(s1);//注意,不是getInteger()
returnversion;
}
privateStringreadFromFile(){//获得文件转化成的字符串
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
Stringfoldername=Environment.getExternalStorageDirectory().getPath()+"/eryaApp";
Filefolder=newFile(foldername);
if(folder==null||!folder.exists()){
folder.mkdir();
}
Stringsdpath=Environment.getExternalStorageDirectory()+"/"+"download/android";
FiletargetFile=newFile(sdpath);
StringreadedStr="";
try{
if(!targetFile.exists()){
targetFile.createNewFile();
return"NoFileerror";
}else{
InputStreamin=newBufferedInputStream(newFileInputStream(targetFile));
BufferedReaderbr=newBufferedReader(newInputStreamReader(in,"UTF-8"));
Stringtmp;
while((tmp=br.readLine())!=null){
readedStr+=tmp;
}
br.close();
in.close();
returnreadedStr;
}
}catch(Exceptione){
//Toast.makeText(context,e.toString(),Toast.LENGTH_LONG).show();
returne.toString();
}
}else{
//Toast.makeText(context,"未发现SD卡!",Toast.LENGTH_LONG).show();
return"SDCarderror";
}
}
onCreate方法中建线程,隔5秒再检查更新
newHandler().postDelayed(newRunnable(){
@Override
publicvoidrun(){
//TODOAuto-generatedmethodstub
UpdateManagermanager=newUpdateManager(MainActivity.this,getVersionFromString());
manager.checkUpdate();
//Stringtu=XMLParser.getXmlFromUrl(UPDATEVERSIONXMLPATH);
}
},5000);//5秒之后执行
重要的已经说完了,如果下载apk这块不懂,可以参考别人的博文,我不转载。如果有其他问题,请留言。
相关文章推荐
- Android adb一些命令记录
- Android轻量存储值SharedPreference存世实例
- [置顶] Android开发利用shareSDK等第三方分享,弹出的是英文名称。例如Genymotion模拟器
- 可能是讲解 Android 事件分发最好的文章
- Android开发艺术探索读书笔记(第10章 消息机制)
- (浅谈)AndroidStudio中关于多渠道打包相关处理
- Android Studio调试功能使用总结【转】
- Android Data Binding
- Android文件监控FileObserver介绍
- Android APK版本升级设计
- Android中的dispatchTouchEvent()、onInterceptTouchEvent()和onTouchEvent()
- android开发中,ListView中输入框与软键盘的坑
- android数字签名的创建和获取签名信息
- android studio aidl用法详解
- android 判断真机还是虚拟机的方法汇总
- 解决首次启动程序白屏时间过长的问题(针对Android Studio Instant Run)
- android - RadioButton椭圆形背景样式和字体选择时候的颜色
- 解决Mac Androidstudio无法关联源码问题
- Android中线程同步之Mutex与Condtion的用法
- 解决Mac AndroidStudio无法关联源码问题