Qt 之 全局的QNetworkAccessManager

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在项目实践中,由于设备要与各种各样的资源通信,所以代码中各个模块都使用了自己的QNetworkAccessManager。
在Qt的官方文档中,有如下说明:

The QNetworkAccessManager class allows the application to send network requests and receive replies
The Network Access API is constructed around one QNetworkAccessManager object, which holds the common configuration and settings for the requests it sends. It contains the proxy and cache configuration, as well as the signals related to such issues, and reply signals that can be used to monitor the progress of a network operation. One QNetworkAccessManager should be enough for the whole Qt application.


翻译下来就是说:

QNetworkAccessManager类允许应用程序发送网络请求和接收回复
网络访问API是围绕一个QNetworkAccessManager对象构建的,该对象保存它发送的请求的公共配置和设置。它包含代理和缓存配置,以及与此类问题相关的信号,以及可用于监控网络操作进度的回复信号。一个QNetworkAccessManager应该足以支持整个Qt应用程序。

就是说qt框架下,建议我们一个app用一个QNetworkAccessManager即可,这样删除和管理也都方便一些。
QNetworkAccessManager不是线程安全的,全局网络访问应该在主线程中(或者通过信号post到主线程);

代码实现

我们设计了一个单例类来实现全局 QNetworkAccessManager的管理
.h文件如下:

#ifndef GLOBALNETWORKMANAGER_H
#define GLOBALNETWORKMANAGER_H
#include <QNetworkAccessManager>

class GlobalNetworkManager : public QObject
{
    
    
public:
    explicit GlobalNetworkManager(QObject *parent = nullptr);

    static void resetNetworkManager();
    static QNetworkAccessManager *getGlobalNetworkManager();
    static QPointer<QNetworkAccessManager> globalManager;   
};

.cpp文件:

#include "globalnetworkmanager.h"
#include <QCoreApplication>
#include <QThread>
#include <QPointer>

QPointer<QNetworkAccessManager> GlobalNetworkManager::globalManager = new QNetworkAccessManager;

GlobalNetworkManager::GlobalNetworkManager(QObject *parent) : QObject(parent)
{
    
    
}

void GlobalNetworkManager::resetNetworkManager()
{
    
    
    if(globalManager)
    {
    
    
        delete globalManager;
        globalManager = NULL;
    }
    globalManager = new QNetworkAccessManager;
    if(globalManager == NULL)
    {
    
    
        qCritical() << "resetNetworkManager error";
    }
}

QNetworkAccessManager *GlobalNetworkManager::getGlobalNetworkManager()
{
    
    
    Q_ASSERT(!qApp || QThread::currentThread() == qApp->thread());
    return globalManager;
}

用法

1.实现说明

  • 通过QPointer保存manager指针,防止悬垂指针;
  • 全局方法getGlobalNetworkManager内的断言保证了调用的正确性:
    QNetworkAccessManager不是线程安全的,全局网络访问应该在主线程中(或者通过信号post到主线程),保证全局的QNetworkAccessManager是在主线程中使用的。
  • 如果确实需要在子线程中进行网络访问,应该在子线程中重新创建一个manager.

2.用法

代码如下(示例):

QNetworkAccessManager *pManager = GlobalNetworkManager::getGlobalNetworkManager();

别的模块中声明的QNetworkAccessManager *指针直接指向全局的QNetworkAccessManager即可。


3. 如何删除QNetworkAccessManager 下的所有请求?

if(globalManager)
{
QList<QNetworkReply *> list = globalManager->findChildren<QNetworkReply *>();
qDebug() << func << “child size=” << list.size();
foreach (QNetworkReply *t, list) {
qDebug() << func << “before abort”;
t->abort();
}
}

猜你喜欢

转载自blog.csdn.net/u011942101/article/details/126918195