chromium-cronet库的编译用于Android和ios平台实现quic协议

2023-11-03

 

chromium-cronet文档 原文文档写的已经很清楚,最好还是参考官方文档,避免由于版本原因导致的问题。

Cronet开发者文档:https://developer.android.com/guide/topics/connectivity/cronet

博客中的git地址:https://github.com/bgylde/chromium-cornet

环境配置

  1. chromium源码环境;
  2. 已经配置好相关环境,安装好相关依赖;
  3. 这里是在linux环境下对Android库的编译,在macos环境下会直接编译为ios平台库;

编译开发和debug环境的Cronet库

Android / IOS build

$ ./components/cronet/tools/cr_cronet.py gn --out_dir=out/Cronet

如果build主机是在linux环境下,build的是android的库。如果build主机是macOS,build的是ios库。

$ ninja -C out/Cronet cronet_package

编译Cronet库,最终文件可以在out/Cronet/cornet中寻找。

使用cronet库

  1. 创建CronetEngine,最好整个应用使用一个CronetEngine,这里可以理解为OkHttpClient;
  2. 创建自己的线程池给Cronet使用,Cronet的网络请求都会在线程池中,避免主线程阻塞;
  3. 实现回调UrlRequest.Callback,在UrlRequest调用start以后,网络请求开始,之后产生请求回调;
public class UrlRequestCallback extends UrlRequest.Callback {

    private static final String TAG = "UrlRequestCallback";

    private long startTime;
    private ByteBuffer mByteBuffer = ByteBuffer.allocateDirect(102400);
    private ByteArrayOutputStream mBytesReceived = new ByteArrayOutputStream();
    private WritableByteChannel mReceiveChannel = Channels.newChannel(mBytesReceived);

    @Override
    public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
        LogUtils.i(TAG, "onRedirectReceived method called.");
        // You should call the request.followRedirect() method to continue
        // processing the request.
        request.followRedirect();
    }

    @Override
    public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
        LogUtils.i(TAG, "onResponseStarted method called.");
        // You should call the request.read() method before the request can be
        // further processed. The following instruction provides a ByteBuffer object
        // with a capacity of 102400 bytes to the read() method.
        //ByteBuffer byteBuffer = ByteBuffer.allocateDirect(102400);
        startTime = System.currentTimeMillis();
        request.read(mByteBuffer);
    }

    @Override
    public void onReadCompleted(UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
        LogUtils.i(TAG, "onReadCompleted method called.");
        // You should keep reading the request until there's no more data.

        try {
            byteBuffer.flip();
            mReceiveChannel.write(byteBuffer);
            byteBuffer.clear();
        } catch (IOException e) {
            LogUtils.e(TAG, e);
        }

        request.read(mByteBuffer);
    }

    @Override
    public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
        LogUtils.i(TAG, "onSucceeded method called: " + info.toString());
        LogUtils.d(TAG, "cost time: " + (System.currentTimeMillis() - startTime) + " ms");
        //byte[] bytes = mBytesReceived.toByteArray();
        String receivedData = null;
        try {
            receivedData = mBytesReceived.toString("GBK");
        } catch (UnsupportedEncodingException e) {
            LogUtils.e(TAG, e);
        }

        final String url = info.getUrl();
        final String text = "Completed " + url + " (" + info.getHttpStatusCode() + ")";
        //LogUtils.i(TAG, "text: " + text);
        //LogUtils.i(TAG, "receivedData: " + receivedData);
    }

    @Override
    public void onFailed(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo, CronetException e) {
        //LogUtils.d(TAG, "url: " + urlResponseInfo.getUrl());
        LogUtils.e(TAG, "onFailed method called.", e);
    }

    @Override
    public void onCanceled(UrlRequest request, UrlResponseInfo info) {
        LogUtils.d(TAG, "onCanceled method called.");
    }
}
  • onRedirectReceived 顾名思义,是重定向的回调,这里直接选择继续访问重定向的地址,也可以调用UrlRequest的cancel方法,取消访问;
  • onResponseStarted 从google文档上面来看是请求完header以后开始请求body部分会回调这里,每次请求只会回调一次;
  • onReadCompleted 这是读取body一定数据时会回调这个方法,这里request.read读取的数据不一定会填满缓冲区,请求生命周期中会有多次回调发生;
  • onSucceeded 最终请求成功回调,可以作为数据处理阶段;
  • onFailed 请求失败回调,例如网络不通,或者没有网络访问权限之类的错误;
  • onCanceled 请求取消回调,只会在cancel后才会回调,回调这个意味着整个请求完成;

