QML 从无到有 3 (自动更新)
新的需求出来啦,需要自动更新功能,不怕程序升级了。
自动更新,QML不好写,需要c++来辅助,这里就涉及QML中调用c++功能(这里就不写了,百度一下,很多)。
思路:获取版本》下载程序》安装程序
第一步,获取版本信息,可以通过XMLHttpRequest获取最新版本。
第二步,下载程序,通过Qt c++的QtNetwork:
头文件:
#ifndef ZRDOWNLOAD_H
#define ZRDOWNLOAD_H #include <QObject>
#include <QtNetwork/QNetworkAccessManager>
#include <QFile>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <QIODevice> class ZRDownload : public QObject
{
Q_OBJECT
Q_PROPERTY(QString url READ GetUrl WRITE SetUrl)
Q_PROPERTY(QString fileName READ GetFileName WRITE SetFileName)
public:
explicit ZRDownload(QObject *parent = );
~ZRDownload(); QString GetUrl();
void SetUrl(QString u);
QString GetFileName();
void SetFileName(QString fn);
private:
QString url;
QString fileName;
QFile *file;
QNetworkAccessManager *accessManager;
QNetworkRequest request;
QNetworkReply *reply; signals:
void progressPosition(double pre); //更新进度条信号
void downloadFinished(); //结束信号 protected slots:
void httpDownload();
void replyFinished(QNetworkReply*reply);
void onDownloadProgress(qint64 bytesSent,qint64 bytesTotal);
void onReadyRead();
}; #endif // ZRDOWNLOAD_H
CPP文件:
#include "zrdownload.h"
#include <QDebug> ZRDownload::ZRDownload(QObject *parent) : QObject(parent)
{
accessManager = NULL;
reply = NULL;
}
ZRDownload::~ZRDownload()
{
} QString ZRDownload::GetUrl()
{
return url;
} void ZRDownload::SetUrl(QString u)
{
url = u;
} QString ZRDownload::GetFileName()
{
return fileName;
} void ZRDownload::SetFileName(QString fn)
{
fileName = fn;
} void ZRDownload::httpDownload(){ file=new QFile(fileName);
bool suc = file->open(QIODevice::WriteOnly);//只读方式打开文件 accessManager=new QNetworkAccessManager(this); request.setUrl(url); /******************设置http的header***********************/
// request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data");
// request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");
// request.setRawHeader("Content-Disposition","form-data;name='doc';filename='a.txt'");
//request.setHeader(QNetworkRequest::ContentLengthHeader,post_data.length()); reply=accessManager->get(request);//通过发送数据,返回值保存在reply指针里.
connect(accessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));//finish为manager自带的信号,replyFinished是自定义的
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT( onDownloadProgress(qint64 ,qint64 )));//download文件时进度
connect((QObject *)reply, SIGNAL(readyRead()),this, SLOT(onReadyRead())); }
/***************响应结束**************************/
void ZRDownload::replyFinished(QNetworkReply *reply){
//获取响应的信息,状态码为200表示正常
QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QByteArray bytes = reply->readAll(); //获取字节
QString result(bytes); //转化为字符串 //无错误返回
if(reply->error() == QNetworkReply::NoError)
{
QByteArray bytes = reply->readAll(); //获取字节
QString result(bytes); //转化为字符串 file->flush();
file->close();
delete file;
file=NULL;
}
else
{
//处理错误
} reply->deleteLater();//要删除reply,但是不能在repyfinished里直接delete,要调用deletelater;
reply=NULL; accessManager->deleteLater();
accessManager=NULL; downloadFinished();
} /***********更新进度条*************/
void ZRDownload::onDownloadProgress(qint64 bytesSent, qint64 bytesTotal){ double pre = double(bytesSent)/bytesTotal; progressPosition(pre);
} void ZRDownload::onReadyRead(){ file->write(reply->readAll());
}
上面的代码也是修改网上的代码,增加了QML调用的信息。
注意:项目文件pro中需要添加 QT += network
main.cpp:
添加 qmlRegisterType<ZRDownload>("xxx.xxx.ZRDownload", 1, 0, "ZRDownload");
QML调用:
ZRDownload{
id:download
url:"http://xxx.xxx.com/xx.apk"
fileName:""
onProgressPosition:progressBar.update(pre) //自定义更新进度条函数
onDownloadFinished: {
//下载完成
}
} //启动下载
download.fileName=getAppPath();//设置保存目录,pc和安卓不同
download.httpDownload();
第三步,安装程序:
不同平台,安装程序的代码也不同,PC平台使用QProcess启动安装程序,安卓平台通过QAndroidJniObject调用Activity实现。下面是代码:
#ifndef ZRINSTALL_H
#define ZRINSTALL_H #include <QObject>
#include <QString> class ZRInstall : public QObject
{
Q_OBJECT
Q_PROPERTY(QString fileName WRITE SetFileName)
public:
explicit ZRInstall(QObject *parent = ); void SetFileName(QString fn);
signals: public slots:
void install();
private:
QString m_FileName;
}; #endif // ZRINSTALL_H
头文件
#include "zrinstall.h"
#include <QDebug>
#if defined(Q_OS_ANDROID)
#include <QtAndroid>
#else
#include <QProcess>
#endif ZRInstall::ZRInstall(QObject *parent) : QObject(parent)
{ } void ZRInstall::SetFileName(QString fn)
{
m_FileName = fn;
} void ZRInstall::install()
{
#if defined(Q_OS_ANDROID)
//安装apk
QAndroidJniObject path = QAndroidJniObject::fromString("file://"+m_FileName);
QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", path.object<jstring>());
QAndroidJniObject param = QAndroidJniObject::getStaticObjectField<jstring>("android/content/Intent", "ACTION_VIEW");
QAndroidJniObject intent("android/content/Intent","(Ljava/lang/String;)V",param.object<jstring>());
QAndroidJniObject type = QAndroidJniObject::fromString("application/vnd.android.package-archive");
QAndroidJniObject result = intent.callObjectMethod("setDataAndTypeAndNormalize", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/Intent;", uri.object<jobject>(), type.object<jstring>());
QtAndroid::startActivity(intent, , );
#else
//qDebug()<<m_FileName;
QProcess * proc = new QProcess();
proc->startDetached(m_FileName,QStringList());
delete proc;
#endif
}
CPP文件
android{
QT += androidextras
}
项目文件pro
调用就不写了,可以参考上面download。
这样整个版本自动更新就写好了,有一些细节自己需要注意,如下载安装文件不同,安装目录不同。
QML 从无到有 3 (自动更新)的更多相关文章
- 解析大型.NET ERP系统 自动更新
C/S架构的应用程序需要支持自动更新功能,当新版本程序发布后,正在运行的客户端能检测到新版本的程序,通知用户是否下载更新.工作以来参与过几个自动更新模块的设计与维护,撰文总结自动更新模块设计与实现. ...
- 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常
在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...
- 分析nuget源码,用nuget + nuget.server实现winform程序的自动更新
源起 (个人理解)包管理最开始应该是从java平台下的maven开始吧,因为java的开发大多数是基于开源组件开发的,一个开源包在使用时很可能要去依赖其他的开源包,而且必须是特定的版本才可以.以往在找 ...
- ClickOnce部署(2):自动更新
上次我们说了如何用最基本的方式用ClickOnce技术部署应用程序项目,本篇我们来认识一下如何让应用程序具备自动更新的功能. 我们依然通过实例来学习. 第一步,随便建一个应用程序项目,至于是控制台.W ...
- Android接入百度自动更新SDK
一:前言 公司的app,上传到百度应用市场,然后说必须要接入百度的自动更新sdk才能上架,于是从百度官网上去下载jar包,下载的时候必须要带上数据统计,如果使用自动的jar包,还需要带上广告联盟,坑爹 ...
- C#之tcp自动更新程序
.NETTCP自动更新程序有如下几步骤: 第一步:服务端开启监听 ServiceHost host; private void button1_Click(object sender, EventAr ...
- 使用 SVN Hook 实现服务器端代码自动更新
之前的做法是客户端提交代码之后,再去服务器端项目中 svn up 一下来更新代码,让服务器端的项目更新到最新版本.可以编写一个 post-commit 钩子脚本来实现服务器端代码的自动更新,它在 SV ...
- git 远程版本库,github提供服务原理,git自动更新发送邮件
1.安装好Linux,安装好Git(192.168.1.239) 2.创建一个用户zph(让此用户提供git on server),密码设置为12345678 # useradd zph # pass ...
- 【原创】我所理解的自动更新-APP发布与后台发布
发布后台 创建渠道:添加新的渠道,设置渠道名称,自动生成渠道id. 查看渠道:查看渠道基本信息,渠道app版本号,资源版本号,是否开启更新. 创建/更新APP:选择打包ios,androi ...
随机推荐
- RabbitMQ + PHP (一)入门与安装
RabbitMQ: 1.是实现AMQP(高级消息队列协议)的消息中间件的一种. 2.主要是为了实现系统之间的双向解耦而实现的.当生产者大量产生数据时,消费者无法快速消费,那么需要一个中间层.保存这个数 ...
- 基于Vue2.0的单页面开发方案
2016的最后一天,多多少少都应该总结一下这一年的得失,哪里做的好,哪里需要改进,记一笔,或许将来会用到呢. 毕业差不多半年了,一直是一个人在负责公司项目的前端开发与维护,当时公司希望前后端分离,提高 ...
- JavaScript基础
JavaScript基础 JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处 ...
- iOS开发 适配iOS10
2016年9月7日,苹果发布iOS 10.2016年9月14日,全新的操作系统iOS 10将正式上线. 作为开发者,如何适配iOS10呢? 1.Notification(通知) 自从Notificat ...
- 在MySQL数据库中创建一个完整的表
1.登陆成功后,首先进入某一个数据库 (不是指数据库服务器) use t1; //t1是数据库名 如图所示: 2.在此数据库中建立数据库表 2.1 先建立表结构(可以理解为表的列名,也就是字段名)在实 ...
- (转) 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)
原文地址: http://www.cnblogs.com/lyhabc/p/4682986.html 这一篇是从0开始搭建SQL Server AlwaysOn 的第三篇,这一篇才真正开始搭建Alwa ...
- 【腾讯Bugly干货分享】跨平台 ListView 性能优化
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/FbiSLPxFdGqJ00WgpJ94yw 导语 精 ...
- H5嵌入原生开发小结----兼容安卓与ios的填坑之路
一开始听说开发H5,以为就是做适配现代浏览器的移动网页,心想不用管IE了,欧也.到今天,发现当初too young too simple,兼容IE和兼容安卓与IOS,后者让你更抓狂.接下来数一下踩过的 ...
- C++虚函数和函数指针一起使用
C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...
- Azure 上通过 SendGrid 发送邮件
SendGrid 是什么? SendGrid 是架构在云端的电子邮件服务,它能提供基于事务的可靠的电子邮件传递. 并且具有可扩充性和实时分析的能力.常见的用例有: 自动回复用户的邮件 定期发送信息给用 ...