七夕情人节到了,各种App都要忙着上新,抓住互联网产品的节日热点,结合应用的类别进行活动营销。比如购物类App会在节日进行大促;旅游类App会推出各种优惠活动;短视频和拍照App会推出各种节日限定特效、专属贴纸等。
尤其是游戏类App,具有较强的社交属性,在节日热点一般都会进行版本更新,上线新皮肤新场景等,涉及到的内容很多,有时候版本更新包的资源太大,导致用户更新时等待时间长,影响运营推广和用户下载体验。这时只需要接入HMS Core Network Kit,就可大幅提升资源下载速率。
HMS Core Network Kit是一款网络基础服务套件,聚合远场网络通信优秀实践,辅以RESTful、文件上传/下载等场景化接口,为您提供简单易用、低时延、高吞吐和高安全的端云传输通道。除了可以提升文件上传/下载的速度和成功率,还可以在URL访问网络场景中提升网络访问速度,在弱网环境中可减少无效网络等待时间,且支持网络平滑迁移。

从图中可以看出,集成Network Kit后下载速度提升约40%。
HMS Core Network Kit首先在QUIC 协议上叠加自研的大文件拥塞控制算法,通过高效的并发数据流,有效提升弱网下的吞吐量;其次,智能分片针对不同机器环境设置不同分片阈值及分片数,尽可能提升下载速度;同时也支持多任务并发执行及管理,任务断点续传,提升下载成功率。适用于与新版本升级、补丁升级、新场景地图等相关资源加载、活动图片、视频下载等。
在进行开发之前,您需要完成必要的开发准备工作,详情可见Network开发指导文档。
SDK集成示例代码如下:
dependencies {
// 使用Network Kit的网络请求功能
implementation 'com.huawei.hms:network-embedded: 6.0.0.300'
// 使用Network Kit的文件上传/下载功能
implementation 'com.huawei.hms:filemanager: 6.0.0.300'
}
因为Network Kit使用了Java 8的新特性,如:Lambda表达式、静态接口方法等。所以Network Kit均需要为Gradle添加Java 8的环境编译约束。
在“compileOptions”中添加如下编译配置。
android{
compileOptions{
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
文件上传功能可以通过如下操作实现。详细开发过程和代码实现可以参见codelab(文件上传/下载集成)和示例代码。
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1000);
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1001);
}
}
UploadManager upManager = (UploadManager) new UploadManager
.Builder("uploadManager")
.build(context);
Map<String, String> httpHeader = new HashMap<>();
httpHeader.put("header1", "value1");
Map<String, String> httpParams = new HashMap<>();
httpParams.put("param1", "value1");
// 替换成您需要上传的目的地址。
String normalUrl = "https://path/upload";
// 替换成您需要上传的文件的地址。
String filePath1 = context.getString(R.string.filepath1);
// 替换成您需要上传的文件的地址。
String filePath2 = context.getString(R.string.filepath2);
// 构造POST请求对象。
try{
BodyRequest request = UploadManager.newPostRequestBuilder()
.url(normalUrl)
.fileParams("file1", new FileEntity(Uri.fromFile(new File(filePath1))))
.fileParams("file2", new FileEntity(Uri.fromFile(new File(filePath2))))
.params(httpParams)
.headers(httpHeader)
.build();
}catch(Exception exception){
Log.e(TAG,"exception:" + exception.getMessage());
}
FileUploadCallback callback = new FileUploadCallback() {
@Override
public BodyRequest onStart(BodyRequest request) {
// 文件上传开始时回调此方法。
Log.i(TAG, "onStart:" + request);
return request;
}
@Override
public void onProgress(BodyRequest request, Progress progress) {
// 文件上传进度变化时回调到此方法。
Log.i(TAG, "onProgress:" + progress);
}
@Override
public void onSuccess(Response<BodyRequest, String, Closeable> response) {
// 文件上传成功时回调此方法。
Log.i(TAG, "onSuccess:" + response.getContent());
}
@Override
public void onException(BodyRequest request, NetworkException exception, Response<BodyRequest, String, Closeable> response) {
// 文件上传过程中网络发生异常,或请求被取消时回调此方法。
if (exception instanceof InterruptedException) {
String errorMsg = "onException for canceled";
Log.w(TAG, errorMsg);
} else {
String errorMsg = "onException for:" + request.getId() + " " + Log.getStackTraceString(exception);
Log.e(TAG, errorMsg);
}
}
};
当Result的getCode方法获取的返回值与静态变量Result.SUCCESS一致则文件上传任务启动成功。
Result result = upManager.start(request, callback);
// 上传任务启动是否成功,可以通过Result的getCode()方法获取的返回值是否与静态变量Result.SUCCESS一致来判断。
if (result.getCode() != Result.SUCCESS) {
Log.e(TAG, result.getMessage());
}
文件上传状态改变时,步骤4创建的FileUploadCallback对象的不同回调方法将被调用。
• 文件上传开始时,onStart方法会被调用。
• 文件上传进度改变时,onProgress方法会被调用,并可通过解析回调的Progress对象,获取上传进度。
• 文件上传任务发生异常时,onException方法会被调用。
文件上传成功后会回调到步骤4创建的FileUploadCallback请求回调对象的onSuccess方法。
文件下载功能可以通过如下操作实现。详细开发过程和代码实现请参见codelab(文件上传/下载集成)和示例代码。
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1000);
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1001);
}
}
DownloadManager downloadManager = new DownloadManager.Builder("downloadManager")
.build(context);
// 替换成您需要下载的资源地址。
String normalUrl = "https://gdown.baidu.com/data/wisegame/10a3a64384979a46/ee3710a3a64384979a46542316df73d4.apk";
// 替换成您想要保存的目的地址。
String downloadFilePath = context.getExternalCacheDir().getPath() + File.separator + "test.apk";
// 构造GET请求体对象。
GetRequest getRequest = DownloadManager.newGetRequestBuilder()
.filePath(downloadFilePath)
.url(normalUrl)
.build();
FileRequestCallback callback = new FileRequestCallback() {
@Override
public GetRequest onStart(GetRequest request) {
// 文件下载开始时回调此方法。
Log.i(TAG, "activity new onStart:" + request);
return request;
}
@Override
public void onProgress(GetRequest request, Progress progress) {
// 文件下载进度变化时回调此方法。
Log.i(TAG, "onProgress:" + progress);
}
@Override
public void onSuccess(Response<GetRequest, File, Closeable> response) {
// 文件下载成功时回调到此方法。
String filePath = "";
if (response.getContent() != null) {
filePath = response.getContent().getAbsolutePath();
}
Log.i(TAG, "onSuccess:" + filePath);
}
@Override
public void onException(GetRequest request, NetworkException exception, Response<GetRequest, File, Closeable> response) {
// 文件下载过程中网络发生异常,或请求被暂停、取消时回调此方法。
if (exception instanceof InterruptedException) {
String errorMsg = "onException for paused or canceled";
Log.w(TAG, errorMsg);
} else {
String errorMsg = "onException for:" + request.getId() + " " + Log.getStackTraceString(exception);
Log.e(TAG, errorMsg);
}
}
};
当Result的getCode方法获取的返回值与静态变量Result.SUCCESS一致则文件下载任务启动成功。
Result result = downloadManager.start(getRequest, callback);
if (result.getCode() != Result.SUCCESS) {
// 当通过result获取到的值为Result.SUCCESS时,则下载任务启动成功,否则启动失败。
Log.e(TAG, “start download task failed:” + result.getMessage());
}
文件下载状态改变时,步骤4创建的FileRequestCallback请求回调对象的不同方法将被调用。
• 文件开始下载时,onStart方法会被调用。
• 文件下载进度改变时,onProgress方法会被调用,并可通过解析回调的Progress对象,获取下载进度。
• 文件下载任务发生异常时,onException方法会被调用。
文件下载成功后会回调到步骤4创建的FileRequestCallback请求回调对象的onSuccess方法,并可根据您设置的下载路径在手机内存中查看到您下载的文件。
了解更多详情>>
访问华为开发者联盟官网
获取开发指导文档
华为移动服务开源仓库地址:GitHub、Gitee
关注我们,第一时间了解 HMS Core 最新技术资讯~
技术选型1,前端小程序原生MINA框架cssJavaScriptWxml2,管理后台云开发Cms内容管理系统web网页3,数据后台小程序云开发云函数云开发数据库(基于MongoDB)云存储4,人脸识别算法基于百度智能云实现人脸识别一,用户端效果图预览老规矩我们先来看效果图,如果效果图符合你的需求,就继续往下看,如果不符合你的需求,可以跳过。1-1,登录注册页可以看到登录页有注册入口,注册页如下我们的注册,需要管理员审核,审核通过后才可以正常登录使用小程序1-2,个人中心页登录成功以后,我们会进入个人中心页我们在个人中心页可以注册人脸,因为我们做人脸识别签到,需要先注册人脸才可以进行人脸比对,进
文章目录⭐️赠书活动-《从程序员到架构师》⭐️编辑推荐⭐️作者简介⭐️赠书活动→获奖名单⭐️赠书活动-《从程序员到架构师》内容简介:《从程序员到架构师:大数据量、缓存、高并发、微服务、多团队协同等核心场景实战》分为数据持久化层场景实战、缓存层场景实战、基于常见组件的微服务场景实战、微服务进阶场景实战和开发运维场景实战5个部分。基于对十余个架构搭建与改造项目的经验总结,介绍了大数据量、缓存、高并发、微服务、多团队协同等核心场景下的架构设计常见问题及其通用技术方案,包含冷热分离、查询分离、分表分库、秒杀架构、注册发现、熔断、限流、微服务等具体需求下的技术选型、技术原理、技术应用、技术要点等内容,将
一、Eolink介绍Eolink是国内起步较早的API全生命周期管理平台。产品能力覆盖API开发-运维-开放交易,实现API研发管理、API快速测试、API自动化测试、API监控、API微服务网关、API对外开放等企业深度场景。使用它能满足我们各种API管理和测试、监控等需求,特别是在自动化测试方面,它提供的建设自动化的功能极大的提高了我们开展自动化接口测试的效率:下面会通过使用Eolink编写一个流程的自动化测试用例来分享讲解一下在Eolink中如何开展自动化及使用教程。目录一、Eolink介绍二、自动化实战1)创建测试项目2)编写用例2.1用户登录2.2创建项目2.3修改项目2.4删除项目
踏浪而行,逐浪而上,MEME全新版本2.0乘势而来,荣耀上线,2022年7月27日,全网最难爆仓平台MEME携全新2.0版正式上线!MEME2.0版本探索更多功能,全面升级重新定义合约,体验感更好,交易更流畅,相比于原来的1.0,MEME2.0版本上线后,全面支持独立钱包与邮箱登陆,全网最难爆仓平台!从追赶者到领航者数字资产和区块链的成长过程,如同观察一个生态系统,一个新兴事物从无到有的蓬勃发展,这带给我们的冲击是前所未有的。尽管生态系统已经拥有相当悠久的历史,但数字化技术的出现改变了一切。不同于传统的生态圈,数字生态系统实现了1+1>2的协同效应。MEME全网首家Web3交互交易平台,去中心
近日,妍丽召开用户运营CDP项目优秀表彰会,以此庆祝妍丽&神策CDP项目上线圆满成功。在此次合作过程中,神策数据凭借着可靠的数据产品与高质量服务,获得了妍丽的充分认可,并荣获妍丽“最佳营销科技服务商”的称号。妍丽成立于1995年,凭借着差异化的商品组合、覆盖全国的直营网络、优质的服务体验等独特优势,始终保持着优秀的品牌口碑和强劲的增长势头,现已通过自有电商体系打造了线上线下的服务闭环,并将持续推进数字化、服务化、平台化能力的建设,努力将妍丽打造成深受消费者喜爱的全球美妆产品和服务提供商。此次CDP项目开始之前,妍丽信息中心CIOGlen团队调研发现,妍丽中台存在诸多数据问题:数据之间相互独立影
💗wei_shuo的个人主页💫wei_shuo的学习社区🌐HelloWorld!『赠书活动|第一期』本期书籍:《分布式中间件核心原理与RocketMQ最佳实践》赠书规则:评论区:点赞|收藏|留言评论区留言:"人生苦短,我用Java"活动截止时间:4月23日赠书数量:1Tip:中奖后博主私信通知|三天内不回复将视为|自动放弃书籍介绍分布式中间件核心原理与RocketMQ实战技术一本通:实战案例+操作步骤+执行效果图,手把手教你吃透分布式中间件技术,轻松实现从小白到大牛的职业跃迁!分布式中间件核心原理与RocketMQ实战技术必修宝典!内容简介本书从分布式系统的基础概念讲起,逐步深入分布式系统中间
本文实现的功能有:1、播放音乐2、自定义流星数量、飞行速度、光晕大小、流星大小3、自定义表白话语 运用到的知识点有:GUI:java实现窗体、Swing。其实JAVASwing的GUI目前企业中已经不用了,主要是一些学校和培训机构用来教导学生写一些游戏、小项目,练练手的。 多线程:让cpu同一时间处理多个任务(本文中涉及到音乐、文字缓慢出现、流星线条移动)效果图:音乐类(其实也可以不用音乐,有些人并不喜欢): importjavazoom.jl.decoder.JavaLayerException;importjavazoom.jl.player.Player;importjava.io.Fi
在JavaScript类中,XMLHttpRequest连接到服务器。服务器正在缓慢地发送数据。这在Chromium中工作正常,但Firefox会在随机时间后(~4秒到~70秒之间)关闭连接。为什么Firefox关闭连接?以及如何避免这种情况?简化的JS代码:varoptions={};options['header']={'Cache-Control':'no-cache,max-age=0','Content-type':'application/octet-stream','Content-Disposition':'inline'};//Getrequestinformatio
我正在尝试创建一个Angular应用程序,其中包含用户在几分钟不活动后需要注销的视频。如果用户正在正常或全屏观看视频,则无需注销。如果选项卡处于非事件状态并且正在播放视频,我需要他在处于非事件状态后注销。 最佳答案 最简单的方法是使用idlejs.它与Angular配合得很好,它包括Typescript的.d.ts绑定(bind)。import{Idle}from'idlejs/dist';//withpredefinedeventson`document`constidle=newIdle().whenNotInteractive
如何在我的网站上使用JavaScript在60秒不活动后将用户重定向到/logout页面?我知道设置计时器或使用元刷新标签很简单:但我只想重定向非事件用户,而不是中断某人的事件session/使用。这可以用JavaScript实现吗? 最佳答案 与其使用不必要的Kbytes插件,您只需要一个像这样的简单函数(请参阅评论中的解释):(function(){constidleDurationSecs=60;//XnumberofsecondsconstredirectUrl='/logout';//Redirectidleusersto