https://ssl.gstatic.com/gb/images/qi2_00ed8ca1.png 实现quic访问,可作为测试地址。

 这是通过抓包看到的quic协议,进一步的性能对比就需要自己搭建一个支持quic协议的服务器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

chromium-cronet库的编译用于Android和ios平台实现quic协议 的相关文章

  • Android - 保存动态更改布局的状态

    我有一个布局 用户可以在其中添加按钮并将其放置在他们想要的位置 我想允许用户保存他们的布局 以便下次打开应用程序时加载它 有谁知道我是否可以将文件保存到 SD 卡上 或者 我可以使用某种layout getXml 方法并将其放入我的应用程序
  • BottomNavigationView - 如何获取选定的菜单项?

    我使用BottomNavigationView来切换片段 如何获取当前选定的菜单项 以防止重新打开片段 BottomNavigationView bottomNavigationView BottomNavigationView findV
  • getItem 与 getItemAtPosition

    有两种方法可以获取列表视图中的选定项目 list getAdapter getItem position list getItemAtPosition position 我的问题是 哪一种是首选的做法 我见过人们同时使用这两种方法 您可以使
  • GCM 向主题发送消息:TOO_MANY_TOPICS 错误

    以前 GCM 每个应用程序有 100 万个主题订阅的限制 我发现他们现在已经取消了这一限制 基于发布 订阅模型 主题消息支持 每个应用程序无限订阅 https developers google com cloud messaging to
  • 从 Throwable 获取错误代码 - Android

    我怎样才能从错误代码可投掷 https developer android com reference java lang Throwable html public void onFailure Throwable exception 我
  • Android SoundPool 堆限制

    我正在使用 SoundPool 加载多个声音剪辑并播放它们 据我所知 它的功能 100 正确 但在 load 调用期间 我的日志中充斥着以下内容 06 09 11 30 26 110 ERROR AudioCache 23363 Heap
  • 在自定义对象中创建时粘性服务不会重新启动

    我有一个具有绑定服务的单例对象 我希望它重新启动 当我从启动器启动应用程序时 单例对象将初始化并绑定到这个现有的服务实例 以下是在单例中创建和绑定服务的代码 public class MyState private static MySta
  • 如何从 SQLite 获取记录总数

    我正在尝试从 Sqlite DB 获取行的总数 以下是我想要做的代码片段 我不知道我在这里做错了什么 public static int getTotalCount Context context Cursor c null try c g
  • RxJava、Proguard 和 sun.misc.Unsafe

    我有以下问题RxJava 1 1 0 使用时Proguard 我没有更改 RxJava 版本或其 pro文件 但更新后OkHttp我无法编译使用Proguard因为我有关于sun misc Unsafe不在场 rxJava pro keep
  • 从 Firebase 数据库填充微调器

    public class MainActivity extends AppCompatActivity DatabaseReference reference Spinner areaSpinner ArrayList
  • Android 版 Robotium - solo.searchText () 不起作用

    我在使用 Robotium 时遇到 searchText 函数问题 我正在寻找这个字符串
  • Android相机意图:如何获取全尺寸照片?

    我正在使用意图来启动相机 Intent cameraIntent new Intent android provider MediaStore ACTION IMAGE CAPTURE getParent startActivityForR
  • Android Studio:无法启动守护进程

    当我尝试在 Android Studio 中导入 gradle 项目时 遇到以下错误 Unable to start the daemon process This problem might be caused by incorrect
  • 材质设计图标颜色

    应该是哪种颜色 暗 材质图标 在官方文档上 https www google com design spec style icons html icons system icons https www google com design s
  • 如何将设备连接到Eclipse?

    我无法解决这个简单的问题 我正在尝试通过 USB 电缆将我的设备连接到 Eclipse 在我的 PC 上 我已经安装了 Eclipse 和 Android SDK 并且在模拟器上运行该程序运行良好 我已在我的电脑上下载并安装了 Samsun
  • 在 Android 上按下电源按钮时,如何防止先调用 onDestroy() 再调用 onCreate()

    我正在记录每个 onCreate 和 onDestroy 调用 我发现 一旦我单击 Android 上的电源按钮 以及模拟器上的电源按钮 我的活动中就会拨打电话 gt onDestroy gt onCreate 这会杀死我的游戏 然后立即从
  • 当手机旋转(方向改变)时如何最好地重新创建标记/折线

    背景 开发一个使用 Android Google Map v2 的本机 Android 应用程序 使用android support v4 app FragmentActivity 在 Android v2 2 上运行 客观的 在更改手机方
  • Android中webview的截图方法

    我在 webview 中的 html5 canvas 上画了一些线 并尝试使用下面的代码截取 webview 的屏幕截图 WebView webView WebView findViewById R id webview webView s
  • Android:有没有办法以毫安为单位获取设备的电池容量?

    我想获取设备的电池容量来进行一些电池消耗计算 是否可以以某种方式获取它 例如 三星 Galaxy Note 2 的电池容量为 3100mAh 谢谢你的帮助 知道了 在 SDK 中无法直接找到任何内容 但可以使用反射来完成 这是工作代码 pu
  • 无法运行我的应用程序,要求选择 Android SDK

    今天我已经安装了Android Studio 金丝雀 1 现在我无法运行我的应用程序 将出现以下对话框 我已经通过 文件 gt 项目结构 gt Android SDK 位置 设置了正确的 SDK 位置 期待您的帮助来解决这个问题 警告对话框

随机推荐

  • UART串口的8倍过采样和16倍过采样原理

    由于在空闲状态时 传送线为逻辑 1 状态 而数据的传送总是以一个起始位 0 开始 所以当接收器检测到一个从 1 向 0 的跳变时 便视为可能的起始位 要排除干扰引起的跳变 起始位被确认后 就知道发送器已开始发送 接收器就可以按这个数据通信格
  • 利用SSM搭建web项目

    下面给大家介绍一下 ssm的搭建和使用 7步搞定框架搭建 SSM所需要的jar包下载地址 http download csdn net download baidu 32492845 10126554 1 创建数据库 DROP TABLE
  • 性能测试怎么做?性能测试策略配套适用场景,打通性能测试...

    目录 导读 前言 一 Python编程入门到精通 二 接口自动化项目实战 三 Web自动化项目实战 四 App自动化项目实战 五 一线大厂简历 六 测试开发DevOps体系 七 常用自动化测试工具 八 JMeter性能测试 九 总结 尾部小
  • 网易2018校园招聘编程题真题集合

    1 8 编程题 魔法币 include
  • linux fedora 桌面环境,为Fedora 30系统安装Deepin桌面环境(DDE)

    Fedora 30已经新增两个桌面环境选项 DeepinDE 和 Pantheon Desktop 所以除GNOME KDE Plasma 和 Xfce 之外 因为Deepin桌面环境现在可以在Fedora 30存储库中使用 用户现在还可以
  • ChatGPT应用场景: 基于对话生成的智能客服系统

    关于ChatGPT 今天小编简单说下用在客服服务的要点 ChatGPT可以用于开发基于对话生成的智能客服系统 帮助企业提供高效 便捷 满意的在线客服服务 从而提升客户体验和满意度 以下是ChatGPT应用于智能客服系统的一些场景 1 自动回
  • 基于redis分布式缓存实现

    在网上找了些redis搭建集群的资料 分享给大家 可以仔细看看 了解redis主从复制的逻辑 以及如何构建redis集群 Redis复制流程概述 Redis的复制功能是完全建立在之前我们讨论过的基于内存快照的持久化策略基础上的 也就是说无论
  • flask.ext 的那些事

    偶然发现 在pycharm 使用alter enter 自动修复 未导入的外部模块时 推荐的是 flask ext 包名 的形式 如下例 from flask ext migrate import Migrate MigrateComman
  • 分立元件搭建自举电路解析-高端mos驱动

    分立元件搭建自举电路 上桥mos驱动 高端MOS为什么要自举电路 自举电容 分立元件搭建自举电路 高端MOS为什么要自举电路 众所周知MOS是电压型驱动 只有G极比S极高一个开启电压Vth之后 MOS才会导通 这里指NMOS 但是如下图 我
  • JQuery 页面加载完成后执行事件

    一 document ready function code 二 jQuery document ready function code 三 window nl ad function code 四 将jquery代码放入body的后面 这
  • 使用OpenCV/python进行双目测距

    在做SLAM时 希望用到深度图来辅助生成场景 所以要构建立体视觉 在这里使用OpenCV的Stereo库和python来进行双目立体视觉的图像处理 立体标定 应用标定数据 转换成深度图 标定 在开始之前 需要准备的当然是两个摄相头 根据你的
  • 什么是 agent

    agent 是任何通过sensor感知其环境并通过actuators在此环境中作出行动的东西 比如人agent sensor 是眼睛 耳朵 以及其他器官 actuators 是手 腿 声道等 比如机器人agent sensor 是摄像头 红
  • JVM系列-第8章-执行引擎

    文章目录 toc 执行引擎 执行引擎概述 执行引擎概述 执行引擎工作过程 Java代码编译和执行过程 解释执行和即时编译 什么是解释器 什么是JIT编译器 机器码 指令 汇编语言 机器码 指令和指令集 汇编语言 高级语言 字节码 C C 源
  • Java使用图片压缩工具压缩图片的两种方法

    上代码 pom xml
  • 单元测试是什么?为什么要做单元测试?

    背锅侠 一个有个性的订阅号 1 单元测试是什么 单元测试是开发者编写的一小段代码 用于检验被测代码的一个很小的 很明确的功能是否正确 通常而言 一个单元测试是用于判断某个特定条件 或者场景 下某个特定函数的行为1 长按图片识别二维码 入群
  • [Qt 教程之Widgets模块] —— QButtonGroup抽象容器

    Qt系列教程总目录 文章目录 0 QButtonGroup简介 1 创建QButtonGroup 2 成员函数与信号 3 示例 3 1 为按钮组添加按钮 3 2 为按钮设置id 3 3 按钮组中按钮的互斥状态 3 4 获取组内所有按钮 3
  • 开源图像和视频编辑软件汇总

    1 Belender http www blender org Blender 是一套 三维绘图 及 渲染 软件 它具有跨平台的特性 支持 FreeBSD IRIX GNU Linux Microsoft Windows Mac OS X
  • django自带的序列化组件

    目录 sweetalert前端插件 django自带的序列化组件 简易分页器 带有页码的分页器 优化后的版本 模块代码 后端代码 Forms组件 校验数据 渲染标签 展示信息 widgets 注意 sweetalert前端插件 https
  • 计算机组成原理 及CPU,硬盘,内存三者的关系

    电脑之父 冯 诺伊曼 提出了组成计算机的五大部件 输入设备 输出设备 存储器 运算器和控制器 下图为 现在我们电脑的 键盘鼠标 显示器 机箱 音响等等 这里显示器为比较老的CRT显示器 现在一般都成功了液晶显示器 回想一下 在玩电脑的时候
  • chromium-cronet库的编译用于Android和ios平台实现quic协议

    chromium cronet文档 原文文档写的已经很清楚 最好还是参考官方文档 避免由于版本原因导致的问题 Cronet开发者文档 https developer android com guide topics connectivity