关于android:Android平台上ABI的确认

ABIABI 即 Application binary interface,是 CPU 与指令集专属的应用程序二进制接口。它定义了一套规定,容许编译好的二进制指标代码能在所有兼容该ABI的操作系统中无需改变就能运行。不同的 Android 设施应用不同的 CPU,而不同的 CPU 反对不同的指令集。 ABI 蕴含以下信息: 可应用的 CPU 指令集(和扩大指令集)。运行时内存存储和加载的字节程序。Android 始终是 little-endian。在利用和零碎之间传递数据的标准(包含对齐限度),以及零碎调用函数时如何应用堆栈和寄存器。可执行二进制文件(例如程序和共享库)的格局,以及它们反对的内容类型。Android 始终应用 ELF。如何重整 C++ 名称。ABI 和指令集NDK 以前反对 ARMv5 (armeabi) 以及 32 位和 64 位 MIPS,但 NDK r17 已不再反对。APK 在门路 /lib/<abi>/lib<name>.so 中寻找 NDK 生成的库。装置利用时,软件包管理器服务将扫描 APK,依照主辅及偏好程序查找共享库,将它们复制到利用的原生库目录 。强制应用特定 ABI 装置 APK,通过 adb install --abi abi-identifier path_to_apk 。armeabi不反对硬件辅助的浮点运算,所有浮点运算都应用编译器的 libgcc.a 动态库中的软件辅助函数。ABI反对的指令集备注armeabi-v7aarmeabi,Thumb-2,VFPv3-D16与 ARMv5/v6 设施不兼容。arm64-v8aAArch64 x86x86 (IA-32),MMX,SSE/2/3,SSSE3不反对 MOVBE 或 SSE4。x86_64x86-64,MMX,SSE/2/3,SSSE3,SSE4.1、4.2,POPCNT ABI 与 CPU大多数 CPU 都反对多种 ABI,其中一个为主 ABI,其余为辅助 ABI。获得最佳性能,最好应用 CPU 的主 ABI。Android 零碎依据特定的零碎属性来决定主辅 ABI。x86设施蕴含ARM模仿层,可能很好地运行ARM类型的so库,但并不保障100%不产生Crash。64位设施(arm64-v8a, x86_64, mips64)可能运行32位的so库。然而以32位模式运行时,会失落专为64位优化过的性能特色(ART, WebView, Media, etc.)。CPU主ABI反对的ABIARMv5armeabiarmeabiARMv7armeabi-v7aarmeabi ,armeabi-v7aARMv8arm64-v8aarmeabi ,armeabi-v7a,arm64-v8ax86x86armeabi ,armeabi-v7a ,x86x86_64x86_64armeabi ,x86 ,x86_64ABI 的零碎属性[ro.product.cpu.abilist] : [arm64-v8a, armeabi-v7a, armeabi][ro.product.cpu.abilist32] : [armeabi-v7a, armeabi][ro.product.cpu.abilist64] : [arm64-v8a]ro.product.cpu.abilist 的值表明以后零碎所反对所有的ABI类型ro.product.cpu.abilist32 和 ro.product.cpu.abilist64 别离示意零碎所反对的32位和64位的 ABI 类型。这些属性值中 ABI 的排序代表着零碎偏好。比方 ro.product.cpu.abilist 的值里 arm64-v8a 排在第一个,就表明如果没有指定,arm64-v8a 就会成为 APP 过程默认启动的关联 ABI。为利用指定 ABI利用编译时,默认状况下,Gradle 会为所有 NDK 反对的 ABI 构建独立的 .so 文件,并将这些文件全副打包到您的利用中。如果您心愿 Gradle 仅构建和打包原生库的特定 ABI 配置,能够在模块级 build.gradle 文件中应用 ndk.abiFilters 标记指定这些配置,如下所示: ...

October 8, 2022 · 2 min · jiezi

关于android:仅需30行代码轻松集成HMS-Core视频编辑服务屏幕录制能力

现如今,手机录屏是必不可少的能力之一。对于游戏畛域作者来说,在平时直播玩游戏、制作攻略、操作集锦时,不不便切屏,这时在游戏内如果有一个录制按钮就能够随时开启,记录下每个精彩霎时,缩小前期剪辑工作量;在直播App中开启一键录屏,不光不便主播后续的账号经营与复盘,用户也能随时截取有意思的片段流传在社交媒体上;在会议App里,通常因为要点太多而来不及记录,此时点击录屏按钮,后续再进行会议的回顾、总结与摘要就非常便当;在上网课时,用户能够间接在课程页面点击录屏,不便及时学习和批注;和亲朋好友视频聊天,也可在社交App里间接点击录制,记录下每个相见的时光。 那么,如何在App里集成录屏能力呢?HMS Core视频编辑服务屏幕录制SDK提供全屏录制手机桌面、实时录音、后盾录制等能力,集成简略,反对自定义录屏告诉、多分辨率抉择、多存储门路抉择等,无需切屏,助力游戏、直播等App疾速、轻松实现录屏性能。 性能特点30行代码就能够简略集成; 反对自定义告诉栏款式; 反对横竖屏切换; 反对多分辨率抉择; 录屏完结后,反对自定义存储地位。 Demo开发步骤1.开发筹备具体筹备步骤可参考华为开发者联盟官网。 2. 集成屏幕录制创立屏幕录制事件监听器HVERecordListener实例,重写监听器的办法。HVERecordListener mHVERecordListener = new HVERecordListener(){ @Override public void onRecordStateChange(HVERecordState recordingStateHve) { // 录屏状态变动 } @Override public void onRecordProgress(int duration) { // 录屏进度 } @Override public void onRecordError(HVEErrorCode err, String msg) { // 录屏谬误 } @Override public void onRecordComplete(HVERecordFile fileHve) { // 录屏实现 }};应用利用上下文和HVERecordListener实例,初始化HVERecord。HVERecord.init(this, mHVERecordListener);3.(可选)创立HVERecordConfiguration.Builder实例,设置录屏配置。 HVERecordConfiguration hveRecordConfiguration = new HVERecordConfiguration.Builder() .setMicStatus(true) .setOrientationMode(HVEOrientationMode.LANDSCAPE) .setResolutionMode(HVEResolutionMode.RES_480P) .setStorageFile(new File("/sdcard/DCIM/Camera")) .build();HVERecord.setConfigurations(hveRecordConfiguration);自定义录屏告诉。在自定义录屏告诉前,先创立用来指定告诉布局的XML文件。XML文件需蕴含按钮等告诉组件的ID。以下为指定录屏告诉布局的XML文件应用示例。将自定义录屏告诉的按钮对应ID命名为“btn_1”。可依据理论须要决定告诉中的按钮数量。a. 将自定义告诉布局传入HVENotificationConfig的初始化办法。 b. 应用XML文件中定义的按钮、textView等组件的ID及点击事件。调用addClickEvent可新建点击事件。 c. 调用setDurationViewId设置textView ID,用来指定录屏时长显示地位。 ...

September 30, 2022 · 1 min · jiezi

关于android:MobSDK-快速集成文档

开发工具:Android Studio集成形式:Gradle集成前筹备应用MobSDK之前,须要先在MobTech官网注册开发者账号,并获取MobTech提供的AppKey和AppSecret,详情能够点击查看注册流程 增加配置在我的项目Gradle文件中注册MobSDK buildscript { repositories { // 1.增加MobSDK Maven地址 maven { url "https://mvn.mob.com/android" } } dependencies { // 2.注册MobSDK classpath "com.mob.sdk:MobSDK:2018.0319.1724" }}在我的项目App Module的Gradle文件中增加插件和扩大apply plugin: 'com.mob.sdk'MobSDK { appKey "您的appkey" appSecret "您的appsecrt" MobAdPush {} }在gradle.properties中增加代码MobSDK.spEdition=FP 增加混同代码在我的项目中增加如下混同代码 -keep class com.mob.**{*;}-dontwarn com.mob.**另如有用到AndResGuard混同资源问题,请在whiteList中增加如下混同配置 R.layout.adpush*R.drawable.adpush*R.anim.adpush*R.id.*回传用户隐衷受权后果(submitPolicyGrantResult)为保障您的App在集成MobSDK之后可能满足工信部相干合规要求,您应确保App装置首次冷启动且获得用户浏览您《隐衷政策》受权之后,调用Mob提交到的隐衷协定回传函数MobSDK.submitPolicyGrantResult回传隐衷协定受权后果。 反之,如果用户不批准您App《隐衷政策》受权,则不能调用MobSDK.submitPolicyGrantResult回传隐衷协定受权后果。 相干隐衷申明请参考这个链接:合规指南 //com.mob.MobSDK.class/** * 回传用户隐衷受权后果 * @param isGranted 用户是否批准隐衷协定 * @param callback 接口执行后果,可为null */ public static void submitPolicyGrantResult(boolean isGranted, com.mob.OperationCallback callback)示例代码 调用地位开发者能够本人指定,只需在应用SDK性能之前调用即可。 MobSDK.submitPolicyGrantResult(true, null);

September 28, 2022 · 1 min · jiezi

关于android:用AR-Engine手部骨骼跟踪能力实现虚拟手表试戴

AR技术的落地利用,推动着电商畛域的一直降级,通过加强事实为用户带来了虚构与事实联合的AR购物体验。如AR试衣、AR试鞋、AR试妆等性能的呈现让用户在手机上就能体验产品的佩戴成果,能够让用户更直观、更实在的理解产品信息,晋升消费者的购物愉悦感,帮忙电商利用进步购物转化率。华为AR Engine也为AR购物提供了实现计划,应用手部跟踪能力即可实现虚构手表试戴。 成果展现 实现办法AR Engine提供手部骨骼跟踪能力,能够辨认跟踪21个手部关节点的地位和姿势,造成手部骨骼模型。通过手势辨认能力,能够给AR利用提供交互性能并实现一些趣味玩法,比方能够将AR世界中的虚构物体置放到人的手部更准确的地位,如手指尖、手掌心等;还可驱动虚构手做出更精密的动作。上面我会展现虚构手表试戴性能的具体开发步骤。 集成步骤开发环境要求:JDK 1.8.211及以上。 装置Android Studio 3.0及以上: minSdkVersion 26及以上 targetSdkVersion 29(举荐) compileSdkVersion 29(举荐) Gradle 6.1.1及以上(举荐) 在华为终端设备上的利用市场下载AR Engine服务端APK(需在华为利用市场,搜寻“华为AR Engine”)并装置到终端设备。 测试利用的设施:参见AREngine个性软硬件依赖表。如果同时应用多个HMS Core的服务,则须要应用各个Kit对应的最大值。 开发筹备在开发利用前须要在华为开发者联盟网站上注册成为开发者并实现实名认证,具体方法请参见帐号注册认证。华为提供了Maven仓集成形式的AR Engine SDK包,在开始开发前,须要将AR Engine SDK集成到您的开发环境中。Android Studio的代码库配置在Gradle插件7.0以下版本、7.0版本和7.1及以上版本有所不同。请依据您以后的Gradle插件版本,抉择对应的配置过程。以7.0为例:关上Android Studio我的项目级“build.gradle”文件,增加Maven代码库。 在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。 buildscript { repositories { google() jcenter() maven {url "https://developer.huawei.com/repo/" } }}关上我的项目级“settings.gradle”文件,配置HMS Core SDK的Maven仓地址 dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { repositories { google() jcenter() maven {url "https://developer.huawei.com/repo/" } } }}增加依赖 在“dependencies”中增加如下编译依赖:dependencies { implementation 'com.huawei.hms:arenginesdk:{version}}利用开发1.运行前验证:查看以后设施是否装置了AR Engine,若曾经装置则失常运行,若没有装置,App应采纳适合的形式揭示用户装置AR Engine,如被动跳转利用市场,申请装置AR Engine。具体实现代码如下 ...

September 28, 2022 · 1 min · jiezi

关于android:阿里云EMAS|App隐私合规免费自动化检测

为什么要进行App隐衷合规检测2021年11月1日《个人信息保护法》正式失效;往年6月14日,国家互联网信息办公室颁布《挪动互联网应用程序信息服务治理规定》,这是针对App的最强监管新规,于8月1日起正式施行。新规要求应用程序提供者和应用程序散发平台该当履行信息内容治理主体责任,建立健全信息内容平安治理、信息内容生态治理、数据安全、个人信息爱护、未成年人爱护等管理制度。 工信部信息通信管理局副局长鲁春丛去年曾在中消协第五届理事会第七次会议上示意,针对消费者投诉热点,工信部将继续加强App体系化治理: “弹窗信息标识近于有形、敞开按钮小如蝼蚁、页面假装瞒天过海、诱导点击暗渡陈仓……工业和信息化部针对网友提出的弹窗信息不胜其烦等问题进行了集中整治。” 8月-10月上海相干部门将聚焦于在国内繁多利用市场内下载量/装置量达500万次以上的App利用进行集中严格查看。 EMAS App隐衷合规检测EMAS App隐衷合规检测可解决App利用对于隐衷合规的问题,避免被下架。App隐衷合规检测提供了全面的隐衷合规检测报告和专家建议,从确保模式合规(隐衷政策文本合规性)及本质合规(代码层合规性)的一致性,从个人信息收集、权限应用场景、超范围采集、隐衷政策、三方SDK等多个维度帮忙企业和开发者提前辨认App隐衷合规相干危险,躲避监管通报、利用下架等重大危险。 EMAS App隐衷合规检测什么?根据工信部164号文《工业和信息化部对于发展纵深推动APP侵害用户权利专项整治口头的告诉》等标准要求,对App进行隐衷合规评估服务,并出具合规报告。 隐衷政策协定合规剖析代码权限检测个人信息采集项检测三方SDK检测危险项及整改倡议 产品技术介绍模式合规:从重常识重人力转为自动检测监管查看的一大重点是隐衷政策协定文本是否依照要求进行了申明。传统的隐衷政策由法务编写、查看,对法务专业知识要求较高,并且需专人跟踪监管动静和相干规章,对开发者来说投入比拟大。 EMAS模式合规检测基于现行法律法规、规范、部门规章和监管动静等,总结了若干检测点。同时。基于小样本学习、信息抽取、文本分类等AI技术,可对隐衷协定文本进行细粒度解析,能精准定位到包含不限于隐衷数据采集、存储、第三方SDK应用等描述性信息。 在此基础上,依靠于自建的合规常识图谱+智能合规剖析引擎,自动化、标准化产出模式合规监测点的检测后果,最大限度地升高人力和工夫老本。 本质合规:黑盒App的代码检测合规检测的另一个问题是,咱们如何判断理论运行的采集行为与隐衷政策申明统一。EMAS合规检测产品服务底层集成的隐衷合规检测引擎基于控制流、数据流、污点剖析、动静沙箱等动动态剖析技术,深度交融隐衷专家教训,提供了精确的代码层本质合规检测能力。 本质合规关注敏感权限调用、数据采集、数据传输、数据存储等APP理论数据应用行为,通过动态剖析和动态分析两种剖析引擎,基于形象语法树、控制流图、数据流图,刻画App代码管制链路和数据流转链路,联合真机预览及模仿点击的动态分析后果,产出具体的本质合规检测点检测后果,包含敏感数据泄露、超范围采集、弹窗打搅等。相干隐衷政策点击:EMAS隐私权政策,该隐衷政策实用于挪动推送/HTTPDNS/挪动热修复/近程日志/解体剖析/性能剖析/移动用户反馈等EMAS全平台产品。 EMAS App隐衷合规检测流程上传未加固的APK安装包下载检测报告依据检测报告里的报错和倡议批改,再次检测,批改欠缺。 >> 进入阿里云EMAS挪动测试 << 产品性能劣势 技术答疑欢送退出开发者钉钉开发者交换群:35248489

September 26, 2022 · 1 min · jiezi

关于android:HMS-Core上新啦

HMS Core上新啦!剖析服务营销剖析报告全新上线;?ha_source=hms1静止衰弱服务反对指标场景事件订阅;音频编辑服务提供业余的三维声音频编辑与渲染能力,更多HMS Core能力可点击网页链接理解。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

September 26, 2022 · 1 min · jiezi

关于android:华为帐号自拟形象上线-打造手机里的另一个你

华为帐号自拟形象上线啦!用户只需一张照片,即可轻松创立属于本人的华为帐号自拟形象,还能对形象进行个性化打扮,DIY发型、服装、配饰等。点击“手机设置 > 华为帐号 > 自拟形象 ”即刻领有手机中的另一个你。 华为帐号自拟形象提供数个预置虚构形象供用户间接应用,用户也可能通过拍摄/上传照片,一键生成照片中人物形象。此外,华为帐号自拟形象领有丰盛的个性化调整模块,用户能够进一步调整发型、脸型、眉毛、眼睛、鼻子、嘴唇、胡须等部位,并且反对更换肤色、发色,让用户轻松打造心仪形象。 华为帐号自拟形象还提供包含服装、眼镜、手表等风格各异的潮流服饰,用户可依据本人的爱好随心搭配,打扮本人的独特形象。将来,自拟形象将提供更丰盛DIY能力,提供更丰盛的服饰、色调。 华为帐号自拟形象的产品设计在谋求美的同时,也力求形象细节更加真切。通过AI对数百位设计师手动捏脸生成的模型数据进行了解与训练,华为帐号自拟形象应用的算法可能基于用户照片的五官形态特色、面部尺度特色、整体构型特色,对人脸的130个维度值进行计算,模仿人脑对面部特色的辨认过程,使个体特色的辨认更准确。而得益于华为自研渲染引擎轻量、高效的个性,华为帐号自拟形象能够在较低硬件设施能耗的状况下,保障更加实在的质感,做到即便部分放大也清晰。 目前,华为帐号自拟形象可作为华为帐号的头像,在华为利用市场、华为视频等利用中展现;同时,用户也能够将其作为动静息屏,或在小艺输入法中生成表情包。快来定制属于本人的华为帐号自拟形象,体验丰盛的个性化穿搭,摸索更多乏味玩法。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

September 25, 2022 · 1 min · jiezi

关于android:国际聋人周-聋健人群无界融合看见手语的力量

听不见、听不清、听不懂,这是全国上千万听障群体的真实写照。因为听力的局限,他们在求学、工作、就医、出行等方面都面临微小挑战。AI时代,全行业为信息无障碍建设造成弱小合力,但听障群体仍然面临着凉飕飕的事实:业余语言服务人员的稀缺、沟通辅助用具的不齐备,甚至来自社会的偏见及误会…… “聋人只有通过助听设施就能够复原听力,用书面语晦涩沟通”,许多不理解听障群体的人往往会有这样的误会。以后,晚期干涉服务还无奈精准笼罩到全国每个聋童家庭,助听设施虽能够帮忙聋人重建听力,但聋人所获取的信息仍然不残缺,在沟通中仍然须要口形、手势、文字等视觉反对。此时,手语的及时染指对他们来说大有所益。 在无声世界中,手语和有声语言一样,承当着交际工具与思维工具的性能,而手语作为平面的视觉语言,它的语法不同于有声语言,除了手形、方向、地位、静止这些基本要素,面部表情、身材姿势和口部动作也是传情达意必不可少的语法标记。 (HMS Core手语数字人:大家好,我是华为HMS Core智能手语服务助手小语) “聋人不喜爱沟通”,这是又一误会。沟通,是每个人最原始的诉求,只是对聋人来说,沟通不是一件容易的事。和他们来往,友善的态度和发自内心的接收尤为重要。常言道:“如果你用一个人听得懂的语言和他交换,他会记在脑子里;如果你用他本人的语言与他交换,他会记在心里。” 为响应“数字容纳“倡导,华为HMS Core凋谢能力始终致力于构建信息无障碍环境,凋谢高质量的手语服务。 通过多项技术攻关,HMS Core手语服务以后已涵盖20000+手语词汇,在满足日常生活沟通的根底上,还可用于媒体直播、政务办理、线上学习等场景。同时,手语数字人的26种面部表情和精确口动,也无效晋升了手语表白的可懂度。通过手语服务,聋人敌人们以手为媒,交流学习、获取资讯,可能享受和健听人一样的“声歌沸腾”。 (HMS Core手语数字人:手语,链接你我他) “聋人须要人们的同情”,这或者是传统观念中对聋人最大的误会。聋人群体中流传着一位美国聋人大学校长的名言,“除了听,聋人能够做任何事件”。相比“同情”,他们更须要的是了解、容纳、帮忙。 9月24日,是往年国内聋人周的第六天,也是南京市聋人学校的手语节。在流动中,HMS Core手语数字人与听障同学们一起实现了学习中罕用成语等表演。这是手语服务赋能特教行业的一次尝试,也给了手语服务利用在更多场景一份信念。置信将来,手语服务将凋谢具备更好交互体验的教育资源,走进课堂,成为特教工作者的“小助手”,帮忙听障学生们更高效地学习,打造有温度的智慧教育。 科技助力,在突破听障群体信息孤岛的同时,也促使人们从新扫视着生命的多样化状态。咱们置信,科技的翻新不仅为听障教育的倒退点亮星光,更能推动整个社会信息无障碍继续提高,让咱们生存的世界变得更加平等、有爱、容纳。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

September 25, 2022 · 1 min · jiezi

关于android:关爱2700多万听障者手语服务助力无声交流

如果有一天,周遭的世界忽然变得很宁静,难听美好的音乐,在你看来只是寂静;振奋人心的演讲,对你而言只是默剧;大自然的千里莺啼,于你来说也只是画卷。你会不会感到胆怯? 而有这么一群人,每天都在与这世界无声交换着,他们就是听力阻碍人士。据2006年第二次全国残疾人抽样调查显示,我国的听力残疾人约2780万,占全国残疾人的30%以上,而且数据每年都在减少。受限于发病起因及家庭状况,可能应用助听器、人工耳蜗的听障人士占比拟少,其他人不仅面临着生存中的种种不便,也难以感触到世界的精彩纷呈,所以手语成了他们与人们的次要沟通桥梁。 然而手语看不懂、专业知识不够、翻译技巧不够、体态不够活泼、手语翻译在翻译的过程中有存在帮忙聋人答复问题的景象……这些裸露的问题都极大的影响了听障人士在翻译服务中的用户体验。据残联统计,我国业余的手语翻译有余1万人,难以满足听障人士参加社会生存时的沟通需要。这就须要一些App可能增加将文本翻译成手语的能力,在手语翻译无限的状况下,满足听障人士的根本生存和学习的须要。 每年9月的第四个星期日是国内聋人日,为了关爱听障人士,华为手语服务(SignPal Kit)提供手语生成能力,将文本实时翻译为晦涩、天然且合乎听障人士表白习惯的手语动作数据,可能轻松构建信息无障碍翻新利用,构筑无缝交换的世界。可用于家庭日常生活交换、教育学习、外出购物、媒体播报等场景。例如在教学场景中,可帮忙听障儿童学习浏览,实现手语教学。 手语生成手语动作生成基于深度神经网络技术,实时将输出文本翻译为时序稳固、连贯且合乎听障人士表白习惯的手语动作数据。 手语表情生成手语生成不仅包含手部动作和身材姿势,还反对面部表情,包含开心、愤恨、伤心、纳闷等根本表情信息,以及皱眉、鼓腮等多种非手控表情。 手语口型生成手语生成反对合乎听障人士表白习惯的口动。 手语服务能将输出文本转化为手语动作数据,可用于家庭日常生活交换、教育学习、外出购物、媒体播报等场景。使用手语动作及面部表情,手语服务精准流畅地传递讲师的授课内容,让处在无声世界的特教学院听障学生,也能实现无障碍网课学习。 劣势特点天然晦涩:手语动作晦涩、天然,合乎手语表白习惯。词汇笼罩广:依照中国国家通用规范有1万多个词汇,满足多场景利用。手语表白丰盛:手语动作包含手部动作、身材姿势、面部表情和口型驱动。开发步骤在开始App开发工作之前,您须要实现必要的开发筹备工作,确保您的工程中曾经配置AppGallery Connect、集成HMS Core SDK、配置混同脚本以及增加权限。 1、开明鉴权。须要应用“agconnect-services.json”里的api_key值,在利用初始化时通过AccessToken或者api_key来设置利用鉴权信息,AccessToken的优先级较高。 通过setAccessToken()办法设置Access Token,在利用初始化时设置即可,如果Token过期了,须要更换Token从新设置。 SignPalApplication.getInstance().setAccessToken("your AccessToken");通过setApiKey()办法设置api_key,在利用启动时初始化设置一次即可,无需屡次设置。 SignPalApplication.getInstance().setApiKey("your api_key");当您在AppGallery Connect上注册您的利用时,零碎会给您的利用调配api_key,可参见增加以后利用的AppGallery Connect配置文件。 2、创立手语生成实例。能够通过手语生成自定义配置类GeneratorSetting创立手语生成SignGenerator实例。 // 1.创立新的配置项,不是必须设置,不设置则应用默认值GeneratorSetting setting = new GeneratorSetting() .setLanguage(GeneratorConstants.CN_CSL)// 2.配置办法 // a.初始化时设置 SignGenerator signGenerator = new SignGenerator(setting); // b.过程中更新 signGenerator.updateSetting(setting);3、给SignGenerator实例设置手语生成回调GeneratorCallback,用于解决手语生成后果。 signGenerator.setCallback(new GeneratorCallback() { @Override public void onEvent(String taskId, int eventId, Bundle bundle) { switch (eventId){ // 以下回调事件类型是在应用手语生成过程中须要关注的 case GeneratorConstants.EVENT_START: // 工作开始回调 break; case GeneratorConstants.EVENT_DOWNLOADING: // 工作下载中 break; case GeneratorConstants.EVENT_STOP: // 工作进行回调 boolean isInterrupted = bundle.getBoolean(GeneratorConstants.EVENT_STOP_INTERRUPTED); break; default: break; } } @Overridepublic void onSignDataAvailable(String taskId, SignMotionFragment signFragment, Pair<Integer, Integer> range, Bundle bundle) { // 获取手语动作数据 ArrayList<Map<String,float[]>> motionDataList= signFragment.getSignMotionDataMap(); // 获取表情数据 int[] faceArr = signFragment.getFaceMotion(); // 获取口型BlendShape驱动数据,如果不设置开启则为空数组 float[] faceBlendShape = signFragment.getFaceBlendShapeArray(); // 手语动作表情绘制,须要您自行实现 } @Override public void onError(String taskId, SignPalError err){ // 手语生成失败解决 } @Override public void onWarning(String taskId,SignPalWarning warning){ // 告警解决(不影响业务逻辑) }});4、调用text2SignMotion()办法进行手语生成,text取值为字符串类型。 ...

September 24, 2022 · 1 min · jiezi

关于android:小米应用商店上架流程

      小米利用商店是国内支流的利用商店之一,能够将开发好的app提交到小米开放平台,通过审核之后,就能够在小米利用商店搜寻下载了。上面介绍一下小米利用商店的上架流程和注意事项,供大家参考。1. 首先注册小米开放平台账号,并进行认证。认证后,关上治理控制台,抉择利用和游戏。 接下来就是创立利用,填写利用名称和包名。 上传安装包,如图。零碎会自动识别利用敏感权限,能够补充相应阐明;而后填写公布设置、根底信息、以及图形信息和行业资质证实。 最初填联系人信息就能够提交了,审核通过后上架就实现了!审核通常会在1~3个工作日内实现。 利用商店审核的反馈信息,如果有疑议,能够间接提工单,工单根本半个工作日内就有回复,这样有助于解决问题,疾速通过审核。这里具体的反馈还须要认真解决,以进步审核通过效率。

September 23, 2022 · 1 min · jiezi

关于android:蚂蚁数科mPaaS被列为Gartner多体验开发平台市场指南代表产品

近日,国内钻研机构Gartner®公布《多体验开发平台市场指南》(Market Guide for Multiexperience Development Platforms)(下简称“《报告》”),聚焦多体验开发平台的市场现状及发展趋势。蚂蚁团体被认可为代表供应商,也是惟一一家中国厂商,其自主研发的一站式挪动开发平台mPaaS作为代表产品被收录其中。 随着数字经济深刻倒退,越来越多的服务正减速向线上化、挪动化和智能化转型。与此同时,可穿戴设施、聊天机器人、加强事实及混合事实等新兴交互方式不断涌现,如何在宽泛的数字产品组合中提供统一的用户体验成为企业关注的焦点。 在此背景下,多体验开发平台成为趋势。多体验开发平台反对分布式、可扩大的开发方法,企业能够此构建跨设施、触点和交互模式的应用程序,确保用户体验的一致性。据Gartner预测,到2025年,多体验开发平台市场规模将达47亿美元;到2027年,40%的大型企业将基于多体验开发平台来打造超级应用程序。 为了给企业IT架构决策者及利用开发者提供参考,上述《报告》从开发者工具、微利用和超级利用模式、API和集成反对、开发运维反对等10项规范对寰球的多体验开发平台厂商进行评估。《报告》中列举了寰球28家符合标准的产品供应商。其中,蚂蚁团体是惟一一家来自中国的厂商,其余代表厂商还包含AWS、微软、谷歌等海内公司。 据理解,蚂蚁数科mPaaS是蚂蚁团体自主研发的挪动开发平台,为挪动利用开发、测试、经营及运维提供云到端的一站式解决方案,可能显著晋升挪动利用的交互体验,保障利用合规及平安。 值得一提的是,蚂蚁数科mPaaS还配套精细化经营工具、丰盛营销场景能力,帮忙企业实现业务增长。以新华保险为例,往年2月,基于mPaaS打造的“掌上新华”App正式上线,成为新华保险面向整体C端客户的线上服务平台。新版App上线后,日活用户数晋升450%,累计用户冲破100万,日均交易额为此前的4.63倍。 目前,蚂蚁数科mPaaS曾经广泛应用于金融、政务、通信及互联网等行业,服务于包含富滇银行、新华保险、12306、上海地铁等数百家机构及企业。 蚂蚁团体数字行业事业部总经理余滨示意:“很快乐mPaaS挪动开发平台凭借杰出的体现取得Gartner认可。将来,咱们将保持自主研发、继续翻新,为各行各业提供高效的数字化、智能化产品与解决方案,助力企业数智化降级。”

September 23, 2022 · 1 min · jiezi

关于android:开发者问第四期统一扫码服务机器学习服务等问题解答

开发者问第四期问答分享来啦!对立扫码服务反对哪些条码解析?机器学习服务反对离线翻译吗?如何让玩偶跳舞?点击链接,理解详情或发问你想问的问题:https://developer.huawei.com/... 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

September 23, 2022 · 1 min · jiezi

关于android:Target-API-level升级到31后Android-12启动黑屏卡死

1)Target API level降级到31后Android 12启动黑屏卡死2)Unity Renderer中SortingLayer、SortingOrder底层如何实现渲染排序3)如何用Addressable实现按需下载4)多个Package须要不同版本的DLL的解决方案 这是第309篇UWA技术常识分享的推送。明天咱们持续为大家精选了若干和开发、优化相干的问题,倡议浏览工夫10分钟,认真读完必有播种。 UWA 问答社区:answer.uwa4d.comUWA QQ群2:793972859(原群已满员) AndroidQ:以后海内版本有硬性要求:Target API level必须降级到31,降级之后在Android 12机型上启动游戏,Unity闪屏之后卡死,其余Android版本失常。 咱们应用的Unity版本:2017.4.27f其余一些简略测试:去掉闪屏, 导出新的空工程,都会呈现启动卡死。 其余一些Unity论坛上的形式尝试均失败:https://forum.unity.com/threa...https://forum.unity.com/threa... 之前咱们也遇到降级之后无奈装置的问题,而后参照其余解决了装置,只是黑屏无奈解决。以后最新尝试Unity 2019版本是失常,初步判断是与以下问题同时修复的:https://issuetracker.unity3d.... 不晓得是否有其余大神遇到此问题并解决了?如果有降级之后失常,请告知一下Unity版本号,谢谢。 A:查了一下这个问题,是因为TelephonyManager的listen函数在Android 12过期了,如果没有受权READ_PHONE_STATE权限,此函数会抛出一个SecurityException。 而Unity在启用了自带的音频系统的状况下,凑巧在启动时机会去调用这个办法以实现“在用户接电话时游戏静音”的性能,抛出的异样影响了后续的流程导致卡死。 论坛上有人遇到了相似的问题,然而体现为解体:https://forum.unity.com/threa... 我的项目能降级引擎的话,能够试试这里提到的修复的版本:https://issuetracker.unity3d.... 如果我的项目不能降级引擎,也有一个解决办法: 反编译classes.jar批改UnityPlayer类的addPhoneCallListener实现,判断if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) return;据说Android 12开始不须要本人解决静音了再编回classes.jar感激[email protected]问答社区提供了答复 RenderingQ:Unity Renderer中SortingLayer、SortingOrder底层是如何实现渲染排序的? A1:第一级是材质RenderQueue的区间:不通明(<2499)优先,而后半透明(>=2500)。第二级是SortingLayer。第三级是SortingOrder。第四级是材质RenderQueue自身。感激欧月松@UWA问答社区提供了答复 A2:Unity残缺渲染程序如下: CameraDepth从小到大开始渲染不通明物体(RenderQueue < 2500)SortingLayer从小到大SortingOrder从小到大RenderQueue从小到大物体深度近到深度远开始渲染半透明物体(RenderQueue >= 2500)SortingLayer从小到大SortingOrder从小到大RenderQueue从小到大物体深度远到深度近感激萧小俊@UWA问答社区提供了答复 AddressableQ:如何用Addressable实现按需下载,大体是想要实现上面两个性能: 1. 一部分资源是在游戏启动的时候去更新的。2. 还有一部分资源是在玩家玩到某个关卡的时候,让玩家手动触发下载。当然,这些关卡,没有下载实现之前,玩家是不能玩的。 A:可参考Unity官网实例Git,其中Advanced/Play Asset Delivery这个案例很好地展现了AssetBundle和Google新格局aab的联合以及打包Asset Packs后,哪些资源预下载,哪些资源实时下载。https://github.com/Unity-Tech...感激郑骁@UWA问答社区提供了答复 ScriptingQ:具体情况就是Google ProtoBuf库的高版本会强制依赖 System.Runtime.CompilerServices.Unsafe.dll 4.0.4.1版本。 而后Unity内置的Package com.unity.collections会本人带进来一个DLL,并且版本不匹配。 当初有没有方法,导入一个DLL,并且只让某一个Package内的代码进行援用。或者有没有其余代替计划,比方禁止com.unity.collections带入本人的Unsafe.dll之类的流程? 其余就是思考一个流程从新编译ProtoBuf的动静库,使其内含一个本人用的依赖库。然而这个依赖库也不好找源码。 次要问题是:com.unity.collections是Unity原生并主动植入的,不进入Packages门路,间接植入到Library。所以没有方法手动调整门路。当初临时是用脚本在启动编辑器时替换Library外面的动静库。然而这个流程不洁净,心愿有个洁净的唱工。 A:先把我的项目中反复度高的DLL都放在一个Common Package中,而后把com.unity.collections拉到本地变成Local Package,再去依赖Common Package,最初就让Google ProtoBuf也去依赖这个Common Package。 对于Unity原生并主动植入的Package,个别从Library拉到本地就行,留神一下最初的package-lock.json文件中com.unity.collections的Version为file:XXXXX,并且Source显示为Embedded就代表胜利了。 感激萧小俊@UWA问答社区提供了答复 封面图来源于网络 明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在UWA问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。 官网:www.uwa4d.com官网技术博客:blog.uwa4d.com官网问答社区:answer.uwa4d.comUWA学堂:edu.uwa4d.com官网技术QQ群:793972859(原群已满员)

September 21, 2022 · 1 min · jiezi

关于android:如何用AR-Engine开发一个虚拟形象表情包

现如今,人们在网上聊天、发帖时越来越爱用表情包,表情包一方面是一种个性化的表达方式,另一方面更能传播出当下的心理流动,能够说在网络社交中表情包是一个不可或缺的存在。加上近年来元宇宙的衰亡,3D虚构形象广泛应用,用户能够通过本人的表情来管制虚构形象的表情,做一系列专属的表情包,更加活泼形象。 那么,如何让虚构形象领有人类一样多变的表情呢?HMS Core AR Engine的人脸表情跟踪能力就能帮忙实现,实时计算人脸各表情对应的参数值。用户可通过本人的面部动作,管制虚构人物的表情,最终制作成虚构人物的各种活泼的表情,以更乏味的模式配合传播文字情绪,同时也极大不便了虚构人物的表情制作等利用场景。 比方在社交App中,不想露脸的人能够把本人的喜怒哀乐通过虚构形象的表情传播,在爱护隐衷的同时又减少了趣味性。在直播、电商App里,为了防止同质化,商家利用虚构主播的表情生动性可能给用户带来更活泼的生产场景以及离奇的互动体验,激发年轻人对沉迷式虚构娱乐和数字生产的需要。在短视频、拍照等App中,用户利用人脸表情管制虚构形象的表情,进行自我展现与表白,拉近人与人的间隔;而在教育、文旅等App中,捕获人脸图像信息,实时将其了解成人脸表情内容,用虚构形象进行解说教学更加活泼,激发用户的学习趣味。 实现办法 AR Engine提供“人脸表情跟踪”能力,可实时跟踪获取人脸图像信息,计算人脸的位姿,并将其了解成人脸表情内容,并转化成各种表情参数,利用表情参数能够实现人脸表情间接管制虚构形象的表情。AR Engine目前共提供64种表情,蕴含眼睛、眉毛、眼球、嘴巴、舌头等次要脸部器官的表情动作。眼部共有21种表情,包含眼球的挪动、睁闭眼、眼皮的微动作等;嘴部共有28种表情,包含张嘴噘嘴、嘴角下拉、抿嘴唇、舌头的动作等;眉毛共有5种表情,包含抬眉、单侧眉毛朝下或抬上等。其余具体表情参数可见FaceAR设计规范。 成果展现 开发步骤开发环境要求: JDK 1.8.211及以上。装置Android Studio 3.0及以上:minSdkVersion 26及以上targetSdkVersion 29(举荐)compileSdkVersion 29(举荐)Gradle 6.1.1及以上(举荐) 在华为终端设备上的利用市场下载AR Engine服务端APK(需在华为利用市场,搜寻“华为AR Engine”)并装置到终端设备。 测试利用的设施:参见AREngine个性软硬件依赖表。如果同时应用多个HMS Core的服务,则须要应用各个Kit对应的最大值。 开发筹备在开发利用前须要在华为开发者联盟网站上注册成为开发者并实现实名认证,具体方法请参见帐号注册认证。华为提供了Maven仓集成形式的AR Engine SDK包,在开始开发前,须要将AR Engine SDK集成到您的开发环境中。Android Studio的代码库配置在Gradle插件7.0以下版本、7.0版本和7.1及以上版本有所不同。请依据您以后的Gradle插件版本,抉择对应的配置过程。以7.0为例:关上Android Studio我的项目级“build.gradle”文件,增加Maven代码库。 在“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。 buildscript { repositories { google() jcenter() maven {url "https://developer.huawei.com/repo/" } }}关上我的项目级“settings.gradle”文件,配置HMS Core SDK的Maven仓地址 dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { repositories { google() jcenter() maven {url "https://developer.huawei.com/repo/" } } }}增加依赖 在“dependencies”中增加如下编译依赖:dependencies { implementation 'com.huawei.hms:arenginesdk:{version}}利用开发运行前验证:查看以后设施是否装置了AR Engine,若曾经装置则失常运行,若没有装置,App应采纳适合的形式揭示用户装置AR Engine,如被动跳转利用市场,申请装置AR Engine。具体实现代码如下boolean isInstallArEngineApk =AREnginesApk.isAREngineApkReady(this);if (!isInstallArEngineApk) { // ConnectAppMarketActivity.class为跳转利用市场的Activity。startActivity(new Intent(this, com.huawei.arengine.demos.common.ConnectAppMarketActivity.class)); isRemindInstall = true;}创立AR场景:AR Engine提供5种场景,包含静止跟踪(ARWorldTrackingConfig)、人脸跟踪(ARFaceTrackingConfig)、手部辨认(ARHandTrackingConfig)、人体跟踪(ARBodyTrackingConfig)和图像识别(ARImageTrackingConfig)。调用ARFaceTrackingConfig接口,创建人脸跟踪。// 创立ARSession。mArSession = new ARSession(this);// 依据要应用的具体场景,选用具体的Config来初始化ARSession。ARFaceTrackingConfig config = new ARFaceTrackingConfig(mArSession);创建人脸跟踪ARSession后,可通过config.setXXX办法配置场景参数 ...

September 21, 2022 · 2 min · jiezi

关于android:什么是原创独立完成就是原创吗

前言大家好,我是小彭。 前几天刷到一个议论 “什么是原创?” 的视频,可能是本人也是创作者的缘故,视频也引发了我的一些思考。另外,我更多地去搜寻了相干话题的内容,也查阅了《中华人民共和国著作权法》相干法条内容和最高人民法院对于著作权的指导性案例。综合以上内容,分享到小彭现阶段我对于 “原创” 的了解。 我认为对于原创的了解,应该从 2 个角度来看 —— 著作权 + 用户。著作权角度是立足于创作者的权利,是原创的根底规范,而用户角度是立足于用户的权利,是高价值原创的规范。 只有同时从著作权角度和用户角度对待一个作品,能力残缺地体现一个作品的原创性。 留神: 本文波及的法条内容及其观点仅作为学习应用,不形成参考意见。学习路线图: 1. 著作权和专利权的区别在法律概念中,著作权与专利权有相似之处,咱们先了解分明它们的区别。尽管新发明新专利也属于创作行为,然而咱们明天探讨的原创次要是指著作权中的创作行为,不蕴含发明权中的创作行为,这两者有什么区别呢?简略一句话 —— 爱护对象不同:发明权爱护的是思维自身,而著作权爱护的是这个思维的表现形式,而不爱护思维自身。 举个例子,Apple 公司的 iPhone 14 Pro 系列中灵动岛设计就是一个独创性的思维,受专利权爱护(如果 Apple 申请了设计专利),其他人未经许可不能应用完全相同的设计,也不能再申请雷同专利。专利权具备十分强烈的排他性。 而 Apple 公司对于灵动岛的宣传视频或营销文就是对灵动岛这一思维的表现形式,受著作权爱护,其他人未经许可不能应用这些宣传视频或文章,但任何人都能够创作新的视频或文章来表白本人对于灵动岛的观点,且都领有各自的著作权。 iPhone 14 Pro 灵动岛 —— 图片援用自 Apple 官网 这个例子应该可能比较清楚地体现著作权和专利权最次要的区别 —— 爱护对象: 专利权爱护思维自身: 例如新的制作办法、独特的外观设计、原创的故事等;著作权爱护思维的表现形式: 例如对这一思维进行解释或探讨的视频、文章等。了解了著作权的爱护对象之后,咱们再回到 “什么是原创” 的问题。 2. 什么是原创?(著作权角度)先说论断, 从著作权角度看,原创作品是指对某个思维或观点的独创性表白,在原创作品的根底上进行二次创作(改编、翻译或汇编等)并退出新的独创性表白所造成的新作品,也具备著作权,但在发行(复制、流传或商业表演等)时须要获得原作品作者的许可并领取报酬。 首先,能够先看一下百度词条对于 “原创” 的解释: 原创是独立实现的创作。 原创不属于扭曲、篡改别人创作或者剽窃、抄袭别人创作而产生的作品,亦不属于改编、翻译、正文、整顿别人已有创作而产生的作品。 —— 百度词条 这个观点我是不齐全认同的。 1、原创是独立实现的创作: 不认同。例如剽窃者对原作品进行简略搬运、拼接、篡改的作品也属于独立实现的,但显著不属于原创作品;2、原创不属于扭曲、篡改别人创作或者剽窃、抄袭别人创作而产生的作品: 认同。3、亦不属于改编、翻译、正文、整顿别人已有创作而产生的作品: 不认同,在原作品的根底上进行二次创作的作品也能够是原创作品。举个例子,《静夜思》是李白的作品,而许渊冲的英文译本《Tranquil Night》是在原作品根底上的翻译作品,但亦是原创作品。这个判断并不是小彭臆想的,我在《著作权法》中找到了相应的法条根据: “什么是爱护对象?” 《最高人民法院对于公布第28批指导性案例的告诉》亦给出着重解释:我国著作权法所爱护的是作品中作者具备独创性的表白, 而不爱护作品中所反映的思维自身。“什么是原创作品?” 《著作权法》对著作权爱护的原创作品定义给予了充分说明:所谓作品,是指文学、艺术和迷信畛域内 具备独创性并能以肯定模式体现的智力成绩。 这些模式包含:(1)文字作品;(2)口述作品;(3)音乐、戏剧、曲艺、舞蹈、杂技艺术作品;(4)美术、修建作品;(5)摄影作品;(6)视听作品;(7)工程设计图、产品设计图、地图、示意图等图形作品和模型作品;“什么是二次创作作品?” 《著作权法》亦给出了相干限度要求:第十三条 改编、翻译、正文、整顿已有作品而产生的作品, 其著作权由改编、翻译、正文、整顿人享有, 但行使著作权时不得进犯原作品的著作权。第十五条 汇编若干作品、作品的片段或者不形成作品的数据或者其余资料, 对其内容的抉择或者编排体现独创性的作品,为汇编作品,其著作权由汇编人享有, 但行使著作权时,不得进犯原作品的著作权。第十六条 应用改编、翻译、正文、整顿、汇编已有作品而产生的作品进行出版、上演和制作录音录像制品, 该当获得该作品的著作权人和原作品的著作权人许可,并领取报酬。咱们将以上三段法条连接起来,“原创作品” 的概念就曾经比拟清晰了。 2 个关键词:表白 + 独创性 ,具体能够分为 3 点: ...

September 19, 2022 · 1 min · jiezi

关于android:手把手教你轻松打造沉浸感十足的动态漫反射全局光照

一个沉迷感十足的游戏,其场景中的全局光照成果肯定功不可没。 动静漫反射全局光照(DDGI)带来的光影变动,是细腻延展的视觉语言,让场景中每种色彩都有了“五彩斑斓”的诠释,场景布局光影,物体关系立显,环境温度来临,拓展了画面信息传播的档次,点睛之笔。 间接光渲染 VS 动静漫反射全局光照 细腻的光照视觉语言带来的技术挑战不小。不同材质外表与光照产生的出现成果千差万别,漫反射(Diffuse)将光照信息平均散射,光线的强弱、光照动势、物体外表材质的变换等,面对这些浮动的变量,平台性能和算力备受考验。 针对全局光照需克服的简单“症状”,HMS Core图形引擎服务提供了一套实时动静漫反射全局光照(DDGI)技术,面向挪动端,可扩大到全平台,无需预烘培。基于光照探针(Light Probe)管线,在Probe更新和着色时提出改良算法,升高原有管线的计算负载。实现屡次反射信息的全局光照,晋升了渲染真实感,满足挪动终端设备实时性、互动性要求。 并且,实现一个沉迷感满满的动静漫反射全局光照,几步就能轻松搞定! Demo示例 开发指南步骤阐明1.初始化阶段:设置Vulkan运行环境,初始化DDGIAPI类。 2.筹备阶段: 创立用于保留DDGI渲染后果的两张Texture,并将Texture的信息传递给DDGI。 筹备DDGI插件须要的Mesh、Material、Light、Camera、分辨率等信息,并将其传递给DDGI。 设置DDGI参数。 3.渲染阶段 如果场景的Mesh变换矩阵、Light、Camera信息有变动,则同步更新到DDGI侧。 调用Render()函数,DDGI的渲染后果保留在筹备阶段创立的Texture中。 将DDGI的后果融入到着色计算中。 美术限度1.对于想要使能DDGI成果的场景,DDGI的origin参数应该设置为场景的核心,并设置相应步长和Probe数量使得DDGI Volume能笼罩整个场景。 2.为了让DDGI取得适合的遮挡成果,请防止用没有厚度的墙;如果墙的厚度绝对于Probe的密度显得太薄了,会呈现漏光(light leaking)景象。同时,形成墙的立体最好是单面(single-sided)的,也即墙是由两个单面立体组成。 3.因为是挪动端的DDGI计划,因而从性能和功耗角度登程,有以下倡议:①管制传到SDK侧的几何数量(倡议5万顶点以内),比方只将场景中的会产生间接光的主体构造传到SDK;②尽量应用适合的Probe密度和数量,尽量不要超过101010。以上倡议以最终的出现后果为主。 开发步骤1、下载插件的SDK包,解压后获取DDGI SDK相干文件,其中包含1个头文件和2个so文件。Android平台应用的so库文件下载地址请参见:动静漫反射全局光照插件。 2、该插件反对Android平台,应用CMake进行构建。以下是CMakeLists.txt局部片段仅供参考: cmake_minimum_required(VERSION 3.4.1 FATAL_ERROR)set(NAME DDGIExample)project(${NAME})set(PROJ_ROOT ${CMAKE_CURRENT_SOURCE_DIR})set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O2 -DNDEBUG -DVK_USE_PLATFORM_ANDROID_KHR")file(GLOB EXAMPLE_SRC "${PROJ_ROOT}/src/*.cpp") # 引入开发者主程序代码。include_directories(${PROJ_ROOT}/include) # 引入头文件,能够将DDGIAPI.h头文件放在此目录。# 导入librtcore.so和libddgi.soADD_LIBRARY(rtcore SHARED IMPORTED)SET_TARGET_PROPERTIES(rtcore PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/libs/librtcore.so)ADD_LIBRARY(ddgi SHARED IMPORTED)SET_TARGET_PROPERTIES(ddgi PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/libs/libddgi.so)add_library(native-lib SHARED ${EXAMPLE_SRC})target_link_libraries( native-lib ... ddgi # 链接ddgi库。 rtcore android log z ...)3、设置Vulkan环境,初始化DDGIAPI类。 // 设置DDGI SDK须要的Vulkan环境信息。// 包含logicalDevice, queue, queueFamilyIndex信息。void DDGIExample::SetupDDGIDeviceInfo(){ m_ddgiDeviceInfo.physicalDevice = physicalDevice; m_ddgiDeviceInfo.logicalDevice = device; m_ddgiDeviceInfo.queue = queue; m_ddgiDeviceInfo.queueFamilyIndex = vulkanDevice->queueFamilyIndices.graphics; }void DDGIExample::PrepareDDGI(){ // 设置Vulkan环境信息。 SetupDDGIDeviceInfo(); // 调用DDGI的初始化函数。 m_ddgiRender->InitDDGI(m_ddgiDeviceInfo); ...}void DDGIExample::Prepare(){ ... // 创立DDGIAPI对象。 std::unique_ptr<DDGIAPI> m_ddgiRender = make_unique<DDGIAPI>(); ... PrepareDDGI(); ...}4、创立两张Texture,用于保留相机视角的漫反射全局光照和法线深度图。为进步渲染性能,Texture反对降分辨率的设置。分辨率越小,渲染性能体现越好,但渲染后果的走样,例如边缘的锯齿等问题可能会更加重大。 ...

September 19, 2022 · 3 min · jiezi

关于android:最全的-Android-之-Dialog

Android 之 Dialog一、简介对话框的性能次要就是提醒一些信息给用户,让用户可进行下一步操作,或者提醒用户该操作不可逆等等。 然而对话框自身的时候不简单,简单在于和其余控件联合起来应用。 上面介绍会介绍几种罕用的对话框。 二、属性和办法Android零碎提供的对话框父类为Dialog, 外面并没有实现对话框的具体类型,比方单选、多选、列表等对话框,仅提供一个框架和标准。零碎为开发者提供了一个 多功能的对话框类AlertDialog, 封装了各种对话框的款式,咱们只须要实现要显示的内容和监听。 大部分对话框就是应用零碎封装好的对话框AlertDialog的实例对象。AlertDialog并不提供对外的构造方法,即不能间接通过AlertDialog的构造函数来生产一个AlertDialog。因为AlertDialog所有的构造方法都是protected的。所以为了获取AlertDialog对象,零碎提供了一个动态外部类Builder让咱们应用,通过Builder能够创立AlertDialog对象。 Builder对象设置对话框的属性 .setTitle() //设置题目 .setIcon ()//设置图标 .setMessage ()//设置要显示的内容 .setItems//设置在对话框中显示的我的项目列表 .setView//设置自定义的对话框款式 .setPositiveButton ()//设置确定按钮 .setNegativeButton ()//设置勾销按钮 .setNeutralButton ()//设置中立按钮 .setSingleChoiceItems//单选框 .setMultiChoiceItems//复选框三、各种Dialog的应用对话框的在安卓中的应用堪称无处不在,应用十分的宽泛,一个好的对话框能进步用户的应用感。这在安卓开发中是十分重要的。 本章节会介绍以下这些常见的对话框的应用。 应用步骤: 创立AlertDialog.Builder实例对象。通过Builder对象设置对话框的属性。调用Builder对象的create()办法创立AlertDialog对话框调用AlertDialog的show()办法来显示对话框调用AlertDialog的dimiss()办法销毁对话框。1、一般的对话框当咱们要提醒用户一些信息,以及让用户做一些判断的选项时候,就能够时候简略的对话框即可。 如图成果: java外围代码: AlertDialog dialog=new AlertDialog.Builder(this) .setIcon(R.drawable.hmbb)//设置图标 .setTitle("我是一般的对话框")//设置题目 .setMessage("我是内容")//设置要显示的内容 .setNegativeButton("勾销", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { Toast.makeText(MainActivity.this, "点击了勾销按钮", Toast.LENGTH_SHORT).show(); dialogInterface.dismiss();//销毁对话框 } }) .setNeutralButton("第三方按钮", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { Toast.makeText(MainActivity.this, "我是第三个按钮", Toast.LENGTH_SHORT).show(); } }) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "点击了确定的按钮", Toast.LENGTH_SHORT).show(); dialog.dismiss();//销毁对话框 } }).create();//create()办法创立对话框 dialog.show();//显示对话框2、列表对话框如图成果: ...

September 18, 2022 · 3 min · jiezi

关于android:Android中Activity的工作过程二

PS:本文系转载文章,浏览原文可读性会更好,文章开端有原文链接 本篇文章是基于Android中Activity的工作过程(一)来持续写的,在Android中Activity的工作过程(一)这篇文章中,咱们有讲到两行代码,那就是如下代码;这里的 this 是指 MainActivity 对象,咱们在Android中Activity的工作过程(一)这篇文章中剖析了 MainActivity 的 onPause 的调用流程,本篇文章打算从以上两行代码剖析 Main2Activity 的 onCreate 和 onStart 调用流程。在Android中Activity的工作过程(一)这篇文章中,咱们有剖析到如下几行代码;看正文15,调用了 ActivityStack 的 resumeTopActivityInner-Locked(ActivityRecord prev, ActivityOptions options) 办法;看正文27和28的代码,mStackSupervisor 是 ActivityStackSupervi-sor 类型的对象,都调用的是 ActivityStackSupervisor 的 startSpecificActivityLocked(ActivityR-ecord r,boolean andResume, boolean checkConfig) 办法;下面的两行代码:Intent intent = new Intent(this,Main2Activity.class); startActivity(intent);咱们要启动的是 Main2Activity 对不对?那么 ActivityStackSupervisor 的 startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) 办法就是 Main2Activity 的 onCreate 和 onSt-art 办法的入口,好,咱们回到正文27和28的代码,咱们到底调用的是正文27的代码还是正文28的代码呢?咱们看一下正文26代码这个 if 语句的用意,它示意的是判断新的 app 过程是否被创立;首先我写这个 demo 启动 Main2Activity 的时候并没有启动一个新的过程哦,所以不会走正文26的 if 包裹的代码,所以会执行正文28的代码,咱们看一下 ActivityStackSupervisor 的 startSpecificActivityLocked(ActivityR-ecord r,boolean andResume, boolean checkConfig) 办法;看正文29,调用了 ActivityStackSupervisor 的 realStartActivi-tyLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) 办法;看正文30,app.thread 是 ActivityThread 的外部类 ApplicationThread,而后调用了 ApplicationThread 的 schedule-LaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,Co-mpatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,int procState, Bundle state, PersistableBundle persistentState,List<ResultInfo> pendingResults, List<ReferrerI-ntent> pendingNewIntents,boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) 办法;看正文31,这里就插入一条 what 等于 H.LAUNCH_ACTIVITY 的音讯,而后 ActivityThread 的外部类 H 就会相应的做解决; 看正文32,又调用了 ActivityThread 的 handleLaunchActivity(Activ-ityClientRecord r, Intent customIntent, String reason) 办法;看正文33,这里就调用了 ActivityThread 的 performLaunch-Activity(ActivityClientRecord r, Intent customIntent) 办法;private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ...... try { ...... if (activity != null) { ...... if (r.isPersistable()) { //35、 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { //36、 mInstrumentation.callActivityOnCreate(activity, r.state); } ...... if (!r.activity.mFinished) { //37、 activity.performStart(); r.stopped = false; } ...... } ...... } catch (SuperNotCalledException e) { ...... } catch (Exception e) { ...... } return activity; }看正文35,这里的 r.isPersistable() 就为 true,所以执行的是正文35处的代码,mInstrumentation 是 Instrumentation 类型的对象,所以调用了 Instrumentation 的 callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) 办法;看正文38,这里调用了 Activity 的 performCreate(Bundle icicle, PersistableBundle persistentState) 办法,咱们往下看;看正文39,这里又调用了 Activity 的 onCreate(@Nullable Bundle savedInstanceState,@Nullable PersistableBundle persistentState) 办法;看到正文40了没有,这里调用了 Activity 的 onCreate(Bundle savedInstanceState) 办法,所以 Activity 的 onCreate 流程咱们理分明了;好,咱们当初回看到正文37的代码,这里就调用了 Activity 的 performStart 办法,咱们往下看;看正文41,mInstrumentation 是 Instrumentation 类型的对象,这里就调用了 Instrumentation 的 callActivityOnStart(Activity activity) 办法;看到正文42的代码没有,这里就调用到了 Activity 的 onStart 办法,所以 Activity 的 onStart 流程也理分明了。 ...

September 18, 2022 · 2 min · jiezi

关于android:Android之SeekBar

Android之SeekBar一、简介 SeekBar意思为拖动条,是ProgressBar的一个子类。 在咱们安卓的开发中也是利用十分的宽泛。如音乐播放、音量条、播放进度条,等等。Android零碎只提供了程度的,默认的款式,咱们也能够依据本人需要自定义款式。 二、罕用属性和办法seekBar继承了ProgressBar,ProgressBar所反对的xml属性和办法都实用于seekBar,ProgressBar的应用能够看这篇博客Android之 ProgressBar的简略应用 这里介绍下最罕用属性和办法: 属性名含意max设置该进度条的最大值progress设置该进度条的已实现进度值progressDrawable自定义drawable显示secondaryProgress定义二级进度值,值介于0到max。该进度在主进度和背景之间。比方用于网络播放视频时,二级进度用于示意缓冲进度,主进度用于示意播放进度。thumb设置进度条的滑块图片splitTrack滑块底部 背景款式 (false为通明 )getMax() //返回这个进度条的范畴的下限getProgress():返回进度getsecondaryProgress() //返回二级进度incrementProgressBy(int diff) //指定减少的进度isIndeterminate() //批示进度条是否在不确定模式下setIndeterminate(boolean indeterminate) //设置不确定模式下 三、简略应用实现一个简略seekbar监听事件,扭转图片的透明度 编写布局代码因为图片的透明度分为256阶(0-255),所以咱们的max属性要设置为255,初始值progress属性也设置为255,使照片不通明可见。 <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="拖动条" android:layout_gravity="center" android:layout_marginTop="50dp"/> <ImageView android:id="@+id/iv_zhuyin" android:layout_width="match_parent" android:layout_height="250dp" android:src="@drawable/zhuyin"/> <SeekBar android:id="@+id/seek_bar" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:splitTrack="false" android:max="255" android:progress="255" android:layout_width="match_parent" android:layout_height="wrap_content" android:thumb="@drawable/seekbar01"/> <TextView android:id="@+id/tv_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_gravity="center" android:text="以后透明度:255/255"/></LinearLayout>编写MainActivity里的java代码次要是实现一个seek的监听事件,OnSeekBarChangeListener() 能够为拖动条增加监听事件,该监听事件重写三个办法。 办法作用onStartTrackingTouch当开始滑动滑块时,会执行该办法下的代码onStopTrackingTouch当完结滑动滑块时,会执行该办法下的代码onProgressChanged当滑块进度扭转时,会执行该办法下的代码public class MainActivity extends AppCompatActivity { private SeekBar mSeekBar; private TextView mTextView; private ImageView mImageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSeekBar=findViewById(R.id.seek_bar); mTextView=findViewById(R.id.tv_progress); mImageView=findViewById(R.id.iv_zhuyin); mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override //当滑块进度扭转时,会执行该办法下的代码 public void onProgressChanged(SeekBar seekBar, int i, boolean b) { mImageView.setAlpha(i);//设置以后的透明度 mTextView.setText("以后透明度: " +i+"/255"); } @Override //当开始滑动滑块时,会执行该办法下的代码 public void onStartTrackingTouch(SeekBar seekBar) { Toast.makeText(MainActivity.this,"我seekbar开始滑动了",Toast.LENGTH_SHORT).show(); } @Override //当完结滑动滑块时,会执行该办法下的代码 public void onStopTrackingTouch(SeekBar seekBar) { Toast.makeText(MainActivity.this,"我seekbar完结滑动了",Toast.LENGTH_SHORT).show(); } }); }}最初实现成果: ...

September 18, 2022 · 1 min · jiezi

关于android:Android之ProgressBar-手把手教学使用控件

进度条是app中最司空见惯的控件了,上面就来理解一下。 一、简介进度条是UI界面中一种十分实用的组件,通常用于向用户像是某个耗时操作实现的百分比。进度条可动静地显示进度,因而防止长时间地执行某个操作时,让用户感觉程序失去了响应,从而更好地进步用户界面的敌对性。 进度条大体分为 程度型(条形)和 环形 如图所示:简直所有的花色的进度条都次要为这两种类型。 二、罕用属性和办法属性名含意style设置进度条的格调max设置该进度条的最大值maxHeight进度Widget最大高miniHeight进度Widget最小高maxWidth进度Widget最大宽minWidth进度Widget最小宽progress设置该进度条的已实现进度值progressDrawable自定义drawable显示indeteminateDrawable设置绘制不显示进度的进度条的Drawable对象indeterminate该属性设为true,设置进度条不准确显示进度indeteminateDuration设置不准确显示进度的持续时间secondaryProgress定义二级进度值,值介于0到max。该进度在主进度和背景之间。比方用于网络播放视频时,二级进度用于示意缓冲进度,主进度用于示意播放进度。interpolator设置动画速度indeterminateBehavior定义当进度达到最大时,不确定模式的体现;该值必须为repeat或者cycle,repeat示意进度从0从新开始;cycle示意进度放弃以后值,并且回到0style属性: @android:style/Widget.ProgressBar.Horizontal:程度进度条@android:style/Widget.ProgressBar.Inverse:一般大小的进度条@android:style/Widget.ProgressBar.Large:大环形进度条@android:style/Widget.ProgressBar.Large.Inverse:大环形进度条@android:style/Widget.ProgressBar.Small:小环形进度条@android:style/Widget.ProgressBar.Small.Inverse:小环形进度条在java代码中,咱们罕用的办法有: getMax() //返回这个进度条的范畴的下限getProgress():返回进度getsecondaryProgress() //返回二级进度incrementProgressBy(int diff) //指定减少的进度isIndeterminate() //批示进度条是否在不确定模式下setIndeterminate(boolean indeterminate) //设置不确定模式下 三、简略应用编写布局文件 <!-- 零碎提供的进度条--><TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="程度进度条" android:layout_marginTop="50dp" android:layout_gravity="center"/> <ProgressBar android:id="@+id/progress_01" android:layout_width="match_parent" android:layout_height="30dp" android:max="100" android:layout_marginTop="100dp" android:padding="20dp" style="@style/Widget.AppCompat.ProgressBar.Horizontal"/> <TextView android:id="@+id/tv_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/progress_01" android:layout_centerHorizontal="true"/>编写java代码,细节在代码正文里public class MainActivity extends AppCompatActivity { private ProgressBar mProgressBar; private TextView mTextView; private int start=0,maxprogress; private Handler mHandler=new Handler(){ @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); switch (msg.what){ case 0: mTextView.setText(start+" %");//更新进度 mProgressBar.setProgress(start);break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mProgressBar = findViewById(R.id.progress_01); mTextView=findViewById(R.id.tv_progress); maxprogress=mProgressBar.getMax(); } @Override protected void onStart() { super.onStart(); //启动线程加载 new Thread() { @Override public void run() { while (true) { try { Thread.sleep(1000);//线程休眠1s int a = new Random().nextInt(10);//产生一个10以内的随机数 start += a; if (start > maxprogress)//如果过程超过最大值 break; mHandler.sendEmptyMessage(0);//在安卓里。咱们不能间接在线程中更新UI,这里用Hander音讯解决 } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); }}成果: ...

September 17, 2022 · 1 min · jiezi

关于android:TheRouter-页面跳转源码分析

TheRouter是什么TheRouter是货拉拉开源的 Android 平台中对页面、服务模块化整合开发、提供路由性能的中间件,提倡的是简略且够用。 Github: https://github.com/HuolalaTech/hll-wp-therouter-android 官网: https://therouter.cn 简略应用示例Activtiy跳转TheRouter.build("http://therouter.cn/test/activity").withString("name", "姓名").navigation();获取依赖服务// 假如以后有一个用户信息获取服务public interface IUserService { String getUserInfo();}// 服务提供方@ServiceProvider(returnType = IUserService.class)public static UserServiceImpl test() { xxx}// 服务应用方TheRouter.get(IUserService::class.java)?.getUserInfo()次要代码构造TheRouter ├─app │ └──代码应用示例Demo ├─business-a │ └──用于模块化业务模块的演示模块 ├─business-b │ └──用于模块化业务模块的演示模块 ├─business-base │ └──用于模块化根底模块的演示模块 ├─apt │ └──注解处理器相干代码 ├─plugin │ └──编译期 Gradle 插件源码 └─router └──路由库外围代码外围源码剖析TheRouter.build("http://therouter.cn/test/activity").withString("name", "姓名").navigation();从最罕用的跳转开始剖析,根本可理解到 TheRouter 的运行原理。这行实现跳转的代码最终成果是携带参数跳转到对应的 Activity,在 Android 层面来说最初肯定是通过调用 startActivity 或是 startActivityForResult 来实现跳转。 分为几步来看: TheRouter 调用 Build 生成 Navigator,过程是怎么的Navigator 是什么Navigator 调用 navigation 是怎么执行到 startActivity 的生成 Navigator通过查看源码TheRouter.build()实际上调用的是Navigator的构造方法, ...

September 16, 2022 · 4 min · jiezi

关于android:MobLink-Android端快速集成文档

开发工具:Android Studio集成形式:Gradle在线集成安卓版本反对:minSdkVersion 19集成前筹备注册账号应用MobSDK之前,须要先在MobTech官网注册开发者账号,并获取MobTech提供的AppKey和AppSecret,详情能够点击查看注册流程MobLink后盾配置注册完Mob账号后,须要在Mob后盾进行相干信息的配置,详情能够点击查看具体配置信息 MobLink流程图 增加配置在我的项目Gradle文件中注册 MobSDKbuildscript { repositories { // 1.增加MobSDK Maven地址 maven { url "https://mvn.mob.com/android" } ... } dependencies { ... // 2.注册MobSDK classpath "com.mob.sdk:MobSDK:2018.0319.1724" }}在我的项目App Module的Gradle文件中增加插件和扩大 // 增加插件apply plugin: 'com.mob.sdk'// 在MobSDK的扩大中注册MobLink的相干信息MobSDK { appKey "替换为mob官网申请的appkey" appSecret "替换为mob官网申请的appkey对应的appSecret" MobLink { uriScheme "您后盾配置的scheme" appLinkHost "您后盾开启AppLink时生成的Host" }}在gradle.properties中增加代码`MobSDK.spEdition=FP` 接口调用回传用户隐衷受权后果(submitPolicyGrantResult)为保障您的App在集成MobSDK之后可能满足工信部相干合规要求,您应确保App装置首次冷启动且获得用户浏览您《隐衷政策》受权之后,调用Mob提交到的隐衷协定回传函数MobSDK.submitPolicyGrantResult回传隐衷协定受权后果。 反之,如果用户不批准您App《隐衷政策》受权,则不能调用MobSDK.submitPolicyGrantResult回传隐衷协定受权后果。 相干隐衷申明请参考这个链接:合规指南 /** * com.mob.MobSDK.class * 回传用户隐衷受权后果 * @param isGranted 用户是否批准隐衷协定 */ public static void submitPolicyGrantResult(boolean isGranted)示例代码调用地位开发者能够本人指定,只需在应用SDK性能之前调用即可,强烈建议开发者在终端用户点击利用隐衷协定弹窗批准按钮后调用。MobSDK.submitPolicyGrantResult(true); 获取场景还原参数(setRestoreSceneListener) //com.mob.moblink/** * 全局场景还原监听器 * @param listener 回调监听 */ public static void setRestoreSceneListener(RestoreSceneListener listener)示例代码 ...

September 15, 2022 · 1 min · jiezi

关于android:京东金融客户端用户触达方式的探索与实践

一、对于用户触达用户触达:能够简略了解为通过某种形式将消息传递给用户的行为;触达的特定音讯从性能上可分展现、疏导落地两层。用户触达作为一种产品经营形式,曾经融入咱们日常生产流动的方方面面。在挪动互联网的世界里,咱们的产品离不开触达,用户流动也离不开触达。 二、为什么做用户触达以用户应用角度来看,用户在应用 App 的过程中会有一些与用户相干的零碎类的告诉,比方交易物流、客服音讯、账单信息,借还款揭示,实时资讯等音讯须要及时的给用户揭示; 以 APP 经营流动看,App 在日常经营过程中,依据以后的指标,联合流动向用户定向发送相干营销类信息,比方单品的流动信息或一些品类促销优惠等,疏导用户疾速进入流动页面; 因而触达在拉新、促活、留存、变现、自流传等经营流动中扮演者重要角色。这篇文章从 app 研发视角介绍下用户触达方面的一些实际。 三、触达用户的形式实际从 APP 的存活状态辨别,实现触达有两种形式,一种是:APP 非沉闷状态时的站外触达,次要蕴含:短信、Push、桌面小组件等 另一种是:APP 沉闷状态时的站内触达,次要蕴含站内弹窗、页面固定经营位,feed 流举荐位等。 上面介绍下一下咱们实现的几种触达形式及遇到的一些问题。 触达形式一:短信 短信起初利用最宽泛的场景是作为咱们交换沟通的一种形式,随着时代的倒退微信、QQ 等即时通讯类的 app 逐步代替了短信作为人与人沟通工具,然而因为短信可能及时稳固的将音讯同步给用户的特点,它仍是咱们当初应用比拟宽泛的音讯触达形式。常见的利用场景如:验证码告诉、还款揭示、账户变动、营销流动告诉等。咱们晓得作为一种触达形式,它的使命不仅是将音讯告诉到用户,对于特定的音讯还要能便捷的疏导用户跳转到 APP 内的相应的落地页。 短信的音讯触达能力是毋庸置疑的,尽管短信文本中间接放入的链接咱们也能够关上,然而确存在一些局限性,这种形式仅反对关上 web 页面,无奈跳转到 APP 原生页面,另外点击链接会先弹窗,由用户抉择关上链接的 app,这种体验相比间接关上 APP 指定页面来说大打折扣。因而,如何通过短信间接达到 APP 内,相应的落地页就是咱们须要解决的问题。google 提供了一种能使 Android 零碎间接通过网站地址关上应用程序对应内容页面,而不须要用户抉择应用哪个利用来解决网站地址的形式,即 Android App Links;其工作流程如下: 要增加 Android App Links 到利用中,须要在利用里定义通过 Http (s) 地址关上利用的 intent filter,并验证你的确领有该利用和该网站。 如果零碎胜利验证到你领有该网站,那么零碎会间接把 URL 对应的 intent 路由到你的利用。 1. 在 AndroidManifest 里配置用于零碎进行验证的 IntentFilter: 当 android:autoVerify="true" 呈现在你任意一个 intent filter 里,在 Android 6.0 及以上的零碎上装置利用的时候,会触发系统对 APP 里和 URL 无关的每一个域名的验证。验证过程设计以下步骤: ...

September 15, 2022 · 4 min · jiezi

关于android:百度App-Android启动性能优化工具篇

一、前言启动性能是APP的极为重要的一环,启动阶段呈现卡顿、黑屏问题,会影响用户体验,导致用户散失。百度APP在一些比拟低端的机器上也有相似启动性能问题,为保留存,须要对启动流程做深刻优化。现有的性能工具,无奈高效的发现、定位性能问题,归因剖析和防劣化老本很高,须要对现有工具进行二次开发,晋升效率。 丨1.1 工具选型 做好性能优化,不仅须要趁手的工具,而且对工具的要求还很高,具体来说,必须满足要求: 高性能,保障本身高性能,以防带偏优化方向多维度,能监控多维度信息,帮忙全面发现问题易用性,不便的可视化界面,不便剖析目前业界支流的APP性能探测工具有TraceView、CPU Profiler、Systrace、Perfetto。 Perfetto提供了弱小的Trace剖析模块:Trace Processor,能够把多种类型的日志文件(Android systrace、Perfetto、linux ftrace)通过解析、提取其中的数据,结构化为SQLite数据库,并且提供基于SQL查问的Python API,可通过python实现自动化剖析;同时有良好的可视化页面,可通过可视化页面查看火焰图和写SQL进行Trace剖析。 从性能、监控维度的丰盛水平和提供的配套的剖析和可视化工具来抉择,Perfetto是最好的抉择,但后期因为Perfetto是9.0当前默认内置服务然而默认不可用,Android 11服务才默认可用,对低版本零碎反对不够,所以咱们抉择了Systrace+Perfetto工具联合,可笼罩所有Android零碎。随着Perfetto继续迭代,减少了对低版本Android零碎反对,百度APP也全面切换到了Perfetto为根底采集和剖析性能工具。 丨1.2 二次开发 Trace采集 Perfetto收集App的Trace是通过Android零碎的atrace收集,须要本人手动增加Trace收集代码,增加Trace采集形式如下: Java/Kotlin:提供了android.os.Trace类,通过在办法开始和完结点成对增加Trace.beginSection和Trace.endSection;NDK:通过引入<trace.h>,通过ATrace\_beginSection() / Atrace\_endSection()增加Trace;Android零碎过程:提供了ATRACE\_*宏增加Trace,定义在libcutils/trace.h;在Android Framework和虚拟机外部会默认增加一些要害Trace,APP层须要手动增加,监控APP启动流程,有海量的办法,手动增加耗时耗力。百度APP大部分逻辑都是Java/Kotlin编写,Java/Kotlin代码会编译成字节码,在编译期间,可通过gradle transform批改字节码,咱们须要开发一套主动插桩的gradle插件,在编译时主动增加APP层Trace收集代码,实现监控APP层所有办法。 防劣化 随着优化继续上线,对性能指标会有肯定的正向收益,然而随着版本继续迭代,会有各种劣化问题,为保住优化成绩,咱们在线下每个版本公布之前都须要做真机启动性能测试,测试流程: 打包:须要打出主动插桩的包,须要一个基准包(上次公布版本的release分支的插桩包)和一个测试包(master分支的插桩包),用来做真机测试。 真机测试:用基准包和测试包手动跑启动相干case,启动Perfetto Trace抓取脚本,抓取Trace日志,会输入基准包Trace日志和测试包Trace日志,用作比照剖析。 比照剖析:Trace日志通过https://ui.perfetto.dev/ 关上可生成的火焰图,通过火焰图进行比照剖析,找到存在的劣化问题,这个流程是最耗时的,须要比照剖析的调用栈十分繁冗。 散发问题:梳理相干劣化问题,散发跟进对应业务负责同学。 这一整套流程实现,须要2人天,而比照剖析工作量最大,须要实现自动化剖析Trace日志性能,主动发现新增耗时、耗时劣化、锁期待等问题。 Perfetto提供了弱小的Trace剖析模块:Trace Processor,把多种类型的日志文件(Android systrace、Perfetto、linux ftrace)通过解析、提取其中的数据,结构化为SQLite数据库,并且提供基于SQL查问的python API,可通过python实现自动化剖析。 为提高效率,需基于Trace Processor的python API,开发一套Trace主动剖析工具集,实现疾速高效剖析版本启动劣化问题。 二、Perfetto介绍百度APP启动性能优化工具是基于Perfetto二次开发,上面对Perfetto的架构和原理做相应的介绍。 丨2.1 整体介绍 Perfetto是Google开源的一套性能检测和剖析框架。依照性能可分成3大块,Record traces(采集)、Analyze traces(剖析)、Visualize traces(可视化)。 Record traces Trace采集能力,反对采集多种类型的数据源,反对内核空间和用户空间数据源。 内核空间数据源是Perfetto内置的,须要零碎权限,次要的数据源包含: Linux ftrace:反对收集内核事件,如cpu调度事件和零碎调用等;/proc和/sys pollers:反对采样过程或者零碎维度cpu和内存状态;heap profilers:反对采集java和native内存信息;用户空间数据采集,Perfetto 提供了对立的Tracing C++库,反对用户空间数据性能数据收集,也可用atrace在用户层增加Trace收集代码采集用户空间Trace。 Analyze traces Trace剖析能力,提供Trace Processor模块能够把反对的Trace文件解析成一个内存数据库,数据库实现基于SQLite,提供SQL查问性能,同时提供了python API,百度APP也是基于Trace Processor开发了一套Trace自动化剖析工具集。 Visualize traces Perfetto还提供了一个全新的Trace可视化工具,工具是一个网站:https://ui.perfetto.dev/ 。在可视化工具中可导入Trace文件,并且可应用Trace Processor和SQLite的查问和剖析能力。 ...

September 15, 2022 · 4 min · jiezi

关于android:不惧繁杂背景视频编辑服务一键实现人像抠图

最近,“你这背景太假了”席卷全网。因为身后风光太柔美,被网友质疑背景太假,某主播为了自证,间接把手里的桶扔进了背地的水里。短短几天工夫播放量几十亿,引发了全网P图狂潮,网友在短视频App里将其人像抠出来,替换了不同的背景,各类创意视频很快冲上热搜。 现如今,视频人像抠图有着广泛应用。在直播App里能够为人像减少各种背景特效、贴纸道具等,提供更加丰盛的娱乐气氛;会议App里能够替换背景,爱护用户隐衷;教育类App中能够将背景替换为课件等内容;而在短视频App里人像抠图能给用户更多施展空间,无需绿幕拍摄和后期制作也能够轻松拍摄穿越时空的震撼大片。 那么,App如何实现一键提取人像性能呢?HMS Core视频编辑服务提供人像和头部宰割能力,反对对输出的视频或图片进行人像或头部宰割,生成宰割后的视频、图片或贴纸。 开发步骤1. 开发筹备具体筹备步骤可参考华为开发者联盟官网。 2. 编辑工程集成2.1 设置利用的鉴权信息 能够通过api_key或者Access Token来设置利用鉴权信息。 通过setAccessToken办法设置Access Token,在利用启动时初始化设置一次即可,无需屡次设置。 MediaApplication.getInstance().setAccessToken("your access token");通过setApiKey办法设置api_key,在利用启动时初始化设置一次即可,无需屡次设置。 MediaApplication.getInstance().setApiKey("your ApiKey");2.2设置惟一标识ID,即License ID。 License ID是进行管控的无效凭证,您要保障设置License ID的唯一性。 MediaApplication.getInstance().setLicenseId("License ID");2.2.1初始化Editor运行环境 创立编辑工程,须要首先创立Editor对象并初始化其运行环境。当来到编辑工程时,应开释Editor实例。 (1) 创立Editor对象 HuaweiVideoEditor editor = HuaweiVideoEditor.create(getApplicationContext());(2) 指定预览窗口的布局地位 预览窗口负责视频图像画面的渲染,由视频编辑原子能力SDK外部创立SurfaceView来实现。在创立窗口之前,须要在您的App中指定预览窗口的布局地位。 <LinearLayout android:id="@+id/video_content_layout" android:layout_width="0dp" android:layout_height="0dp" android:background="@color/video_edit_main_bg_color" android:gravity="center" android:orientation="vertical" />// 指定预览窗口 LinearLayout mSdkPreviewContainer = view.findViewById(R.id.video_content_layout);// 设置预览窗口承载的布局 editor.setDisplay(mSdkPreviewContainer);(3) 初始化运行环境,如果License鉴权失败,会抛出LicenseException。 当Editor对象创立之后,此时还没有占用理论的系统资源,须要手动抉择其环境初始化的机会,此时视频编辑原子能力SDK外部会创立必须的线程和定时器等。 try { editor.initEnvironment(); } catch (LicenseException error) { SmartLog.e(TAG, "initEnvironment failed: " + error.getErrorMsg()); finish(); return; }3. 人像和头部宰割能力集成// 初始化宰割AI引擎。segPart为int类型,值为1时,进行人像宰割;值为其余时,进行头部宰割visibleAsset.initBodySegEngine(segPart, new HVEAIInitialCallback() { @Override public void onProgress(int progress) { // 初始化进度 } @Override public void onSuccess() { // 初始化胜利 } @Override public void onError(int errorCode, String errorMessage) { // 初始化失败 }});// 宰割的处理结果胜利后,增加宰割AI特效visibleAsset.addBodySegEffect(new HVEAIProcessCallback() { @Override public void onProgress(int progress) { // 宰割AI特效解决进度 } @Override public void onSuccess() { // 宰割AI特效解决胜利 } @Override public void onError(int errorCode, String errorMsg) { // 宰割AI特效解决失败 }});// 中断宰割AI特效解决visibleAsset.interruptBodySegEffect();// 移除宰割AI特效visibleAsset.removeBodySegEffect();// 开释宰割AI引擎visibleAsset.releaseBodySegEngine();理解更多详情>> ...

September 15, 2022 · 1 min · jiezi

关于android:如何判断两张图片是否类似

如何判断两张图是否类似?查到了很多算法,流程都是“特征提取”,“特色比照”。以下列出了三个常见算法的通俗的介绍, 均匀哈希算法均匀哈希算法是三种Hash算法中最简略的一种,它通过上面几个步骤来取得图片的Hash值,这几个步骤别离是(1) 缩放图片;(2)转灰度图; (3) 算像素均值;(4)依据类似均值计算指纹。具体算法如下所示:失去图片的ahash值后,比拟两张图片ahash值的汉明间隔,通常认为汉明间隔小于10的一组图片为类似图片。 例子: 其中转为8x8尺寸的Lena对应的数据矩阵为: 很容失去如上矩阵所有元素的均值a= 121.328125, 将上述矩阵中大于或等于a的元素置为1, 小于a的元素置为0,可得: 所以可得Lena图的aHash为 1011111010011110100111011010100110101011101000110000111000101100 将二进制模式ahash转十六进制hash为 be9e9da9aba30e2c将两张图片进行均匀hash后,再计算出各自的汉明间隔 图Lena(noise): 图Barbara: 图汉明间隔: 感知哈希算法感知哈希算法是三种Hash算法中较为简单的一种,它是基于DCT(离散余弦变换)来失去图片的hash值(补充:对于DCT具体如何转换参考 https://www.jianshu.com/p/b92... ),其算法几个步骤别离是(1) 缩放图片;(2)转灰度图; (3) 计算DCT;(4)放大DCT; (5)算平均值;(6) 计算指纹。具体算法如下所示: 差别哈希算法相比pHash,dHash的速度要快的多,相比aHash,dHash在效率简直雷同的状况下的成果要更好,它是基于突变实现的。其算法几个步骤别离是(1) 缩放图片(2)转灰度图; (3)算差别值;(4)算平均值; (5)计算指纹。具体算法如下所示: 文章参考了:http://t.zoukankan.com/kalafi...具体均匀hash的测试代码详见:https://github.com/yuanting20... 本文由博客一文多发平台 OpenWrite 公布!

September 14, 2022 · 1 min · jiezi

关于android:FAQ接入HMS-Core广告服务中的常见问题总结和解决方法

HMS Core广告服务(Ads Kit)为开发者提供流量变现服务和广告标识服务,依靠华为终端能力,整合资源,帮忙开发者获取高质量的广告内容。同时提供转化跟踪参数服务,反对三方监测平台、广告主进行转化归因剖析。上面咱们分享一些开发者在接入广告服务中常常会碰到的问题,心愿给遇到相似问题的开发者提供参考。 1. 手机由竖屏转换成横屏时Banner广告尺寸变大怎么办? 解决方案: 固定BannerView的宽度或高度。例如下方的代码中固定了Banner广告的高度: <com.huawei.hms.ads.banner.BannerView android:id="@+id/hw_banner_view" android:layout_width="match_parent" android:layout_height="45dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" />Banner广告失常显示成果如下: 2. 应用示例代码测试时,原生广告不显示“为什么显示此广告”图标“i”和“不再显示此广告”图标“x”(即广告敞开按钮)怎么办? 起因剖析: 为了合乎本地合规的高要求,SDK减少了“不再显示此广告”的能力,且默认显示“不再显示此广告”的图标“x”。此图标只有在非中国大陆区域发行的设施上才会显示,因而在中国大陆发行的设施上测试时,是看不到的。 参考倡议: 如果App只在非中国大陆区域上线,是不影响应用的,能够应用非中国大陆区域发行的设施查看展现成果。 如果App只在中国大陆区域上线,须要用到敞开按钮时,倡议在原生广告布局中本人实现。 如果App是寰球上线,那么在本人实现敞开按钮的同时还须要留神,App在非中国大陆区域上线后,与默认展现的敞开按钮是否会抵触。 补充: “不再显示该广告”的性能是在原生广告设置选项NativeAdConfiguration.Builder中设置的,其提供的setRequestCustomDislikeThisAd()办法能够设置是否要自定义“不再显示该广告”的性能,默认为false。体现的模式如下: 如果设置为true,则会显示“为什么看到此广告”图标“i”,也就是下图所示: 当本人实现敞开按钮时,为了防止在非中国大陆区域上线的利用中呈现两个敞开按钮,倡议将其设置为true。 其次,能够通过调用NativeAdConfiguration.Builder().setChoicesPosition(int choicesPosition)办法设置图标显示的地位。 广告选项的展现地位: 3. 如何一次申请多个原生广告?原生广告提供了一次同时申请多个原生广告的办法loadAds()。 loadAds()申请有两个参数,除AdParam外,maxAdsNum是申请加载的最大广告数量,最大值为5。SDK返回的广告数量将会小于等于所申请的广告数量,并且返回的广告皆不雷同。示例代码如下所示: nativeAdLoader.loadAds(new AdParam.Builder().build(), 5);当加载广告胜利后,SDK会屡次调用NativeAd.NativeAdLoadedListener监听器的onNativeAdLoaded()办法别离返回一个NativeAd对象,在广告都返回后再调用AdListener监听器的onAdLoaded办法回调告诉此次申请胜利;当加载广告失败后,SDK会调用AdListener监听器的onAdFailed()办法。 示例代码如下所示,其中testy63txaom86"为测试专用的广告位ID,App正式公布时须要改为正式的广告位ID。 NativeAdLoader.Builder builder = new NativeAdLoader.Builder(this, "testy63txaom86");NativeAdLoader nativeAdLoader = builder.setNativeAdLoadedListener(new NativeAd.NativeAdLoadedListener() { @Override public void onNativeAdLoaded(NativeAd nativeAd) { // 广告加载胜利回调,多个广告对应多个回调 ... }}).setAdListener(new AdListener() { @Override public void onAdLoaded() { // 广告全副返回后回调,阐明所有广告返回胜利 ... } @Override public void onAdFailed(int errorCode) { // 广告加载失败回调 ... }}).build();nativeAdLoader.loadAds(new AdParam.Builder().build(), 5);阐明:再次应用NativeAdLoader加载广告前,请确保先前的申请曾经实现。 ...

September 14, 2022 · 1 min · jiezi

关于android:基于-React-Native-的动态列表方案探索

图片来自:https://unsplash.com 本文作者: wyl背景时至2022,精细化经营曾经成为了各大App厂商的强需要,阿里的 DinamicX、Tangram 大家应该都很相熟了,很多App厂商也自研了一些相似框架,基于DSL的动态化计划尽管有性能上的一些劣势,然而毕竟不是图灵齐备,一些须要逻辑动静下发的需要实现老本偏高,或因为DSL自身限度无奈实现,针对这个问题咱们应用RN进行了一下摸索尝试, 利用咱们曾经绝对欠缺的RN基建,联合客户端列表能力低成本的实现了一套的动态化能力,同时兼顾肯定的性能体验。 基于 ReactNative 的动静列表计划简略来说就是将 ReactNative 容器内嵌在 RecyclerView 的 ViewHolder 中,因为页面主体框架还是由 Native 开发和渲染,所以首屏加载速度失去了保障,部分的RN实现也使页面取得动态化的能力,从而在性能、”齐备逻辑执行“的动态化能力之间获得了一个平衡点,依据咱们应用教训对几种动态化计划排序如下: 整体性能体验排序:纯 Native > 基于DSL动态化计划 >= ReactNative 动静列表计划 > 纯 ReactNative 页面 > H5动静能力排序:H5 = 纯 ReactNative 页面 > ReactNative 动静列表计划 > 基于DSL动态化计划 > 纯 Native实现能力排序:纯 Native >= RN 动静列表计划 = 纯 ReactNative 页面 > H5 > 基于DSL的动态化计划从以上排序中能够看出 ReactNative 动静列表计划整体处于中等或中等偏上的一个地位,在实现能力上远胜余基于 DSL 动静计划,和 Native 能力根本对等,能够实现一些简单的UI交互成果,并且相比于纯 RN 实现的页面首屏速度会有十分大的劣势,另外不须要对页面整体框架进行更改就能比拟不便的嵌入,在开发保护老本上 RN 动静列表计划相比各种基于DSL的动态化计划会有比拟显著的劣势,不须要额定的开发组件治理平台,排查问题时也不必去读难懂的 dsl,最重要的是 RN 具备图灵齐备的能力,所以综合来看应用 RN 内嵌到 Native RecyclerView 来实现 Native 页面局部动态化的形式算是一种性价比绝对较高的形式了,值得一试。 ...

September 13, 2022 · 3 min · jiezi

关于android:ShareSDK-Android端权限说明

ShareSDK应用权限状况 去除非必须的权限一般权限去除能够在module模块中的build.gradle文件中增加以下的配置去除Gradle主动加载的可选权限办法,去除之后无需增加其余配置性能能够失常应用: permissions { exclude "须要去除的权限1", "须要去除的权限2"}比方须要去除掉“android.permission.READ_PHONE_STATE”权限,则间接增加如下配置即可: MobSDK { appKey "Mob开发者后盾申请的AppKey" appSecret "Mob开发者后盾申请的AppSecret" ShareSDK { devInfo { ... } } permissions { exclude "android.permission.READ_PHONE_STATE", }}QUERY_ALL_PACKAGES权限去除阐明:Android高版本(Android10以上)判断第三方平台是否装置须要应用QUERY_ALL_PACKAGES权限,如果没有这个权限ShareSDK分享、受权无奈应用,不过因为Google商店对QUERY_ALL_PACKAGES权限审核比拟严格,如您不心愿应用QUERY_ALL_PACKAGES权限,能够应用咱们提供exclude的形式去除QUERY_ALL_PACKAGES权限: MobSDK { appKey "Mob开发者后盾申请的AppKey" appSecret "Mob开发者后盾申请的AppSecret" ShareSDK { devInfo { ... } } permissions { exclude "android.permission.QUERY_ALL_PACKAGESE", }}须要留神的是去除QUERY_ALL_PACKAGES权限之后,须要在Manifest中通过"queries标签"手动配置一下须要应用的第三方平台包名,相似这样: <manifest package="xxxxxx"> ......<queries> <!--WhatsApp--> <package android:name="com.whatsapp" /> <!--Facebook--> <package android:name="com.facebook.katana" /> <!--Line客户端--> <package android:name="jp.naver.line.android" /> <!--Twitter--> <package android:name="com.twitter.android" /> <!--WeChat--> <package android:name="com.tencent.mm" /> <!--QQ--> <package android:name="com.tencent.mobileqq" /> <!--instagram--> <package android:name="com.instagram.android" /> <!--FacebookMessenger--> <package android:name="com.facebook.orca" /> <!--新浪微博--> <package android:name="com.sina.weibo" /> ...... </queries>......</manifest>可进入官网文档核心理解更多操作指南 ...

September 13, 2022 · 1 min · jiezi

关于android:Android打造专有hook让不规范的代码扼杀在萌芽之中

俗话说,无规矩不成方圆,同样的放在代码里也是非常的贴切,所谓在代码里的规矩,指的就是标准,在肯定标准束缚下的我的项目,无论是参加开发还是前期保护,都是十分的直观与便捷,不能说赏心悦目,也能够用强壮可保护来示意;毕竟协同开发的我的项目,每个人都有本人的一套开发规范,你没有一套标准,或者是标准没有落地执行,想想,长此以往,会产生什么?代码堆积如山?保护老本翻倍减少?新人接手艰难?等等,所谓的问题会扑面而来。 正所谓标准是一个我的项目的基石,也是掂量一个我的项目,是否强壮,稳固,可保护的规范,堪称是相当重要的。我置信,大部分的公司都有本人的一套标准规范,我也置信,很多可能就是一个陈设,毕竟人员的泛滥,无奈做到一一的束缚,如果采取人工的查看,有形当中就会投入大量的工夫和人力老本,基于此,所谓的标准,也很难执行上来。 介于人工和工夫的投入,我在以往的钻研与摸索中,开发出了一个可视化的代码查看工具,之前进行过分享,《一个便捷操作的Android可视化标准查看》,想理解的老铁能够看一看,本篇文章不做过多介绍,过后只介绍了工具的应用,没有介绍相干性能的开发过程,后续,有工夫了,我会整顿开源进去,始终忙于开发,老铁们,多体谅。这个可视化的查看工具,尽管大大提高了查看效率,也节俭了人力和工夫,但有一个潜在的弊病,就是,只能查看提交之后的代码是否符合规范,对于提交之前没有进行查看,也就说,在提交之前,标准也好,不标准也罢,都能提交上来,用工具查看后,进行批改,更改不标准的中央后而后再提交,只能采取这样的一个模式查看。 这样的一个模式,比拟合乎,最初的代码查看,实用于我的项目负责人,开发Leader,对组员提交上来的代码进行标准的审阅,其实并不适用于开发人员,不实用不代表着不可用,只不过绝对流程上略微简单了几步;应答这样的一个因素,如何实用于开发人员,不便在提交代码之前进行标准查看,便整体提上了研发日程,通过几日的钻研与编写,一个简略便捷的Android端Git提交专有hook,便应运而生了。 说它简略,是因为不须要编写任何的代码逻辑,只须要寥寥几步命令,便装置结束,通过配置文件,便可灵便定制属于本人的查看范畴。 为了更好的论述性能及讲述实现过程,便于大家定制本人的开发标准,再加上篇幅的束缚,我总结了四篇文章来进行零碎的梳理,还请大家,放弃关注,明天这篇,次要讲述最终的开发成绩,也就是标准工具如何应用,标准这个货色,其实大差不差,大家齐全能够应用我本人曾经开发好的这套。 这个工具的开发,利用的是git 钩子(hook),当然也是借助的是Node.js来实现的相干性能,下篇文章会具体介绍,咱们先来安装程序,来目击一下理论的成果,安装程序,只须要执行几步命令即可,无需代码染指,在理论的开发中须要开发人员,别离进行装置。 装置流程1、装置 Node.js,如果曾经装置,可间接第2步: Node.js中容许应用 JavaScript 开发服务端以及命令行程序,咱们能够去官网https://nodejs.org下载最新版本的安装程序,而后一步一步进行装置就能够了,这个没什么好说的,都是开发人员。 2、装置android_standard android_standard是最终的工具,外面蕴含着拦挡代码判断的各种逻辑 , 在我的项目根目录下执行如下命令: npm install android_standard --save-dev 执行完命令后,你会发现,你的我的项目下曾经多了一个目录,还有两个json文件,如下图所示: node_modules,用来寄存下载安装的包文件夹,外面有咱们要应用到的性能,其实和Android中lib目录很相似,都是一些提供性能的库。 package.json文件,是配置文件,比方利用的名字,作者,介绍,还有相干的依赖等,和Android中的build.gradle文件相似。 3、创立git配置文件,执行如下命令 node node_modules/android_standard/gitCommitConfig命令执行胜利会返回如下信息: 此命令执行完后,会在我的项目根目录下创立gitCommitConfig文件,这个文件很重要,是咱们执行相干命令的配置文件,内容如下,大家能够依据本人理论我的项目须要进行更改。 我的项目下生成gitCommitConfig.android文件,.android是我本人定义的,至于什么格局,等你本人开发的时候,齐全能够自定义,是个文件就行。 关上后,文件内容如下,此文件是比拟重要的,后续所有的标准查看,都要依据这个文件里的参数来执行,大家在应用的时候,就能够通过这个文件来操作具体的标准查看。 4、更改执行文件,执行如下命令 执行文件,就是须要在上边生成的package.json文件,增加运行程序,使其在git提交时进行hook拦挡。 node node_modules/android_standard/package5、增加git过滤 因为执行完上述命令后,会产生几个文件,而这几个文件是不须要咱们上传到近程仓库的,所以咱们须要在.gitignore文件里增加疏忽,间接复制即可。 /node_modulespackage.jsonpackage-lock.jsongitCommitConfig.android6、后续如果有更新,可操作命令进行操作: 注:此命令在更新时执行 npm update android_standard --save-dev 7、删除操作 注:后续不想应用了,便可执行如下命令: npm uninstall android_standard --save-dev具体应用通过上述的装置流程,短短几个命令,咱们的标准查看便装置结束,后续只须要通过gitCommitConfig.android文件,来动静的更改参数即可,是不是十分的不便,接下来,咱们来理论的操作一番。 对于配置文件的相干参数,也都有正文,一看便知,这里简略针对最初的参数,做一个阐明,也就是gitCommand这个参数,true为工具,false为命令形式;true也好,false也好,在次要的性能验证上,没有区别,惟一的区别就是,命令行的形式提交,会有色彩辨别,前面有成果。 咱们先来看下命令行下的执行成果,当配置文件开关gitCommitSwitch已开,并且gitCommand为false,其余的配置参数,大家能够依据须要进行改变,在代码提交的时候如下成果: 在Android studio中执行成果 TortoiseGit提交成果: 目前呢,针对Android端的标准查看,无论是java还是Kotlin,还是资源文件,都做了肯定的适配,通过多方测试,一切正常,如果大家的公司也须要这样的一个hook工具,欢送应用,也欢送持续关注接下来的相干实现逻辑文章。 好了各位老铁,这篇文章先到这里,下篇文章会讲述,具体的实现过程,敬请期待!

September 13, 2022 · 1 min · jiezi

关于android:手部骨骼跟踪能力打造控制虚拟世界的手势密码

AR作为一项加强事实技术,带来了虚构数字世界与事实世界的深度交融,这种虚实交融,不仅能利用于虚构汽车展现、虚构室内设计等视觉交互场景,更可通过动作交互管制虚拟世界场景,实现无边界的人机互动。 比方人们在拍摄短视频时,能够不接触屏幕,仅通过做出特定手势来管制特效切换;也能够在拍照时通过手势辨认管制快门拍摄;还能够实现试用美甲样式、戒指试戴等。以上AR利用场景需做到准确的手部辨认,这就要用到AR Engine的手部骨骼跟踪能力。 手部骨骼跟踪能力可辨认和跟踪21个手部关节点的地位和姿势,并输入手指端点、手掌朝向、手部骨骼等手部高级特色,造成手部骨骼模型。当图像中呈现多只手时,只反馈最清晰置信度最高的手的辨认后果和坐标信息,目前仅反对可获取深度信息的指定华为机型。 通过手部骨骼辨认能力,可将虚构物体叠加到更为准确的手部地位,例如手指尖、手掌心等;利用手部骨骼,可驱动虚构手做出更为丰盛和精密的操控动作,可能为AR利用提供加强的交互性能,便于拓展更多离奇的玩法。 手部骨骼定义图 利用场景 一、简略的手语翻译手部骨骼跟踪能力能够造成简略的手语了解。在对手部骨骼关键点进行提取的根底上,依据关键点的变动预测手部姿势,能够将蜿蜒、竖直等手指状态集映射到一组预约义的手势,比方食指直直伸出就代表计数手势“1”,通过此类算法推导出的手势动作,就是造成手语了解的根底,可利用于手语的辨认和翻译。 二、构建非接触式操作界面科幻电影中经常会呈现人物隔空操作电脑界面的场景,而此类性能基于手部骨骼跟踪能力也能够实现。 通过摄像头对手部骨骼的辨认跟踪,可精确定位指尖等要害节点信息,从而实现对虚构对象的物理交互。比方应用手指按下虚构按钮或其余UI元素;捏住虚构对象并开释菜单项;拉伸较大对象上的小指标等物理管制;甚至用手从新调整对象大小或将其存储在虚构口袋中等等。 该性能可利用于医疗行业的机械管制、机车界面管制等。 三、短视频直播互动AR Engine的手部骨骼跟踪能力也能够在短视频流传过程中削减一些手部特效,比方当用户在拍摄短视频或直播时做出比耶、点赞、比心等指定手部动作时,可辨认用户手势并叠加相应的特效或贴纸,实现手势触发特效、手部特效跟踪等成果,丰盛视频直播过程中的交互体验。 除此之外,手部骨骼跟踪能力还可利用于影视动画制作、儿童教学、医学痊愈、智能家居管制等畛域。 在AR技术疾速倒退的明天,基于手势辨认的人机交互已逐步成为热点,如何实现天然的、合乎人类习惯的手势辨认,是人机交互接口中的一个重要组成部分,作为手势辨认的一项根底能力,手部骨骼跟踪也凸显出了在该畛域的重要位置。华为AR Engine心愿该能力可能帮忙开发者们激发出更宽泛的钻研方向和更具创新力的理论利用。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

September 13, 2022 · 1 min · jiezi

关于android:Android中Activity的工作过程一

PS:本文系转载文章,浏览原文可读性会更好,文章开端有原文链接 PS:本文是基于 Android Api 26 来剖析源码的。Activity 作为四大组件之一,它外部工作过程零碎当然也是做了很多的封装,这种封装使得启动一个 Activity 变得异样简略。在显式调用的情景下,假如我用 MainActivity 启动 Main2Activity,那么通过如下代码即可实现;为了更好的理解显示启动 Activity 时两个 Activity 的申明周期办法调用过程,咱们先列出 MainActivity 和 Main2Activity 的代码;(1)MainActivity 代码;(2)Main2Activity 代码;运行一下 app,日志打印如下所示;看,跳转的过程中两个 Activity 的申明周期办法调用程序是这样的:MainActivity.onPause -> Main2Activity.onCreate -> Main2Activity.onStart -> Main2Activity.onResume -> MainActivity.onStop。因为下面提到的5个生命周期的流程波及到的源码比拟多,这里咱们先找 MainActivity 的 onPause 办法流程走向。MainActivity 启动 Main2Activity 时,它外部是怎么做到的呢?咱们看一下 Activity 的 startActivity(Intent intent) 办法的实现;startActivity(Intent intent) 办法调用了 Activity 的 startActivity(Intent intent, @Nullable Bundle options) 办法;因为 options 这个参数为空,所以执行的是正文2的代码块,咱们看一下 Activity 的 startActivityForResult(@RequiresPermission Intent intent, int requestCode) 办法;startActivityForResult(@RequiresPermission Intent intent, int reque-stCode) 办法调用了 Activity 的 startActivityForResult(@RequiresPermi-ssion Intent intent, int requestCode,@Nullable Bundle options) 办法;看,为什么会执行正文3的代码?这里首先要判断 mParent == null 是否为 true,mParent 就是以后 Activity 的父 Activity,而咱们的 Activity 是 MainActivity,它没有父类的 Activity,所以这里的 mParent == null 的后果是 true,实际上,mParent 罕用在 ActivityGroup 中,而在API 14开始 ActivityGroup 曾经废除。咱们看一下正文4的代码,mInstrumentation 是 Instrumentation 类型的对象,咱们看一下 Instrumentation 的 execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) 办法;咱们先看正文6的代码,看这个办法名,如同是查看启动 Activity 的后果,好吧,咱们先进去看一下 Instrumentation 的 checkStartActivityResult(int res, Object intent) 办法;外面有很多各种查看的后果,我省略了很多;看正文7,如果咱们没有在 AndroidManifest.xml 文件外面注册 Activity,那么就会抛出 Unable to find explicit activity class  have you declared this activity in your AndroidManifest.xml? 的异样。好,咱们当初回来看正文5的代码这里,ActivityManager.getService() 拿到的其实是 ActivityManagerService,所以咱们往下看 ActivityManagerService 的 startActivity(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) 办法;ActivityManagerService 的startActivity(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) 办法又调用了 ActivityManagerService 的 startActivityAsUser 办法;mActivityStarter 是一个ActivityStarter 实例对象,ActivityManagerService 的 startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) 办法调用了 ActivityStarter 的 startActivityMayWait(IApplicationThread caller, int callingUid,String callingPackage, Intent intent, String resolvedType,IVoiceInteractionSe-ssion voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int startFlags,ProfilerInfo profilerInfo, WaitResult outResult,Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,IActivityContainer iContainer, TaskRecord inTask, String reason) 办法;final int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer, TaskRecord inTask, String reason) { ...... synchronized (mService) { ...... //9、 int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, container, inTask, reason); ...... return res; }    }看正文9的代码,又调用了 ActivityStarter 的 startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,IVoiceInteractionSession voiceSession, IVoi-ceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,String callingPackage, int realCallingPid, int realCallingUid, int startFlags,ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,Activity-Record[] outActivity, ActivityStackSupervisor.ActivityContainer contain-er,TaskRecord inTask, String reason) 办法;看正文10的代码,又调用了 ActivityStarter 的 startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceIn-teractor,IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,String callingPackage, int realCallingPid, int realCallingUid, int startFlags,ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,Ta-skRecord inTask) 办法;看正文11,调用了 ActivityStarter 的 startActivity(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity) 办法;看正文12,调用到了 ActivityStarter 的 startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRec-ord[] outActivity) 办法;// Note: This method should only be called from {@link startActivity}. private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { ...... if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) { ...... } else { ...... //13、 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); } } else { ...... } ...... return START_SUCCESS; }看正文13的代码,因为我的 Main2Activity 的启动模式是 standard,所以会走这里,mSupervisor 是 ActivityStackSupervisor 类型的实例,咱们看一下 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLock-ed(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) 办法;看正文14,调用了 ActivityStack 的 resumeTopActivityUncheckedLo-cked(ActivityRecord prev, ActivityOptions options) 办法;看正文15,调用了 ActivityStack 的 resumeTopActivityInner-Locked(ActivityRecord prev, ActivityOptions options) 办法;看正文16,调用了 ActivityStack 的 startPausingLocked(boolean userLeaving, boolean uiSleeping,ActivityRecord resuming, boolean pauseImmediately) 办法;看正文17,prev.app.thread 是 ActivityThread 的外部类 ApplicatitonThread ,调用了 AppcationThread 的 schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) 办法;看正文18,因为 finished 为 false,所有第一个参数是 H.PAUSE_ACTIVITY,又调用了 ActivityThread 的外部类 H;看正文19,又调用了 ActivityThread 的 handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport, int seq) 办法;看正文20,又调用了 ActivityThread 的 performPauseActivity(IBinder token, boolean finished,boolean saveState, String reason) 办法;看正文21,又调用了 ActivityThread 的 performPauseActivity(Activit-yClientRecord r, boolean finished,boolean saveState, String reason) 办法;看正文22,又调用了 ActivityThread 的 performPauseActivity-IfNeeded(ActivityClientRecord r, String reason) 办法;看正文23,mInstrumentation 是 Instrumentation 类型的对象,所以调用了 Instrumentation 的 callActivityOnPause(Activity activity) 办法;看正文24,调用了 Activity 的 performPause 办法;看到正文25了没有,Activity 的 onPause 办法曾经找到,咱们的指标曾经实现,所以这篇文章到这里就写完了。 ...

September 12, 2022 · 4 min · jiezi

关于android:为什么最近每份-Android-简历都说-熟悉-MQTT-协议

请点赞关注,你的反对对我意义重大。 Hi,我是小彭。本文已收录到 GitHub · AndroidFamily 中。这里有 Android 进阶成长常识体系,有气味相投的敌人,关注公众号 [彭旭锐] 带你建设外围竞争力。 前言大家好,我是小彭。 MQTT 是一种基于公布 - 订阅模型的消息传递协定,在物联网和挪动利用有较宽泛的利用。如果你的指标是冲击中高级工程师岗位,MQTT 或者是一个不错的亮点。最近,我还发现很多候选人会在简历中写本人 “相熟 MQTT 协定”,但少数人只是停留在理解或用过的水平。 这篇文章里,我将与你探讨 MQTT 协定的 工作原理 & 协定音讯格局 & 外围个性,实战的局部咱们会在下篇文章中探讨。如果能帮上忙,请务必点赞加关注,给小彭一点创作的能源。 记录:2022 年 9 月 9 日订正:优化文章构造 学习路线图: 1. 意识 MQTT1.1 什么是 MQTT?MQTT (Message Queuing Telemetry Transport,音讯队列遥测传输) 是一种基于 TCP/IP 协定族的应用层协定。MQTT 协定是专门针对硬件性能低下 & 网络情况不稳固的场景设计的,这使得 MQTT 在物联网和挪动利用等受限场景失去广泛应用。 1.2 MQTT 协定的倒退历史1999 年:Andy Stanfork-Clark (IBM) 和 Arlen Nipper 公布 MQTT 协定,用于通过卫星连贯石油管道遥测零碎,MQTT 中的 TT (Telemetry Transport) 就是源于这样一个遥测零碎;2010 年:MQTT 协定收费公布;2014 年:MQTT 协定正式成为 OASIS 规范,通过多年的倒退,MQTT 协定曾经成为互联网 (IoT) 的次要协定之一。目前,MQTT 次要分为两个大版本: ...

September 9, 2022 · 6 min · jiezi

关于android:如何让开发者直接在应用后台控制用户的运动状态

酷暑终于过来,很多人伴着凉快的秋风开启了新一轮的健身打算。当用户进行户外运动或应用跑步机、椭圆机等器械时,他们会心愿在静止衰弱类App里点击即可开启静止并记录静止数据。而对于开发者本人开发的利用来说,用户在应用跟华为衰弱App绑定的静止设施静止时,能够间接在本人的App后盾管制用户静止状态并获取实时数据,不须要再从华为衰弱App里进行操作。 那么,对于静止衰弱App来说,如何实现以上性能呢?HMS Core静止衰弱服务的扩大能力服务凋谢更多实时静止和衰弱数据、静止和衰弱解决方案场景化数据。其中管制静止并获取实时静止数据能力提供了开始、暂停、复原和完结静止的接口,开发者能够间接在利用内调用接口,后盾管制静止衰弱App中对应静止状态,无需跳转到华为静止衰弱App静止界面进行操作,此时静止衰弱App不会弹出静止页面,而是在后盾执行。 同时华为也提供了获取实时静止数据和进行获取实时静止数据的接口,为避免数据失落,个别在开始静止之前调用获取实时静止数据接口,在进行静止之后调用进行获取实时静止数据接口。如果用户绑定了华为穿戴设施,启动静止时,穿戴设施将主动进入静止界面;完结静止时,穿戴设施将主动完结静止。应用接口前,须要向华为申请开明权限,并获取用户受权,否则接口将调用失败。目前反对的静止类型:户外步行、户外跑步、户外骑行、室内跑步(跑步机)、椭圆机、划船机、室内单车。具体场景获取的数据类型请参考实时静止 Bundle 对象键值。 前台静止跳转设施配对页面 Demo 开发步骤开发筹备1. 申请Health Kit服务 申请Health Kit服务前,请先实现申请帐号服务。 2 .集成 HMS Core SDK 集成SDK之前,请先集成华为帐号服务SDK。 在开始开发前,请先将SDK集成到Android Studio开发环境中。Android Studio应为V3.3.2及以上版本。 开发步骤1 .开始获取实时静止数据 调用HiHealthDataStore对象的registerSportData办法,开始获取实时静止数据。通过申请参数HiSportDataCallback对象,返回查问后果,后果中数据类型参考实时静止 Bundle 对象键值。示例代码: HiHealthDataStore.registerSportData(context, new HiSportDataCallback() { @Override public void onResult(int resultCode) { // 接口调用后果 Log.i(TAG, "registerSportData onResult resultCode:" + resultCode); } @Override public void onDataChanged(int state, Bundle bundle) { // 实时数据变动回调 Log.i(TAG, "registerSportData onChange state: " + state); StringBuffer stringBuffer = new StringBuffer(""); if (state == HiHealthKitConstant.SPORT_STATUS_RUNNING) { Log.i(TAG, "heart rate : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_HEARTRATE)); Log.i(TAG, "distance : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_DISTANCE)); Log.i(TAG, "duration : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_DURATION)); Log.i(TAG, "calorie : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_CALORIE)); Log.i(TAG, "totalSteps : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_TOTAL_STEPS)); Log.i(TAG, "totalCreep : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_TOTAL_CREEP)); Log.i(TAG, "totalDescent : " + bundle.getInt(HiHealthKitConstant.BUNDLE_KEY_TOTAL_DESCENT)); } }});2. 进行获取实时静止数据 ...

September 9, 2022 · 2 min · jiezi

关于android:RTC-脚手架的设计和实现

图片起源:https://699pic.com/tupian-401... 作者:AirLand 什么是 RTC?RTC 即 Real-Time Communication 的简称是一种给行业提供高并发、低延时、高清晦涩、安全可靠的全场景、全互动、全实时的音视频服务的终端服务。下面是比拟官网的解释,艰深的来讲就是一种可能实现一对一、多对多音视频通话等泛滥性能的服务。目前提供该项服务的服务商有很多例如:声网、云信、火山引擎、腾讯云等。 背景目前云音乐旗下 APP 泛滥,其中波及到 RTC 业务的不在少数,例如:常见的音视频连麦、PK、派对房,1v1 聊天等。因为业务线不同,性能不同,开发者也不同,大家各写一套,一直的反复造轮子,因而为了防止反复的开发工作晋升开发效率,须要有一套通用的RTC框架。 设计思路在讲具体的方案设计之前,先讲一下我的设计思路: 性能内聚:须要将性能都封装在一个容器里,对外通过接口提供办法调用业务隔离:不同的业务须要有不同的性能容器对立调用:所有性能容器须要有对立的调用入口状态保护:须要对状态进行精准保护切换无感:进行性能容器切换时候,无感知外围可控:对外围链路可监控,故障预警基于以上 6 点,大抵的架构设计如图所示,这里先不必深究图中的模块示意什么,前面会讲到,这里只是先理解一下大抵的架构: 接下来我就来讲讲具体的实现过程。 方案设计前言:RTC 的业务场景尽管很多,但实质上却相差无几,都是用户退出到一个独特的房间,而后在房间内进行实时的音视频通信。具体到理论我的项目中大抵又可分为两种:全场景 RTC 和局部场景 RTC。 全场景 RTC :整个业务都是通过 RTC 技术实现例如:1v1 音视频通话、派对房等。局部场景 RTC:即整个业务链路中只有一部分应用了 RTC 技术,往往这种业务会波及到引擎的切换。不论是哪一种场景,承载外围性能的引擎都是必不可少的,因而咱们首先就从引擎开始着手,另外为了不便形容,后续便将引擎对立称作 Player。 1、Player 的封装在与 RTC 相关联的业务中会波及到不同类型的 Player,例如:主播开播(推流 Player),观众观看直播(拉流 Player)以及 RTC Player等。它们的性能尽管各不相同,但用法却有相似之处,例如都有启动 start,终止 stop 等。因而咱们能够将不同的 Player 形象出一个独特的接口 IPlayer 相干代码如下: interface IPlayer<DS : IDataSource, CB : ICallback> { fun start(ds: DS) fun stop() fun <T : Any> setParam(key: String, value: T?) ......}其中 IDataSource 和 ICallback 别离是启动 Player 所须要的数据源和回调,前面的文章中也会屡次提到,特地是 IDataSource 它是 Player 启动的源头就好比打电话时的电话号码。 ...

September 8, 2022 · 3 min · jiezi

关于android:ViewBinding-与-Kotlin-委托双剑合璧

请点赞关注,你的反对对我意义重大。 Hi,我是小彭。本文已收录到 GitHub · Android-NoteBook 中。这里有 Android 进阶成长常识体系,有气味相投的敌人,关注公众号 [彭旭锐] 带你建设外围竞争力。 前言ViewBinding 是 Android Gradle Plugin 3.6 中新增的个性,用于更加轻量地实现视图绑定(即视图与变量的绑定),能够了解为轻量版本的 DataBinding。 在这篇文章里,我将总结 ViewBinding 应用办法 & 原理,示例程序 AndroidFamilyDemo · KotlinDelegate 有用请记得给 Star ,给小彭一点创作的能源。 前置常识: Kotlin | 委托机制 & 原理 & 利用Kotlin | 扩大函数(终于晓得为什么 with 用 this,let 用 it)Java | 对于泛型能问的都在这里了(含Kotlin)Android | Fragment 外围原理 & 面试题 (AndroidX 版本)学习路线图 1. 意识 ViewBinding1.1 ViewBinding 用于解决什么问题?ViewBinding 是 Android Gradle Plugin 3.6 中新增的个性,用于更加轻量地实现视图绑定(即视图与变量的绑定),能够了解为轻量版本的 DataBinding。 1.2 ViewBinding 与其余视图绑定计划比照在 ViewBinding 之前,业界曾经有过几种视图绑定计划了,想必你也用过。那么,ViewBinding 作为后起之秀就肯定比前者香吗?我从多个维度比照它们的区别: ...

September 8, 2022 · 9 min · jiezi

关于android:ShareSDK-Android端分享与授权示例代码

本文意在提供更便捷的分享和受权代码,仅供参考,心愿能够给你带来更欢快的开发情绪: 分享分享分为两种形式:第一种通过OneKeyShare一键九宫格分享,第二种指定平台分享 一键九宫格分享多个平台一键分享指的是通过OneKeyShare九宫格界面分享多个平台,不同平台分享不同的数据类型请参考: OnekeyShare oks = new OnekeyShare();oks.setShareContentCustomizeCallback(new ShareContentCustomizeCallback() { @Override public void onShare(Platform platform, cn.sharesdk.framework.Platform.ShareParams paramsToShare) { //微博分享链接和图文 if ("SinaWeibo".equals(platform.getName())) { paramsToShare.setText("玩美夏日,护肤也要肆意玩酷!" + "www.mob.com"); paramsToShare.setImageUrl("https://hmls.hfbank.com.cn/hfapp-api/9.png"); } //微信好友分享网页 if ("Wechat".equals(platform.getName())) { paramsToShare.setTitle("题目"); paramsToShare.setText("我是共用的参数,这几个平台都有text参数要求,提取进去啦"); paramsToShare.setImageUrl("https://hmls.hfbank.com.cn/hfapp-api/9.png"); paramsToShare.setUrl("http://sharesdk.cn"); paramsToShare.setShareType(Platform.SHARE_WEBPAGE); Log.d("ShareSDK", paramsToShare.toMap().toString()); } //微信朋友圈分享图片 if ("WechatMoments".equals(platform.getName())) { paramsToShare.setTitle("题目"); paramsToShare.setText("我是共用的参数,这几个平台都有text参数要求,提取进去啦"); /*Bitmap imageData = BitmapFactory.decodeResource(getResources(), R.drawable.logo); paramsToShare.setImageData(imageData);*/ paramsToShare.setImageUrl("https://hmls.hfbank.com.cn/hfapp-api/9.png"); paramsToShare.setShareType(Platform.SHARE_IMAGE); Log.d("ShareSDK", paramsToShare.toMap().toString()); } //QQ分享链接 if ("QQ".equals(platform.getName())) { paramsToShare.setTitle("题目"); paramsToShare.setTitleUrl("http://sharesdk.cn"); paramsToShare.setText("我是共用的参数,这几个平台都有text参数要求,提取进去啦"); paramsToShare.setImageUrl("https://hmls.hfbank.com.cn/hfapp-api/9.png"); Log.d("ShareSDK", paramsToShare.toMap().toString()); } //支付宝好友分享网页 if ("Alipay".equals(platform.getName())) { paramsToShare.setTitle("题目"); paramsToShare.setText("我是共用的参数,这几个平台都有text参数要求,提取进去啦"); paramsToShare.setImageUrl("https://hmls.hfbank.com.cn/hfapp-api/9.png"); paramsToShare.setUrl("http://sharesdk.cn"); paramsToShare.setShareType(Platform.SHARE_WEBPAGE); Log.d("ShareSDK", paramsToShare.toMap().toString()); } //Facebook以卡片模式分享链接 if ("Facebook".equals(platform.getName())) { // paramsToShare.setText("我是共用的参数,这几个平台都有text参数要求,提取进去啦"); paramsToShare.setImageUrl("https://hmls.hfbank.com.cn/hfapp-api/9.png"); paramsToShare.setUrl("http://www.mob.com"); paramsToShare.setShareType(Platform.SHARE_WEBPAGE); paramsToShare.setQuote("我是共用的参数"); paramsToShare.setHashtag("测试话题分享"); } //Twitter分享链接 if("Twitter".equals(platform.getName())){ paramsToShare.setText("我是共用的参数,这几个平台都有text参数要求,提取进去啦"); paramsToShare.setImageUrl("https://hmls.hfbank.com.cn/hfapp-api/9.png"); paramsToShare.setUrl("http://sharesdk.cn"); } //WhatsApp分享图片 if ("WhatsApp".equals(platform.getName())) { paramsToShare.setImageUrl("https://hmls.hfbank.com.cn/hfapp-api/9.png"); } //短信分享文本 if("ShortMessage".equals(platform.getName())){ paramsToShare.setText("我是共用的参数,这几个平台都有text参数要求,提取进去啦"); paramsToShare.setTitle("题目"); paramsToShare.setAddress("17625325208"); } }});oks.setCallback(new PlatformActionListener() { @Override public void onComplete(Platform platform, int i, HashMap<String, Object> hashMap) { Log.d("ShareLogin", "onComplete ----> 分享胜利"); } @Override public void onError(Platform platform, int i, Throwable throwable) { Log.d("ShareLogin", "onError ----> 失败" + throwable.getStackTrace()); Log.d("ShareLogin", "onError ----> 失败" + throwable.getMessage()); } @Override public void onCancel(Platform platform, int i) { Log.d("ShareLogin", "onCancel ----> 分享勾销"); }});// 启动分享GUIoks.show(MobSDK.getContext());指定平台分享支流平台分享示例 ...

September 8, 2022 · 3 min · jiezi

关于android:开发者必读2022年移动应用技术趋势白皮书

华为开发者联盟和艾瑞征询联结公布《2022年挪动利用技术趋势白皮书》,本白皮书通过盘点国内挪动利用倒退环境、热门技术创新动静,剖析影响挪动利用倒退的技术趋势,以及细分应用领域的技术创新热点,洞悉开发者所面临的挑战和时机,帮忙开发者厘清一直倒退的技术场面,提供可落地的行业洞察。 华为开发者联盟始终致力于全方位联接寰球开发者,以当先技术和凋谢能力赋能开发者翻新,以丰盛多元的经营推广资源减速开发者商业胜利,携手寰球开发者共建HMS生态瘠田。以下内容摘自白皮书。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

September 8, 2022 · 1 min · jiezi

关于android:没错TheRouter-是我写的

没错,货拉拉开源的路由库 —— TheRouter 是我写的 大概在17年底到18年初的时候,我常常会讲一些过后做模块化开发的心得和踩坑历程。比方这几篇都是那时候写的:《Android 模块化平台设计》、《优雅移除模块间耦合》、《企业级 Android 模块化平台设计倡议》。 但起初我缓缓不讲这些了,因为我发现做模块化,尽管咱们能总结进去一套较为通用的解决方案,但很难通过几次短短的技术分享就跟他人讲清楚。并且很容易让人产生误解:咱们是小公司,不须要做模块化。再加上因为过后是基于公司已有的根底建设,和制度的一些限度,并不能对外开源一套较为欠缺的模块化计划,开源一套残缺的模块化计划这个种子就始终埋下了。 说回 TheRouter这个名字,其实相熟我的都晓得,之前写过一个开源类 MVP 框架,叫TheMVP,基本上成为了一种将Activity看做 P 层架构的行业标准。起初被支付宝应用了,也在 设置-对于-版权信息 外面能查到,直到前几天我去反编译的时候,都还看到BaseActivity用的是我的代码。 The 代表了一种唯一性,示意有这个就够了。 TheRouter也是一样,我置信用过TheRouter当前你才会真正意识到,当初的企业级Android模块化应该怎么玩。 为什么要应用 TheRouter路由是现如今 Android 开发中必不可少的性能,尤其是企业级APP,能够用于将Intent页面跳转的强依赖关系解耦,同时缩小跨团队开发的相互依赖问题。 对于大型 APP 开发,根本都会选用模块化(或组件化)形式开发,对于模块间解耦要求更高。 TheRouter 是一整套齐全面向模块化开发的解决方案,不仅能反对惯例的模块依赖解耦、页面跳转,同时提供了模块化过程中常见问题的解决办法。例如:完满解决了模块化开发后组件内无奈获取 Application 生命周期与业务流程,造成每次初始化与关联依赖调用都须要跨模块批改代码的问题。 不过为什么要用,说到底,还是用ARouter用的太头疼了。 一个是死板,所有路由都是写死的,凡是想灵便一点,把线上Crash的页面降级成H5长期解决,都得改一大堆代码还很多限制性。另一个就是效率,不论是编译时长还是启动耗时,这俩问题都始终不解决。某个厂的开源我的项目都这样,作者们该降职的降职,该转岗的转岗,剩下的躺平不论,毕竟修修补补这事不占KPI,没法述职啊。没方法,本人来吧,谁让咱们还有启动耗时指标的。再就是遇到的一个坑,在用tinker下发补丁的时候,发现同一个分支打进去的包,ARouter和Butterknife的产物包代码都不一样,间接增大了补丁体积。当然,还有很多差别,看这个表格吧。性能TheRouterARouterWMRouterFragment路由✔️✔️✔️反对依赖注入✔️✔️✔️加载路由表无运行时扫描无反射运行时扫描dex反射实例类性能损耗大运行时读文件反射实例类性能损耗中注解正则表达式✔️✖️✔️Activity指定拦截器✔️(四大拦截器可依据业务定制)✖️✔️导出路由文档✔️(路由文档反对增加正文形容)✔️✖️动静注册路由信息✔️✔️✖️APT反对增量编译✔️✔️(开启文档生成则无奈增量编译)✖️plugin反对增量编译✔️✖️✖️多 Path 对应同一页面(低成本实现双端path对立)✔️✖️✖️远端路由表下发✔️✖️✖️反对单模块独立初始化✔️✖️✖️反对应用路由关上第三方库页面✔️✖️✖️反对应用路由关上第三方库页面✔️✖️✖️对热修复反对(例如tinker)✔️(未扭转的代码屡次构建无变动)✖️(屡次构建apt产物会发生变化,生成无意义补丁)✖️(屡次构建apt产物会发生变化,生成无意义补丁)动静页面路由能力其实单纯的页面路由,没什么好说的,基本上所有人都是这么做的。APT编译期生成一个形容类,gradle插件聚合所有的形容类,利用启动的时候再加载形容类,就这么一个流程。TheRouter 文档外面写的十分具体了,这里次要讲讲路由在古代APP中要怎么用。 TheRouter 从设计阶段,思考的就是APP动态化能力。所以既能反对第三方SDK的路由跳转,也能反对插件化的开发状态,又能解决H5Hybrid、Flutter混合的这种我的项目,反正路由表都是能够轻易增加。 那,真正用途最多的是通过动静下发,晋升客户端容灾能力。 比方在线上,某些页面或者外围下单交易流程因为客户端开发忽略,造成无奈应用的状况,能够通过路由将对应页面降级为H5或者小程序,保障线上APP仍然是可用的状态。 有两种举荐的近程下发形式可供使用方抉择: 将打包零碎与配置零碎买通,每次新版本APP打包后主动将assets/目录中的配置文件上传到配置零碎,下发给对应版本APP 。长处在于全自动不会出错。配置零碎无奈买通,线上手动下发须要批改的路由项,因为 TheRouter 会主动用最新下发的路由项笼罩包内的路由项。长处在于准确,且流量资源占用小。注:一旦你设置了自定义的InitTask,原框架内路由表初始化工作将不再执行,你须要本人解决找不到路由表时的兜底逻辑,一种倡议的解决形式见如下代码。 // 此代码 必须 在 Application.super.onCreate() 之前调用RouteMap.setInitTask(new RouterMapInitTask() { /** * 此办法执行在异步 */ @Override public void asyncInitRouteMap() { // 此处为纯业务逻辑,每家公司远端配置计划可能都不一样 // 不倡议每次都申请网络,否则申请网络的过程中,路由表是空的,可能造成APP无奈跳转页面 // 最好是优先加载本地,而后开异步线程加载远端配置 String json = Connfig.doHttp("routeMap"); // 倡议加一个判断,如果远端配置拉取失败,应用包内配置做兜底计划,否则可能造成路由表异样 if (!TextUtils.isEmpty(json)) { List<RouteItem> list = new Gson().fromJson(json, new TypeToken<List<RouteItem>>() { }.getType()); // 倡议远端下发路由表差别局部,用远端包笼罩本地更正当 RouteMap.addRouteMap(list); } else { // 在异步执行TheRouter外部兜底路由表 initRouteMap() } }});另一种状况,如果某些页面传参过程中,漏传了一些固定参数,也能够通过动静下发路由表的形式,对不同的页面,做动静的默认参数注入,这样就能达到不发版也能间接修复某些参数引起的小问题。 ...

September 7, 2022 · 2 min · jiezi

关于android:Android极简MVVM从一个基类库谈起

Hello啊各位老铁,明天带来一个陈词滥调的技术,MVVM,这篇文章,次要具体介绍如何封装一个MVVM的基类库,以及MVVM架构模式在理论业务中的用法,最初会把理论的封装代码开源,并提供近程依赖,不便给到大家应用以及二次批改,尽量做到细致入微,浅显易懂,OK,废话不多赘述,咱们进入注释。 这篇文章大略会依照以下几个模块进行论述,此次封装,做到绝无第三方依赖,都是Android原生的代码封装,请放心使用,如果您想间接进行应用,请间接跳到第4步,集成应用即可,此次的封装,和目前支流的MVVM架构模式,会完满符合,让架构模式简单化,让业务代码清晰化,必须值得举荐应用。 一、MVVM简略概括 二、基于MVVM模式如何封装基类库 三、实战封装 四、封装后在业务中如何应用 五、开源以及Demo查看 舒适提醒:内容稍多,请合理安排好工夫,如果不想查阅具体封装过程,底部有开源地址,能够间接查看。一、MVVM简略概括MVVM的开发模式,相对来说低耦合,业务之间逻辑显得也非常明显,Model层负责将申请的数据交给ViewModel层;ViewModel层负责将申请到的数据做业务逻辑解决,最初交给View层去展现,与View一一对应;View层只负责界面绘制刷新,不解决业务逻辑,非常适合进行独立模块开发。 三层简略概括1、Model:数据层,蕴含数据实体和对数据实体的操作。 2、View:视图层,对应于Activity,XML,View,负责数据显示以及用户交互。 3、ViewModel:关联层,将Model和View进行绑定,Model或者View更改时,实时刷新对方。 须要留神:1、View只做和UI相干的工作,不波及任何业务逻辑,不波及操作数据,不解决数据,也就是UI和数据是严格离开的。 2、ViewModel只做和业务逻辑相干的工作,不波及任何和UI相干的操作,不持有控件援用,不更新UI。 二、基于MVVM模式如何封装基类库MVVM咱们曾经清晰,然而针对现有的三层,咱们如何进行拆解封装呢?面对这样的一个问题,咱们也是须要从三层以及和理论的业务进行相结合,从理论业务中来,也要从理论业务中去,这是咱们封装的一个潜在因素,一旦脱离了理论,封装的再优良,也只是一个花瓶,中看不中用。 针对MVVM中的三层,其实,咱们在封装中,也是基于这三层,View,ViewModel和Model。View中,在理论的开发中,个别针对Activity和Fragment进行零碎的抽取封装,ViewModel个别会抽取一个父类,做一些公共的办法或属性配置,Model层个别封装的较少,依据理论业务,须要具体问题具体分析。 Activity和Fragment的封装思路,其实是统一的,须要以简略和简单两种方向进行抽取,一种是简略的页面继承应用,一种是简单的页面继承应用,这样辨别的一个目标,就是,专职专用,防止大材小用,而具体的封装,除了使得代码简洁化,更重要的拓展化,不便子类的调用。 在具体封装的时候,与理论业务相结合,这个无比重要,比方理论的大部分页面,都带有一个标题栏,那么标题栏就能够间接封装父类外面,像子类拓展出,更改题目,右侧按钮,左侧按钮等功能属性;除了对立的标题栏,另外就是子类的视图了,对于子类的视图传递,这个是必须的,能够间接形象出一个必须要实现的办法,其余的,比方状态栏的扭转,缺省页的设置等等,也须要在父类中对立的给出。 简单的页面是基于简略的页面而来的,这里的简单,个别是蕴含很多逻辑的解决,那么,咱们就能够减少ViewModel层和Model层了,目前基于DataBinding的实现形式,无论简略和简单,都是必须须要思考的,也就是说在父类中,咱们就须要向子类提供出能够拿到的databinding和viewmodel,个别以泛型的形式引入,这样子类再继承的时候,就能够很不便的进行调用。 在简单的页面,也就是蕴含ViewModel层和Model层的时候,须要思考绑定视图variable的传递,也就是以后的ViewModel和那个xml进行绑定,当然这是在须要的时候,必须要操作的,除了视图绑定,常见的,数据申请状态,比方申请胜利,申请失败,缺省页显示和暗藏,Dialog的显示和暗藏,LiveData的数据回传等等,在简单的页面中也是须要咱们思考的,除此之外,ViewModel中如何和View层的生命周期绑定,在理论的业务中也是不得不须要思考的。 除了以上的惯例思考,在理论的业务中,比方事件消息传递,PagerAdapter应用,状态栏通明等很多和基类的相干的性能,咱们其实也能够进行封装进去,便于子类的调用。 三、实战封装通过第2条中的拆解和具体的封装思路,无妨咱们进行实战一下,因为Activity和Fragment的封装思路以及相干属性和办法,大部分都是雷同的,所以目前只介绍Activity,更具体的封装,还请大家参考源码。 1、Activity的简略封装简略封装,不携带ViewModel,只传递ViewDataBinding,子类必须重写的办法只有一个initData,其余均为选择性重写,如果绝对逻辑比较简单的页面,能够继承此类。 一个很简略的一般封装,就是把共有的常见的,封装到父类里,便于子类的调用,具体什么办法,什么逻辑进行采取封装,须要咱们依据具体业务或者公司的相干状况而定,以下是源码。 abstract class BaseActivity<VB : ViewDataBinding>(@LayoutRes layoutId: Int = 0) : AppCompatActivity(layoutId) { private var mActionBarView: ActionBarView? = null private var mLayoutError: LinearLayout? = null private var mLayoutId = layoutId lateinit var mBinding: VB override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) try { //默认状态栏为白底黑字 darkMode(BaseConfig.statusBarDarkMode) statusBarColor(ContextCompat.getColor(this, BaseConfig.statusBarColor)) setContentView(R.layout.activity_base) val baseChild = findViewById<LinearLayout>(R.id.layout_base_child) mLayoutError = findViewById(R.id.layout_empty_or_error) mActionBarView = findViewById(R.id.action_bar) if (mLayoutId == 0) { mLayoutId = getLayoutId() } if (savedInstanceState != null && getIntercept()) { noEmptyBundle() return } val childView = layoutInflater.inflate(mLayoutId, null) baseChild.addView(childView) mBinding = DataBindingUtil.bind(childView)!! initView() initData() } catch (e: Exception) { e.printStackTrace() noEmptyBundle() } } /** * AUTHOR:AbnerMing * INTRODUCE:获取视图id */ open fun getLayoutId(): Int { return 0 } open fun initView() {} /** * AUTHOR:AbnerMing * INTRODUCE:初始化数据 */ abstract fun initData() /** * AUTHOR:AbnerMing * INTRODUCE:动静扭转状态栏色彩和题目 */ fun setDarkTitle(dark: Boolean, color: Int, title: String) { try { darkMode(dark) statusBarColor(ContextCompat.getColor(this, color)) setBarTitle(title) } catch (e: Exception) { e.printStackTrace() } } /** * AUTHOR:AbnerMing * INTRODUCE:设置题目 */ fun setBarTitle(title: String) { mActionBarView!!.visibility = View.VISIBLE mActionBarView!!.setBarTitle(title) } /** * AUTHOR:AbnerMing * INTRODUCE:暗藏左侧按钮 */ fun hintLeftMenu() { mActionBarView!!.hintLeftBack() } /** * AUTHOR:AbnerMing * INTRODUCE:获取ActionBarView */ fun getActionBarView(): ActionBarView { return mActionBarView!! } /** * AUTHOR:AbnerMing * INTRODUCE:暗藏标题栏 */ fun hintActionBar() { mActionBarView?.visibility = View.GONE } /** * AUTHOR:AbnerMing * INTRODUCE:Bundle为空进行拦挡,解决扭转权限后重回App解体问题 */ open fun getIntercept(): Boolean { return false } /** * AUTHOR:AbnerMing * INTRODUCE:Bundle为空时的逻辑解决,解决扭转权限后重回App解体问题 */ open fun noEmptyBundle() {} override fun onDestroy() { super.onDestroy() try { LiveDataBus.removeObserve(this) LiveDataBus.removeStickyObserver(this) } catch (e: Exception) { e.printStackTrace() } } /** * AUTHOR:AbnerMing * INTRODUCE:通明状态栏 */ fun translucentWindow(dark: Boolean) { try { immersive(0, dark) } catch (e: Exception) { e.printStackTrace() } } /** * AUTHOR:AbnerMing * INTRODUCE:设置缺省页 */ fun setEmptyOrError(view: View) { mLayoutError?.visibility = View.VISIBLE mLayoutError?.removeAllViews() mLayoutError?.addView(view) } /** * AUTHOR:AbnerMing * INTRODUCE:暗藏 */ fun hintEmptyOrErrorView() { mLayoutError?.visibility = View.GONE } /** * AUTHOR:AbnerMing * INTRODUCE:获取谬误或为空的view */ fun getEmptyOrErrorView(): LinearLayout { return mLayoutError!! }}波及的办法概述办法名参数概述getLayoutId无参子类传递的layout,用于加载视图,能够通过构造方法传递,也能够通过此办法传递。initView无参初始化View,非必须重写initData无参初始化数据setDarkTitledark: Boolean, color: Int, title: String,1、dark: Boolean,状态栏色彩,true就是彩色,false就是红色。2、color: Int,状态栏背景色彩,3、title: String,标题栏内容设置题目,状态栏背景及色彩setBarTitletitle: String,标题栏内容设置题目hintLeftMenu无参暗藏左侧按钮getActionBarView无参获取标题栏View,能够操作标题栏里的任何控件hintActionBar无参暗藏标题栏translucentWindowdark: Boolean,状态栏色彩,true就是彩色,false就是红色通明状态栏setEmptyOrErrorview: View,传递的缺省View视图设置缺省视图hintEmptyOrErrorView无参暗藏缺省视图getEmptyOrErrorView无参获取缺省视图简略的Activity没有什么好说的,都是中规中矩,具体的应用请大家看第四条,具体应用即可。 ...

September 7, 2022 · 5 min · jiezi

关于android:FAQ接入华为应用内支付服务常见问题解答

HMS Core利用内领取服务(In-App Purchases,IAP)为利用提供便捷的利用内领取体验和简便的接入流程。开发者的利用集成IAP SDK后,调用IAP SDK接口,启动IAP收银台,即可实现利用内领取。 通过利用内领取服务,用户能够在利用内购买各种类型的虚构商品,包含一次性商品(包含消耗型商品和非消耗型商品)和订阅型商品。小编将这段时间开发者们较为关注的一些集成利用内领取服务过程中的问题进行了汇总,并给出了解决办法,大家按需取用。 问题一、同一订阅组,间断包月未到期,切换到间断包年,在华为帐号核心治理订阅页面中勾销订阅间断包月,为何间断包年订阅也会被一起勾销? 起因剖析: 从间断包月切换至间断包年后,产品处于未(待)失效状态,如果此时勾销掉间断包月产品,那么会发送间断包月订阅勾销告诉事件,因为此时包年未失效,暂不会发送间断包年的勾销订阅事件。 问题二、在华为智能手表上,调用收银台接口,提醒“此利用需装置HMS Core相干组件的更高版本能力应用。是否立刻更新”,点击更新,提醒更新失败,谬误102。 起因剖析: 该错误码个别示意子Kit须要降级,然而手表利用市场没有相干的子利用上架,所以找不到安装包。在华为智能手表上集成JS SDK,须要降级的次要两个子Kit别离是JSB Kit,IAP Kit。目前JSB Kit已上架到利用市场,IAP Kit尚在上架排期中。 解决办法: 如果遇到该提醒,咱们能够应用躲避计划,即提醒用户去手动到手表利用市场下载最新的HMS Core APK,依据返回的700111错误码进行解决。 问题三、利用内领取服务提供Android和HarmonyOS SDK,反对的性能和设施有什么区别?App通过集成IAP SDK,再调用IAP SDK接口启动IAP收银台,即可实现利用内领取。Android和HarmonyOS SDK都提供根底的利用内领取服务,包含订单治理、订阅、查看历史购买记录等;但HarmonyOS SDK目前不反对非PMS领取和提早付款领取。在反对的设施方面,HarmonyOS SDK反对华为手机、华为手表和华为平板;Android SDK除了华为设施以外,还反对非华为手机和车机。 具体可参考下表: 问题四、为什么利用内领取4.0以上版本SDK 接口obtainOwnedPurchasesRecord 无奈查问到2.0 sdk 接口productPay购买的PMS非消耗性商品订单?起因剖析: 利用内领取4.0以上版本和2.0版本数据不在同一个数据库上,且临时无奈合并,所以应用新接口的无奈查问到之前的订单。 解决办法: 如果利用上有展现历史数据的需要,能够仅展现集成4.0之后版本 sdk的数据,如22年1月份集成更新,则可提醒本页面只可查问22年1月份之后的购买数据。(参考)开发者可将之前2.x版本下单的购买数据(从应用服务侧获取)和 4.0之后版本sdk(从IAP SDK接口)获取到的数据进行整合解决。(举荐)问题五、 华为智慧手表上,曾经进入到沙盒测试环境中,拉起收银台后领取二维码不显示,提醒申请参数谬误。 起因剖析: 目前扫码类的领取形式都临时不反对沙盒测试,比方手表,智慧屏等都是通过扫码形式进行领取的,所以会呈现相应谬误提醒。 解决办法: 登录非沙盒帐号(或者删除沙盒帐号),触发现网环境进行测试。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

September 7, 2022 · 1 min · jiezi

关于android:ShareSDK-Android端主流平台分享示例

ShareSDK能够调用getPlatform接口设置要分享的平台,上面是分享示例: 微信分享示例(好友、朋友圈、珍藏)微信分享文本Platform platform = ShareSDK.getPlatform(Wechat.NAME);Platform.ShareParams shareParams = new Platform.ShareParams();shareParams.setShareType(Platform.SHARE_TEXT);shareParams.setTitle("测试分享的题目");shareParams.setText("测试文本");platform.share(shareParams);微信分享图片留神: imageUrl(”网络图片链接”)、imagePath(“/sdcard/abc.jpg”)、imageData(bitmap)是三选一,同时Android11及之后的版本,微信分享图片不反对用imageData(bitmap)接口设置参数; Platform platform = ShareSDK.getPlatform(Wechat.NAME);Platform.ShareParams shareParams = new Platform.ShareParams();shareParams.setShareType(Platform.SHARE_IMAGE);//分享网络图片shareParams.setImageUrl("https://img1.2345.com/duoteimg/qqTxImg/2012/04/09/13339485237265.jpg")//分享本地图片//shareParams.setImagePath("本地图片的门路");//分享bitmap图片//shareParams.setImageData(bitmap);platform.share(shareParams);微信分享音乐Platform platform = ShareSDK.getPlatform(Wechat.NAME);Platform.ShareParams shareParams = new Platform.ShareParams();shareParams.setShareType(Platform.SHARE_MUSIC);shareParams.setTitle("测试分享的题目");shareParams.setText("测试文本");shareParams.setImageUrl("https://img1.2345.com/duoteimg/qqTxImg/2012/04/09/13339485237265.jpg")shareParams.setMusicUrl( "http://music.baidu.com/song/546920050?pst=sug" );shareParams.setUrl("http://music.baidu.com/song/546920050?pst=su");platform.share(shareParams);微信分享视频Platform platform = ShareSDK.getPlatform(Wechat.NAME);Platform.ShareParams shareParams = new Platform.ShareParams();shareParams.setShareType(Platform.SHARE_VIDEO);shareParams.setTitle("测试分享的题目");shareParams.setText("测试文本");shareParams.setImageUrl("https://img1.2345.com/duoteimg/qqTxImg/2012/04/09/13339485237265.jpg")shareParams.setUrl("http://f1.webshare.mob.com/dvideo/demovideos.mp4");platform.share(shareParams);微信分享网页Platform platform = ShareSDK.getPlatform(Wechat.NAME);Platform.ShareParams shareParams = new Platform.ShareParams();shareParams.setShareType(Platform.SHARE_WEBPAGE);shareParams.setTitle("测试分享的题目");shareParams.setText("测试文本");shareParams.setImageUrl("https://img1.2345.com/duoteimg/qqTxImg/2012/04/09/13339485237265.jpg")shareParams.setUrl("https://www.mob.com/");platform.share(shareParams);微信分享文件Platform platform = ShareSDK.getPlatform(Wechat.NAME);Platform.ShareParams shareParams = new Platform.ShareParams();shareParams.setShareType(Platform.SHARE_FILE);shareParams.setTitle("测试分享的题目");shareParams.setFilePath("/storage/emulated/0/Android/data/cn.sharesdk.demo/files/text.txt");//文件本地门路platform.share(shareParams); 微信分享小程序留神:只有微信好友反对分享小程序 Platform platform = ShareSDK.getPlatform(Wechat.NAME);Platform.ShareParams shareParams = new Platform.ShareParams();//分享卡片模式小程序shareParams.setShareType(Platform.SHARE_WXMINIPROGRAM);//间接关上微信小程序//shareParams.setShareType(Platform.OPEN_WXMINIPROGRAM);shareParams.setText("测试文本");shareParams.setTitle("测试分享的题目");shareParams.setUrl("http://sharesdk.cn");shareParams.setImageUrl("https://hmls.hfbank.com.cn/hfapp-api/9.png");//小程序状态:0-正式,1-开发,2-体验shareParams.setWxMiniProgramType(0); //微信小程序多选,默认只能分享一个微信好友,设置false后能够分享多个shareParams.setWxWithShareTicket(false);//分享的小程序页面门路,如不须要指定,请填主页门路(必填)shareParams.setWxPath("pages/index/index");shareParams.setWxUserName("gh_52568203455c");platform.share(shareParams);新浪微博分享示例新浪微博分享文字Platform platform = ShareSDK.getPlatform(SinaWeibo.NAME);Platform.ShareParams shareParams = new Platform.ShareParams();shareParams.setText("测试文本");platform.share(shareParams);新浪微博分享图文留神: imageUrl(”网络图片链接”)、imagePath(“/sdcard/abc.jpg”)、imageData(bitmap)是三选一 Platform platform = ShareSDK.getPlatform(SinaWeibo.NAME);Platform.ShareParams shareParams = new Platform.ShareParams();shareParams.setText("测试文本");//分享网络图片shareParams.setImageUrl("https://img1.2345.com/duoteimg/qqTxImg/2012/04/09/13339485237265.jpg")//分享本地图片//shareParams.setImagePath("本地图片的门路");//分享bitmap图片//shareParams.setImageData(bitmap);platform.share(shareParams);新浪微博分享本地视频Platform platform = ShareSDK.getPlatform(SinaWeibo.NAME);Platform.ShareParams shareParams = new Platform.ShareParams();shareParams.setText("测试文本");//视频文件本地门路shareParams.setFilePath("/sdcard/video.MP4");platform.share(shareParams);QQ分享示例 QQ分享图片留神:imageUrl(”网络图片链接”)、imagePath(“/sdcard/abc.jpg”)是二选一,同时QQ不反对分享bitmap图片 ...

September 6, 2022 · 1 min · jiezi

关于android:货拉拉开源模块化路由框架TheRouter

TheRouter 是一个 Kotlin 编写,用于 Android 模块化开发的一整套解决方案框架。 Github 我的项目地址与应用文档详见 https://github.com/HuolalaTech/hll-wp-therouter-android。 TheRouter 外围性能具备如下能力: 页面导航跳转能力(Navigator)跨模块依赖注入能力(ServiceProvider)单模块主动初始化能力(FlowTaskExecutor)动态化能力(ActionManager)模块AAR/源码依赖一键切换脚本一、为什么要应用 TheRouter路由是现如今挪动端开发中必不可少的性能,尤其是企业级APP,能够用于将Intent页面跳转的强依赖关系解耦,同时缩小跨团队开发的相互依赖问题。 对于大型 APP 开发,根本都会选用模块化(或组件化)形式开发,对于模块间解耦要求更高。 TheRouter 是一整套齐全面向模块化开发的解决方案,不仅能反对惯例的模块依赖解耦、页面跳转,同时提供了模块化过程中常见问题的解决办法。例如:完满解决了模块化开发后因为组件内无奈获取 Application 生命周期与业务流程,造成每次初始化与关联依赖调用都须要跨模块批改代码的问题。 1.1 TheRouter 四大能力Navigator: 反对 Activity 和 Fragment反对Path与页面多对一关系或一对一关系,可用于解决多端path对立问题页面Path反对正则表达式申明反对 json 格局路由表导出反对动静下发 json 路由表,降级任意页面为H5反对任意object跨模块传递(无需序列化,且能保障对象类型)反对页面跳转拦挡解决反对自定义页面参数解析形式(例如将json解析为对象)反对应用路由跳转到第三方 SDK 中的Activity(Fragment)ServiceProvider: 反对跨模块依赖注入反对自定义注入项的创立规定,依赖注入可自定义参数反对自定义服务拦挡,单模块mock调试反对注入对象缓存,屡次注入 只会new一次对象FlowTaskExecutor: 反对单模块独立初始化反对懒加载初始化独立初始化容许多任务依赖(参考Gradle Task)反对编译期循环援用检测反对自定义业务初始化机会,能够用于解决隐衷合规问题ActionManager: 反对全局回调配置反对优先级响应与中断响应反对记录调用门路,解决调试期观察者模式无奈追踪Observable的问题注: FlowTaskExecutor、ActionManager 后续会作为可选能力,提供可插拔或独自应用的选项(预计10月份提供)。 二、路由计划目前现有的路由基本上集中于两种能力的实现:页面跳转、跨模块调用,核心技术计划大体上如图: 开发阶段,对要应用路由的落地页或被调用办法增加注解标识。编译期解析注解,生成一系列中间代码,待调用。利用启动后调用中间代码实现路由的筹备动作。大部分路由会额定通过 Gradle Transform,在编译期做一次聚合,以晋升运行时筹备路由表的效率。发动路由跳转时,实质上就是一次路由表遍历,通过uri获取到对应的落地页或办法对象,进行调用。TheRouter 的页面跳转、跨模块调用也是如此,然而在设计上会有一些细节解决。 TheRouter 会在编译期依据注解生成 RouteMap__结尾的类,这些类中记录了以后模块的所有路由信息,也就是以后模块的路由表。 在最顶层的app模块中,通过Gradle插件,将所有aar、源码中的RouteMap__结尾的类对立集中到TheRouterServiceProvideInjecter类中。 后续利用启动后,初始化路由时只须要执行TheRouterServiceProvideInjecter类的办法,就能没有任何反射的加载到全副的路由表了。 加载当前的路由表会被保留到一个反对正则匹配的 Map 中,这也是TheRouter容许多个path对应同一个落地页的起因。每当产生页面跳转时,通过跳转时的path,去Map中获取到对应的落地页信息,再失常调用startActivity()即可。 三、应用 TheRouter 页面跳转3.1 申明路由项如果一个页面(反对 Activity、Fragment)容许被路由关上,则须要应用注解 @Route 申明路由项,每个页面容许申明多个路由项,也就是一对多的能力,极大升高多端路由对立时的业务影响面。 参数释义 path: 路由path 【必传】。 倡议是一个url。path内反对应用正则表达式(为了匹配效率,正则必须蕴含反双斜杠\),容许多个path对应同一个Activity(Fragment)。action: 自定义事件【可选】。 个别用来关上指标页面后做一个执行动作,例如自定义页面弹出广告弹窗。description: 页面形容【可选】。 会被记录到路由表中,不便前期排查的时候晓得每个path或Activity是什么业务。params: 页面参数【可选】。 主动写入intent中,容许写在路由表中动静下发批改默认值,或通过路由跳转时代码传入。 ...

September 6, 2022 · 3 min · jiezi

关于android:金九银十收下这份-Java-String-面试题

请点赞关注,你的反对对我意义重大。 Hi,我是小彭。本文已收录到 GitHub · Android-NoteBook 中。这里有 Android 进阶成长常识体系,有气味相投的敌人,关注公众号 [彭旭锐] 带你建设外围竞争力。 前言大家好,我是小彭。 过来两年,咱们在掘金平台上公布 JetPack 专栏文章,小彭也受到了大家的意见和激励。最近,小彭会陆续搬运到公众号上。 在每种编程语言里,字符串都是一个躲不开的话题,也是面试经常呈现的问题。在这篇文章里,我将总结 Java 字符串中重要的知识点 & 面试题 ,如果能帮上忙,请务必点赞加关注,这真的对我十分重要。 学习路线图: 1. C 和 Java 中字符串和字符数组的比照1.1 内存示意不同在 C 语言中,字符串和字符数组雷同。字符串实质上是以 \0 为结束符的字符数组字符数组,因而字符串和字符数组在实质上雷同,都是一块间断的内存空间,以须要本义 \0 为结束符。C 语言是不关怀 char[] 里存储字符的编码方式的,只有通过程序的上下文确定;在 Java 中,字符串和字符数组不同。字符串是 String 对象,而字符数组是数组对象,均不须要结束符。如果是数组对象,对象内存区域中有一个字段示意数组的长度,而 String 相当于字符数组的包装类。外部包装了一个基于 UTF-16 BE 编码的字符数组(从 Java 9 开始变为字节数组)。其余字符编码输出的字节流在进入 String 时都会被转换为 UTF-16 BE 编码。java.lang.String public final class String { private final char value[]; private int hash; ...}1.2 char 类型的数据长度在 C 语言中,char 类型占 1 字节,分为有符号与无符号两种;在 Java 中,char 类型占 2 字节,只有无符号类型。语言类型存储空间(字节)最小值最大值Javachar2065535Cchar(相当于signed char)1-128127Csigned char1-128127Cunsigned char102552. 为什么 Java 9 String 外部将 char 数组改为 byte 数组?Java String 的内存示意实质上是基于 UTF-16 BE 编码的字符数组。UTF-16 是 2 个字节或 4 个字节的变长编码,这意味着即便是 UniCode 字符集的拉丁字母,应用 ASCII 编码只须要一个字节,然而在 String 中须要两个字节的存储空间。 ...

September 6, 2022 · 3 min · jiezi

关于android:运营下班指南有人准点下班有人凌晨搬砖

如何探寻用户散失起因并解决这个问题?HMS Core剖析服务有答案。无效实现用户、营收双增长,或者早上班就不须要指南。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

September 6, 2022 · 1 min · jiezi

关于android:个推发布Android13适配攻略开发者请查收

前言:8月16日,谷歌发表Android13新零碎的源代码曾经上传到Android开源我的项目(AOSP)中,Android13正式公布。自从2022年2月Android13第一个预览版上线以来,历经7个月的测试和优化,正式版本的Android13终于来了!Android13依然聚焦个人隐私爱护和平安,并提供了万物互联时代下大小屏适配、电池利用率优化等相干的技术开发能力。 感兴趣的开发者能够登录官网下载源码测试学习:https://developer.android.goo... 个推服务开发者多年,始终亲密关注和跟进行业发展趋势。Android13正式版公布后,咱们应用模拟器进行了钻研和适配测试。本文将从权限变更、系统优化、性能更新等方面来谈谈Android13新个性,以帮忙开发者疾速上手实现Android新零碎的适配。 权限变更一、告诉权限告诉栏音讯始终是App和用户沟通的无效渠道。在Android13之前,App只须要应用NotificationManager即可向终端用户推送告诉栏音讯。Android13则引入了新的运行时告诉权限:POST_NOTIFICATIONS。对此,App开发者须要予以重点关注。 个推对该权限进行了测试,总结如下: 1. 首先看TargetSdk<33的状况。  如下图,当App应用告诉栏性能时,零碎将自动弹出受权弹窗:  用户点击“容许”,App可失常给用户推送音讯:   2. 再看TargetSdk == 33的状况。  开发者须要在AndroidManifest.xml中申明POST_NOTIFICATIONS权限,还须要在应用告诉栏推送性能时在代码中申请运行时权限: <?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.gt.demo.mubai.push"> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/></manifest>requestPermissions(new String[]{“android.permission.POST_NOTIFICATIONS”})以上是用户点击“容许”App推送的状况。当然,用户也有可能点击“不容许”。值得注意的是,一旦被用户回绝受权,下次零碎将不会再呈现权限申请的弹窗。如果App依然要推送重要音讯(比方重大版本更新)给用户,则须要疏导用户返回设置界面关上告诉权限。 代码如下: private void jumpNotificationSetting() { final ApplicationInfo applicationInfo = getApplicationInfo(); try { Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS"); intent.putExtra("app_package", applicationInfo.packageName); intent.putExtra("android.provider.extra.APP_PACKAGE", applicationInfo.packageName); intent.putExtra("app_uid", applicationInfo.uid); startActivity(intent); } catch (Throwable t) { t.printStackTrace(); Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); intent.setData(Uri.fromParts("package", applicationInfo.packageName, null)); startActivity(intent); }★舒适提醒:如果App要确认用户是否已启用告诉,能够调用NotificationManager.areNotificationsEnabled()进行判断。 另外,除了“容许”和“不容许”两种抉择外,用户还能够划走权限申请对话框(User swipes away from dialog),即用户未抉择受权(也未抉择不受权)。那么下次App进行告诉栏音讯推送时,零碎将再次弹出用户受权弹窗。  ...

September 5, 2022 · 2 min · jiezi

关于android:如何使用Postman调试HMS-Core推送接口

HMS Core推送服务反对开发者应用HTTPS协定接入Push服务端。Postman是一款接口测试工具,它能够模仿用户发动的各类HTTP申请,将申请数据发送至服务端,获取对应的响应后果。Postman能够模仿开发者服务器申请Access Token,调用鉴权等接口的申请。 因而有很多开发者在测试端侧推送成果或定位推送问题时都会抉择应用Postman测试推送接口。例如,开发者想应用接口推送测试音讯但又不不便间接应用利用正式服务端推送时,就能够应用Postman模仿服务端的推送申请。或者服务端接口调试不通,又不确定是不是参数有问题,就能够用postman验证一下申请是否胜利。本文将介绍应用Postman调用HMS Core推送接口的具体操作步骤。 一、Postman下载安装下载地址:https://www.postman.com/downl...,点击Download,下载对应版本,而后装置。本文应用的是v7.36.1版本。 如果网络应用了代理,须要给Postman配置代理(如网络没有代理,请疏忽): 关上File菜单,点击Settings菜单,弹出设置界面。 在设置界面选中Proxy,配置您的网络代理。 二、调用鉴权接口,获取Access Token。接口阐明文档 在Postman新建一个Tab,输出接口地址,抉择POST形式:post地址:https://oauth-login.cloud.hua... 抉择body,勾选“x-www-form-urlencoded”,而后在下方列表里输出参数名称和对应的值。三个参数阐明如下: grant_type——固定值“client_credentials”。 client_id——对于AppGallery Connect类利用,该值为利用中OAuth 2.0客户端ID(凭据)的Client ID。 client_secret——对于AppGallery Connect类利用,该值为利用中OAuth 2.0客户端ID(凭据)的Client Secret。 点击send,就能够调用接口返回access_token了,如下图所示: 保留调试配置,按下ctrl+s,输出名字“Get Token”,新建目录“push”,即可保留。三、调用音讯推送接口发送Push音讯接口阐明文档 在Postman新建一个Tab,输出接口地址(将[appid]替换为理论的appid),抉择POST形式:post地址:https://push-api.cloud.huawei...[appId]/messages:send 抉择Authorization,TYPE抉择“Bearer Token”,而后在Token输入框中输出二中获取的access_token,如下图: 抉择Body,选中“raw”,下拉框抉择“JSON”,而后在下方输入框中复制音讯内容,点击send,就能够发送音讯了,如下图: 保留调试配置,按下ctrl+s,输出名字“Send Message”,保留在目录“push”下即可。四、应用Postman生成其余常用工具/语言的命令应用Postman已有的调试胜利的接口,能够主动生成其余工具的命令,如罕用的cURL、Nodejs、Python、Ruby等,能够间接复制应用。 获取形式:在窗口左边,点击Code,即可弹出命令页面,能够抉择本人须要的语言的命令。 最初附上应用Postman导出的实例文件,有须要的开发者能够间接导入测试。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

September 5, 2022 · 1 min · jiezi

关于android:食之无味App-Startup-可能比你想象中要简单

请点赞关注,你的反对对我意义重大。 Hi,我是小彭。本文已收录到 GitHub · AndroidFamily 中。这里有 Android 进阶成长常识体系,有气味相投的敌人,关注公众号 [彭旭锐] 带你建设外围竞争力。 前言大家好,我是小彭。 2020 年 10 月 28 日,JetPack | App Startup 1.0.0 终于迎来正式公布,正好最近在总结组件化架构专题,所以也专门学习下 App Startup 的工作原理。在这篇文章里,我将带你总结 App Startup 的应用办法 & 实现原理 & 源码剖析。有用请点赞给 Star,给小彭一点创作的能源,谢谢。 这篇文章是 Jetpack 系列文章第 13 篇,专栏文章列表: 1、Lifecycle:生命周期感知型组件的根底2、LiveData:生命周期感知型数据容器(本文)3、ViewModel:数据驱动型界面控制器4、Flow:LiveData 的代替计划5、从 MVC 到 MVP、MVVM、MVI:Android UI 架构演进6、ViewBinding:新一代视图绑定计划7、Fragment:模块化的微型 Activity8、RecyclerView:可复用型列表视图9、Navigation:单 Activity 多 Fragment 的导航计划10、Dagger2:从 Dagger2 到 Hilt 玩转依赖注入(一)11、Hilt:从 Dagger2 到 Hilt 玩转依赖注入(二)12、OnBackPressedDispatcher:解决回退事件的新姿态二、其余: 1、AppStartup:轻量级初始化框架(本文)2、DataStore:新一代键值对存储计划3、Room:ORM 数据库拜访框架4、WindowManager:增强对多窗口模式的反对5、WorkManager:增强对后台任务的反对6、Compose:新一代视图开发计划学习路线图: 1. 意识 AppStartup1.1 App Startup 解决了什么问题?App Startup 是 Google 提供的 Android 轻量级初始化框架: ...

September 4, 2022 · 4 min · jiezi

关于android:理解Android中Dialog

PS:本文系转载文章,浏览原文可读性会更好,文章开端有原文链接 PS:本文是基于 Android Api 26 来剖析源码的。1、Dialog 的 Window 是在哪里创立的?Dialog 的 Window 是在什么中央创立的呢?咱们来看看 Dialog 的一个构造方法,那就是 Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) 办法;看到正文1中的代码没有,它创立了一个 Window,而这个 Window 的实现类是 PhoneWindow,它跟 Activity 一样也是用 PhoneWindow 作为本人的 Window;好,那既然有 Window,那就必然有 View 显示进去对不对?那咱们看看这个 Dialog 的 PhoneWindow 是如何加载 View 的,咱们看一下 Dialog 其中一个加载 View 的办法 setContentView(@LayoutRes int layoutResID);mWindow 就是 Window,而 Window 的实现类是 PhoneWindow,所以咱们往下看 PhoneWindow 的 setContentView(@LayoutRes int layoutResID) 办法;看到 PhoneWindow 的 setContentView(@LayoutRes int layoutResID) 办法没有,Activity 的 setContentView(@LayoutRes int layoutResID) 办法解析 View 过程和 Dialog 的 setContentView(@LayoutRes int layoutResID) 办法解析 View 过程是一样的,所以就不在对 PhoneWindow 的 setContentView(@LayoutRes int layoutResID) 办法进行剖析了,能够看Android中AppCompatActivity的setContentView办法剖析这篇文章进行了解它。2、咱们在平时开发的时候是否遇到这样的一个问题:如果 Dialog 应用的 Context 不是 Activity 的而是 Application 的,那么就会报错。好,为了更好的了解,咱们先上一段简略的代码;把 app 运行一下,发现报了如下谬误;这里报错的起因是没有利用 token 所导致的,利用 token 个别只有 Activity 才领有,所以这里只用用 Activity 的 Context 来作为 Dialog 的就能够了;这里因为 Appliation 的 token 是空的,而 Dialog 一开始创立 Winow 的时候 token 要是空的;咱们来看一下 Dialog 的一个构造方法,那就是 Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper);看正文3的代码,第二个参数是不是 null,那就阐明 Dialog 的 token 为 null 了;Dialog 的窗口类型为 TYPE_APPLICATION 类型的,要求必须是 Activity 的 Token,不是的话零碎会抛出 BadTokenException 异样;Dialog 是利用窗口类型,Token 必须是 Activity 的 Token;咱们看一下正文2的代码,假如 context 是 Activity,看 getSystemService 办法的传入的是 Context.WINDOW_SERVICE,好,咱们看一下 Activity 的 getSystemService办法;看正文4的代码,nam 为 Context.WINDOW_SERVICE,所以返回的是 mWindowManager ,而 mWindowManager 的实现类是 WindowManagerImpl;那 Activity 是在什么时候设置 token 的呢?答案是在 Activity 的 attach办法;看到正文5的代码没,第二个参数就是 Activity 的 token ,好,咱们往下看 Window 的 setWindowManager办法;正文6的代码,只是将 token 保留到 Activity 的 Window 中;看正文7的代码,这里的 this 指的是 Activity 的 PhoneWindow;好,咱们往下看 WindowManagerImpl 的 createLocalWindowManager办法;WindowManagerImpl 的 createLocalWindowManager 办法又调用了 WindowManagerImpl(Context context, Window parentWindow)办法;mParentWindow是什么?一看这名字就晓得必定是某个 Window 的父 Window,也就是说 Activity 的 Window 是某个 Window 的父 Window;那什么时候 Activity 的 token 给了 Dialog 呢?咱们看一下 Dialog 的 show 办法;正文9代码其实就是显示 Dialog 的 View 过程,并将 mShowing 置为 true,示意 View 正在显示;好,咱们看看正文9代码的实现,mWindowManager 是 WindowManagerImpl,咱们看看 addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params)办法;正文10中的 mParentWindow是 Activity 的 PhoneWindow(如果 mContext 是 Activity 的话),mGlobal 是 WindowManagerGlobal,咱们看一下 WindowManagerGlobal 的 addView(View view, ViewGroup.LayoutParams params, Display display, Window parent-Window)办法;看正文11的代码,parentWindow 就是 Activity 的 PhoneWindow,所以执行到 Window 的 adjustLayoutParamsForSubWindow(WindowMana-ger.LayoutParams wp)办法;看到正文12的代码没有,decor实质上是 Activity 中 PhoneWindow 的 DecorView,decor 拿到的是 mAttachInfo.mWindowToken ,而 mAttachInfo.mWindowToken正是 Activity 中 PhoneWindow 的 token,所以在 Dialog 的 show 过程其实也将 Activity 的 token 赋值给了 Dialog。咱们下面不是提到过 Dialog 的 Window 是 TYPE_APPLICATION 类型的窗口吗?怎么证实它是?好,咱们回过头来看正文8的代码,也就是 Dialog 的 PhoneWindow 的 getAttributes办法,它在 Window 中实现的;mWindowAttributes 是什么,咱们看看 mWindowAttributes的申明;咱们看看 WindowManager.LayoutParams 的无参构造方法;看到正文13的代码没有,Window 默认应用的 type 是 TYPE_APPLICATION,而 Dialog 的 Window 没有扭转 type,所以 Dialog 的 Window 是 TYPE_APPLICATION 类型的窗口。最初咱们看一下 Dialog 的 dismiss 办法的实现;看正文14,如果以后线程是主线程,那么间接执行 dismissDialog 办法;看正文15,如果不是主线程,那么就切换到主线程去执行;好,咱们持续看 Dialog 的 dismissDialog办法;看正文16代码,最终将 DecorView 从 PhoneWindow 中删除就完事了。 ...

September 4, 2022 · 2 min · jiezi

关于android:android-自定义View-视差动画

背景在Android App的成长过程中,随着包性能越来越多,团队越来越简单,为了保障性能的清晰和可维护性、减少模块的内聚性,减小git推代码抵触的危险等等,App的开发模式会缓缓变成集成开发模式 集成开发模式每个人负责一个或者多个模块,模块之间互相隔离,独立进行打包和降级,最初以远端依赖的形式集成到App中进行打包 问题在采纳集成开发模式的时候会碰到一个问题,因为主App都是通过implement 远端的依赖进行打包的,当在本地开发的时候,如何对模块的本地代码进行调试呢?个别咱们的做法是这样的: 在build.gradle中将远端的依赖改为本地依赖在setting.gradle中定义本地依赖的模块地址// build.gradle文件dependencies { // 在主App中是这么定义依赖的 implementation 'io.github.pettywing:floatwindow:1.0.0' // 当业务在本地开发的时候改为 implementation project(':floatwindow')}// setting.gradle文件 include ':floatwindow'project(":floatwindow").projectDir = file("../floatwindow/floatwindow")但这样设置很麻烦,危险也很高,每次我的项目拉到本地都要改一次,到远端打包的时候还要在批改回来,有没有啥简略的办法呢 解决 在本地新建一个local_develop.gradle文件,并增加到git.ignore ext { dependencies = [ [ // 是否开启模块的本地源码依赖,true则源码依赖,false则AAR依赖 isLocalModule: true, // 代码仓库寄存在本地之后绝对主工程的门路,因为我放在了主工程的同级目录,所以这里要的相对路径要跳出一级目录 projectPath : "../../android/Floatwindow", // module name projectName : ":floatwindow", // maven groupId:artifactId projectMaven : "io.github.pettywing:floatwindow" ] ]}在setting.gradle增加如下代码File localPropertiesFile = new File(rootDir.getAbsolutePath() + "/local.properties")File localDevelopFile = new File(rootDir.getAbsolutePath() + "/local_develop.gradle")if (localPropertiesFile.exists() && localDevelopFile.exists()) { apply from: "local_develop.gradle" if (ext.has("dependencies")) { ext.getProperty("dependencies").each { projectConfig -> // 如果工程是本地依赖,应用本地工程源码进行替换 if (projectConfig["isLocalModule"]) { includeBuild(projectConfig["projectPath"]) { dependencySubstitution { substitute module(projectConfig["projectMaven"]) with project(projectConfig["projectName"]) } } } } }}这样当我的项目在远端打包的时候,因为没有local_develop.gradle,会用远端的依赖版本进行打包。我的项目在本地运行的时候,如果你增加了local_develop.gradle,就会主动把远端依赖改本地依赖;并且因为local_develop.gradle被ignore,多个开发者在应用的过程中也不会相互影响。 ...

September 2, 2022 · 1 min · jiezi

关于android:使用-DialogX-快速构建-Android-App

应用 DialogX 疾速构建 Android App 对话框传统原生对话框组件存在着内存透露、自定义水平有余的问题,开发时常会因为遇到各式各样的奇葩解体而懊恼,面对着产品和设计师诸如“对话框圆角大一些”、“能不能照着iOS设计稿的含糊成果做”、“下滑列表界面主动关掉对话框”等等诸多需要又难以解决,又不想每次封装或编写一大堆的代码去实现某一个小小的提示框需要,你能够试试 DialogX,它足以满足大部分场景下疾速实现对话框、阻断提示框、非阻断提示框、底部对话框等等各式各样的对话框组件,又能完满满足各种主题和性能扩大需要,极大中央便了开发流程,帮忙你疾速构建利用对话框性能。 易用性比照比照传统 AlertDialog,DialogX 具备很大的劣势:DialogX 采纳全新的实现形式,默认 View 实现形式更为轻便,亦可选 Window、DialogFragment 实现形式,自在灵便。DialogX 的启动与线程无关,你能够在任意线程启动 DialogX 而它都将主动在 UI 线程运行。DialogX 的启动无需 context 参数,默认提供静态方法一句代码实现对话框的启动,应用更加不便。更自在,开发者能够轻松定制对话框中任何组件的款式,包含文本款式、按钮文字款式、菜单文本款式、输出文本款式,大到题目,小到提醒音讯都能够依据须要随便批改。DialogX 采纳主题拆散设计,默认自带 Material 主题,可选引入 IOS、Kongzue、MIUI 等其余格调主题,大大减小 App 体积,同时提供了主题接口,如有定制需要齐全能够自行实现一套公有主题。更低的耦合度,更少的问题,DialogX 能够在对话框正在运行的过程中随便敞开 Activity ,而无需放心以往 AlertDialog 等组件会引发的 WindowLeaked 谬误。更晦涩的体验,DialogX 的动画成果更加丰盛,对话框启动动画采纳非线性动画实现,更自带连贯的期待提醒到实现谬误动画过渡成果,让你的 APP 更具动感。所有主题默认反对亮暗色两种模式,只需一键配置即可实现亮暗色的对话框主题切换,更有自在的布局内容满足定制化需要,DialogX 也反对主动适应零碎亮暗色模式切换,可能依据零碎设置主动判断亮暗色显示成果的切换。轻松的实现对话框的生命周期管控以及沉迷式适配。简略来讲,个别咱们要编写一个 AlertDialog,实现一个简简单单的提醒确认,至多须要以下代码: AlertDialog Demo//构建 AlertDialog BuilderAlertDialog.Builder builder = new AlertDialog.Builder(context);builder.setTitle("题目");builder.setMessage("这里是注释内容。");builder.setCancelable(true);  //点击对话框以外的区域是否让对话框隐没builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {    @Override    public void onClick(DialogInterface dialog, int which) {        Toast.makeText(context, "你点击了是的", Toast.LENGTH_SHORT).show();        dialog.dismiss();   }});AlertDialog dialog = builder.create();dialog.show();  //显示对话框MessageDialog DemoMessageDialog.show("题目", "这里是注释内容。", "确定");当然,你也能够依据本人的习惯应用 build 办法构建: ...

September 2, 2022 · 1 min · jiezi

关于android:MobPush-安卓推送消息数据解析推荐实现

MobPush 推送音讯解析须要次要类型分为TCP音讯与厂商音讯,TCP音讯:MobPush 利用在线默认走MobTech本人创立的TCP通道,称为 TCP音讯。厂商音讯:利用完结过程状态推送需走厂商通道(华米OV魅通道)。因而推送音讯解析次要针对这俩种音讯进行解决。举荐以下两种解析形式。更多操作详情可参考官网文档 对立通过intent解析(举荐)推送音讯能够对立通过解析intent解决,须要留神,因为安卓零碎问题,须要音讯落地页Activity的启动模式为SingleTask或者SingleTop,否则有可能落地页的onCreate和OnNewIntent无奈触发,解析厂商音讯失败,可用通明Activity作为落地页,再依据参数进行跳转等其余逻辑。解析示例: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 可通过Mob提供的解析办法,依据解析参数,判断音讯是厂商音讯还是tcp音讯,须要别离解决,打印参数示例参考3,4。 JSONArray jsonA = MobPushUtils.parseMainPluginPushIntent(getIntent()); System.out.println("-------------jsonSchemejsonA 打印查看:"+jsonA ) JSONArray var = MobPushUtils.parseSchemePluginPushIntent(getIntent()); System.out.println("-------------jsonSchemevar打印查看:"+var)}protected void onNewIntent(Intent intent) { // 可通过MobTech提供的解析办法,依据解析参数,判断音讯是厂商音讯还是tcp音讯,须要别离解决,打印示例参考3,4。 super.onNewIntent(intent); setIntent(intent); JSONArray jsonA = MobPushUtils.parseMainPluginPushIntent(getIntent()); System.out.println("-------------jsonSchemejsonA 打印查看:"+jsonA ) JSONArray var = MobPushUtils.parseSchemePluginPushIntent(getIntent()); System.out.println("-------------jsonSchemevar打印查看:"+var)}辨别解决: TCP音讯通过MobTech回调解决,厂商音讯解析Intent解决MobPush TCP音讯均可通过回调解决如下: MobPushReceiver mobPushReceiver = new MobPushReceiver() { @Override public void onCustomMessageReceive(Context context, MobPushCustomMessage message) { //接管到自定义音讯(透传音讯) message.getMessageId();//获取工作ID message.getContent();//获取推送内容 } @Override public void onNotifyMessageReceive(Context context, MobPushNotifyMessage message) { //接管到告诉音讯 message.getMobNotifyId();//获取音讯ID message.getMessageId();//获取工作ID message.getTitle();//获取推送题目 message.getContent();//获取推送内容 } @Override public void onNotifyMessageOpenedReceive(Context context, MobPushNotifyMessage message) { //告诉被点击事件 message.getMobNotifyId();//获取音讯ID message.getMessageId();//获取工作ID message.getTitle();//获取推送题目 message.getContent();//获取推送内容 } @Override public void onTagsCallback(Context context, String[] tags, int operation, int errorCode) { //标签操作回调 //tags: RegistrationId已增加的标签 //operation: 0获取标签 1设置标签 2删除标签 //errorCode: 0操作胜利 非0操作失败 } @Override public void onAliasCallback(Context context, String alias, int operation, int errorCode) { //别名操作回调 //alias: RegistrationId对应的别名 //operation: 0获取别名 1设置别名 2删除别名 //errorCode: 0操作胜利 非0操作失败 } };厂商音讯必须解析intent通过onCreate 或onNewIntent ...

September 2, 2022 · 1 min · jiezi

关于android:贼简单的Android计时工具还不试用起来

嘿!各位老铁,大家好啊,好久没更新了,次要也不晓得写些什么,也不晓得别的博主是如何创作的,但对于我来说,原创的日更真的很难,不过老铁们,莫放心,做不到日更,但断断续续的更还是能做到的,也心愿本人的一些浅显的见识,可能给大家带来些许帮忙,明天呢,给大家带来的是一个十分好用的计时工具,真的十分好用,用过之后,你会发现,延时和定时,真的从未如此简略。 在讲述之前,不晓得各位老铁在平时的开发中,遇到定时和延时相干的性能,都是怎么解决的,古老的Handler还是Timer,无论哪种形式,尽管都可能实现咱们想要的成果,但仿佛都存在着肯定的代码量和生命周期的思考,有没有一种形式,既调用简略,又能不关注生命周期呢? 理解作者的老铁都晓得,已经的作者在Web的陆地里也飞翔了许久,粗浅的晓得Js里的定时和延时,是那么的简略,我这里贴出来,大家能够看一看。 setTimeout(function (){ //延时3秒后操作 },3000)setInterval(function (){ //定时,一秒执行一次 },1000)Js中的延时和定时,老铁们,看后怎么样,简略吧,在Android中,咱们是否也像前端这样操作呢,一个字,能,必须能。 通过对Kotlin中coroutines里的ticker再次封装,应用LifecycleOwner与生命周期进行绑定,一个简略的计时工具就诞生了。目前曾经开源,须要的老铁能够下载。 地址如下: https://github.com/AbnerMing8... 上面讲一下具体的应用形式,老铁们也感触下封装的是否简略,目前曾经上传了近程Maven,大家能够依赖应用。 1、在你的根我的项目下的build.gradle文件下,引入maven。 allprojects { repositories { maven { url "https://gitee.com/AbnerAndroid/almighty/raw/master" } }}2、在你须要应用的Module中build.gradle文件下,引入依赖。 dependencies { implementation 'com.vip:time:1.0.0'}依赖引入之后,咱们就能够理论的操作了,来,小试牛刀一把,和前端调用根本相似,比方一个常见的倒计时,咱们就能够如下操作。 setTimeOut(5) { //倒计时实现}没看错,调用就是这么简略,参数为须要倒计时的工夫,Long类型,是不是用法能够和Web前端相媲美,这个办法,在倒计时中,没有返回倒计时的工夫值,只会在定义的工夫后进行返回。 有的老铁问了,在倒计时的时候,我须要拿到返回的工夫值,怎么搞?必须能搞,大家能够应用上面的办法,参数呢,有两个,第一个参数为倒计时或者延时的时长,第二个参数是距离时长,默认不填是距离1秒,通过是否等于end,来判断是否倒计时实现。 setTimeDown(5) { if (it == end) { //倒计时实现 } else { val t= it.toString()//倒计时 工夫值 }}同样的,定时也是十分的简略,比方我想要实现一个有限定时器,就能够通过上面的办法,参数只有一个,就是工夫距离,也就是多少秒轮询一次。 setIntervalWireless(1) { val t = it.toString()//定时 工夫值 }有的老铁问了,理论的业务中,除了有限的定时之外,还有一些是无限的定时,比方1分钟或者10分钟,这种无限的工夫内采取定时,如何操作呢?也是十分的简略,能够应用上面的形式,两个参数,参数1为定时须要的工夫, 参数2是工夫距离,多久轮询一次。 setInterval(10, 2) { if (it == end) { //定时实现 } else { val t = it.toString()//定时 工夫值 }}提供的这四个办法,基本上能够满足理论的业务需要,能够在Activity或者Fragment里间接调用,因为要和生命周期进行绑定,如果在View或者工具类里进行应用,能够把context转为Activity后再进行调用即可。 ...

September 2, 2022 · 1 min · jiezi

关于android:心遇-Android-启动优化实践将启动时间降低-50

图片来自:https://unsplash.com/photos/_...本文作者:ZZG前言作为 APP 体验的重要环节,启动速度是各个技术团队关注的重点。几百毫秒启动耗时的增减都会影响用户的体验,并间接反馈在留存上。心遇 APP 作为一款用于满足中青年市场用户社交诉求的利用,对各个性能档次的手机型号,都要求有良好的启动体验。因而,随着用户量快速增长,启动优化作为一个性能专项被提上了日程。 启动优化,顾名思义,就是优化用户从点击 icon 到首页齐全可见这一过程的时长。为了能更好地对启动时长进行度量,咱们将它分为启动阶段和首页首刷这两局部。启动阶段即是从点击 icon 到首页首帧展现为止。首页首刷阶段则是记录从首页首帧可见到首页齐全可见的时长。 通过 5 个月的优化实际,心遇线上均匀启动时长从 8 秒多升高到 4 秒左右,启动时长减幅超过 50%,其中启动阶段升高 3.7秒,首帧首刷时长升高了 0.4秒。启动优化作为性能优化我的项目的重要组成部分,曾经胜利达到了预期的基线指标。 优化实际本文将介绍心遇团队在启动优化上所做的工作,以及在优化实际中所取得一些感悟。 利用有三种启动状态:冷启动,温启动和热启动。本文次要关注冷启动的耗时。首先咱们要明确,启动优化优化的是哪几个步骤: 在冷启动开始时,零碎过程首先会执行一系列操作,并最终创立出利用过程,而后由利用过程执行主线程启动,页面创立等工作。这个流程其实波及到的点有很多,但基于缩小从启动到首页展现这段主链路的时长这个指标来讲,咱们能够将工作聚焦于三个阶段: Application 创立,主线程工作, Activity 页面渲染。在后续的优化中,咱们也是着重优化这三个阶段的耗时点。 为了可能更好地论述各个优化措施的实现和带来的收益,咱们以 oppo A5 手机为例进行阐明。 这是优化前的 App 在 oppo A5上 的各个阶段的耗时。 从点击 icon 到首页齐全可交互,这个阶段的耗时达到了 19 秒。oppo A5 作为一款性能较差的手机,固然会对启动时长有肯定影响,然而 App 启动过程中各种不合理的逻辑和代码实现才是整个简短启动流程的次要起因。通过一系列的优化工作,App 各个启动流程的耗时如下所示: 整个启动耗时缩短至 9 秒,优化工作收益在10秒左右。接下来,咱们会分阶段阐明这10秒的收益是如何实现的。 Application 优化Application 阶段通常用于初始化比拟外围的业务库。在利用开发晚期,咱们并没有对这个阶段的启动工作进行管控,导致这里往往会沉积有大量的强业务相干的代码。在接手这个优化我的项目前,整个 Application 中执行的工作有 90 多个。在后续的优化中,咱们对整个工作流程进行了精简,基于的准则是: Application 中的工作该当是全局根底工作Application 创立时该当尽量减少网络申请操作Application 创立时不容许有强业务相干的工作Application 创立时尽量减少有 Json 解析解决和 IO 操作的工作优化后,Application 中的启动工作被缩小到了 60 多个,次要分为根底库初始化,性能配置和全局配置这三大类。根底类库次要是对网络库,日志库等根底库进行初始化配置,除了主过程外,其余的过程也依赖这些工作,移除它们会对全局的稳定性造成影响。它们也是启动工作中占比最大的,耗时最多的一类工作,因而升高它们的耗时也是前面继续优化的重点。性能配置次要是对一些全局相干的业务性能的前置配置,例如对业务缓存的预加载,特定业务前置等,移除它们会造成业务有损,在这种状况下,咱们须要找到业务诉求和性能配置之间的平衡点。全局配置次要是对于全局 UI 配置,文件门路的解决操作,它们占比少,耗时少,是首页创立的前置工作,因而暂不解决。 ...

September 2, 2022 · 3 min · jiezi

关于android:Android中的Drawable三

PS:本文系转载文章,浏览原文可读性会更好,文章开端有原文链接 目录1、TransitionDrawable2、InsetDrawable3、ScaleDrawable1、TransitionDrawable咱们基于Android中的Drawable(二)这篇文章再持续剖析其余罕用的 Drawable;TransitionDrawable 在 xml 文件中对应的标签是 transition,它实现的是2个 Drawable 之间的淡入淡出成果,为了更好的了解它,咱们也先写一个 demo;(1)在 drawable 文件夹下新建一个 my_transition.xml 文件;<?xml version="1.0" encoding="utf-8"?><transition xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/img_3"/> <item android:drawable="@drawable/img_4"/></transition>当初 img_3 的图片如下所示;img_4 的图片如下所示;(2)Activity 的布局文件 activity_transition.xml 如下所示;<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/my_transition"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/iv" android:onClick="onClick" android:text="按钮"/></RelativeLayout>名称为 TransitionActivity 的 Activity 的解决逻辑如下所示;public class TransitionActivity extends AppCompatActivity { ImageView mIv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_transition); mIv = findViewById(R.id.iv); } public void onClick(View v) { TransitionDrawable transitionDrawable = (TransitionDrawable) mIv.getDrawable(); transitionDrawable.startTransition(3000); }}app 一开始运行的效果图如下所示;当咱们点击 “按钮” 后,3s 后就变成了如下的效果图;在 my_transition.xml 文件中,transition 标签下的 item 标签其实就是一种 Drawable;个别咱们用 TransitionDrawable 作为 ImageView 的前景图,或者用作 View 的背景图,咱们可通过 TransitionDrawable 的 startTransition 和 reverseTransition 办法来实现淡入淡出的成果以及它的逆过程。2、InsetDrawableInsetDrawable 在 xml 布局文件中对应的标签是 inset;如果要实现一个 View 的背景比 View 自身还要小,能够应用 InsetDrawable 来实现,相似与 Drawable 的 padding 属性;InsetDrawable 还能够实现将其余 Drawable 内嵌到本人当中,并能够在周围留出肯定的间距;好,为了更好的了解,咱们也写一个 demo ;(1)在 drawable 文件夹下新建一个 my_inset_drawable.xml 文件;<?xml version="1.0" encoding="utf-8"?><inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetBottom="30dp" android:drawable="@drawable/img_4" android:insetTop="30dp" android:insetLeft="30dp" android:insetRight="30dp" ></inset>(2)Activity 的 activity_inset_drawable.xml 文件如下所示;<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.a86188.myapplication.InsetDrawableActivity"> <ImageView android:layout_width="match_parent" android:src="@drawable/my_inset_drawable" android:background="#FF0000" android:layout_height="200px" /></RelativeLayout>app 的运行后果如下所示;首先看一下,咱们的 ImageView 的区域是红色背景的这一块对不对?ImageView 的前景就是咱们看到的图片对不对?很显著,图片间隔 ImageView 顶部 30 dp,图片间隔 ImageView 底部 30 dp;好,咱们对开发中常见的 inset 标签的属性进行阐明一下;android:insetBottom  :  View 的背景或者前景在 View 理论区域的底部内边距。android:insetTop  :  View 的背景或者前景在 View 理论区域的顶部内边距。android:insetRight  :  View 的背景或者前景在 View 理论区域的左边内边距。android:insetLeft  :  View 的背景或者前景在 View 理论区域的右边内边距。3、ScaleDrawable ScaleDrawable 在 xml 文件中对应于 scale 标签,它能够依据本人的等级将指定的 Drawable 缩放到肯定比例,为了更好的了解,咱们也先写一个 demo 进去;(1)在 drawable 文件夹下新建一个 scale_drawable.xml 文件;<?xml version="1.0" encoding="utf-8"?><scale xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/img_3" android:scaleGravity="center" android:scaleHeight="75%" android:scaleWidth="75%"></scale>(2)Activity 的布局文件 activity_scale_drawable.xml 如下所示;<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:background="@drawable/scale_drawable" /></RelativeLayout>(3)Activity 的子类 ScaleDrawableActivity 对 ScaleDrawable 进行解决;public class ScaleDrawableActivity extends AppCompatActivity { ImageView iv; private ScaleDrawable scaleDrawable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scale_drawable); iv = (ImageView)findViewById(R.id.iv); scaleDrawable = (ScaleDrawable)iv.getBackground(); scaleDrawable.setLevel(1); }}app运行的后果如下所示;好,咱们当初将 ScaleDrawableActivity 中的 scaleDrawable.setLevel(1) 这行代码改为 scaleDrawable.setLevel(1000),而后再运行一下app,效果图如下所示;看到没有,图片显著变大了,看 ScaleDrawable 中的 setLevel 办法中的参数,参数的取值范畴是1-10000,在取值范畴内,参数越大,外部的 Drawable 就看起来越大;ScaleDrawable 的默认等级为 0,那么 ScaleDrawable 将无奈显示进去。咱们能够将 Drawable 的等级设置为大于10000 的值,比方10050,尽管也能失常工作,然而不举荐这么做,有可能会呈现其余的问题。刚刚说了,如果 ScaleDrawable 的为0,那么 ScaleDrawable 就无奈显示进去,这是不是真的呢?咱们看一下 ScaleDrawable 的 draw(Canvas canvas)办法;看到了没,当等级不为0的时候才调用 Drawable 的 draw 办法;好,咱们再看看 scale 标签的属性;android:scaleGravity:  等同于 shape 的 android:gravity 属性。android:scaleHeight  :示意 Drawable 的高的缩放比例,值越大,外部 Drawable 的高度显示得越小,  例如 android:scaleHeight=70%”,那么显示时 Drawable 的高度只有原来的30%。android:scaleWidth  :  示意 Drawable 的宽的缩放比例,值越大,外部 Drawable 的宽显示得越小,例如 android:scaleWidth=70%”,那么显示时 Drawable 的宽度只有原来的30%。 ...

September 1, 2022 · 2 min · jiezi

关于android:Android如何实现自定义短信登录丨MobTech

短信验证码SDK,为开发者提供全球通用的短信验证码工具,开发者能够用其在App植入短信验证码SDK、简略设置即可短信验证,集成疾速便捷,且前期易于治理编写xml布局创立本人的登录xml布局,在res/layout文件下新建activity_custom_login.xml文件,如下图: 绘制本人的xml布局文件,可参考如下代码: <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingTop="50dp" android:paddingRight="10dp" tools:context="cn.mob.smssdk.demo.smslogin.ui.login.CustomLoginActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/login_phone_textView" android:layout_width="0dp" android:layout_weight="3" android:layout_height="wrap_content" android:gravity="right" android:padding="10dp" android:text="@string/login_phone" /> <EditText android:id="@+id/editTextPhone" android:layout_width="0dp" android:layout_weight="9" android:layout_height="wrap_content" android:ems="10" android:text="136****6666" android:inputType="phone" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/login_code_textView" android:layout_width="0dp" android:layout_weight="3" android:gravity="center" android:layout_height="wrap_content" android:padding="10dp" android:text="@string/login_code" /> <EditText android:id="@+id/editTextNumber" android:layout_width="0dp" android:layout_weight="4" android:layout_height="wrap_content" android:ems="10" android:text="123456" android:inputType="number" /> <Button android:id="@+id/get_code_id" android:layout_width="0dp" android:layout_weight="3" android:gravity="center" android:layout_height="match_parent" android:text="@string/get_code" > </Button> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingTop="50dp" > <Button android:id="@+id/login_id" android:layout_width="100dp" android:layout_height="match_parent" android:layout_gravity="center" android:text="@string/login" /> </LinearLayout></LinearLayout>编写代码在我的项目中创立登录CustomLoginActivity类,实现性能代码如下: ...

September 1, 2022 · 3 min · jiezi

关于android:如何在保护用户隐私的同时实现精准广告投放

用户在浏览App的页面时,如果常常跳进去不喜爱的弹窗广告不仅侵害用户的浏览体验,也让用户对广告内容产生恶感。作为App的营销人员,线上投放广告时如何精准捕获用户需要,同时不引起用户的冲突心理非常重要。当用户不违心将本人的个人信息,例如年龄、性别、兴趣爱好等隐衷数据受权给App时,基于用户正在浏览的页面投放广告是个不错的抉择,它决定了一则广告是否高效地定位到指标用户。 比方,用户正在新闻App里读一篇对于现阶段新能源汽车减速倒退,续航里程大大增加,各城市也在放慢部署充电桩的文章,如果定向广告机制了解了文章的上下文内容,用户在持续浏览新闻时可能会看到对于左近新能源汽车4S店的试驾邀请的原生广告,或者对于某品牌新能源汽车购买优惠的广告,精准定位指标用户需要。 HMS Core广告服务反对个性化广告和非个性化广告,非个性化广告是不基于用户过来行为的广告,应用上下文信息进行定向。上下文信息包含用户受权以后地位的粗略(例如城市级别)天文定位,设施自带的信息(例如手机型号等)以及以后应用程序的内容或以后利用搜寻关键字上的内容。当用户在App里浏览某个内容,或者搜寻某一话题、关键词表白出了对该话题的具体趣味时,内容相干的广告零碎会扫描特定单词或单词的组合,基于用户正在浏览的页面内容推送广告。 在数据安全个人隐私面临微小挑战的明天,不少用户对于收集个人隐私数据的流动有很大冲突心理,这就意味着精准投放的广告不再精准。现集成HMS Core基于上下文信息申请广告能力,在爱护用户隐衷的同时,同样能够实现精准投放。 开发步骤1. 前提条件HUAWEI Ads SDK依赖HMS Core(APK)4.0.0.300及以上版本。如果设施上未装置HMS Core(APK)4.0.0.300及以上版本,则无奈应用HUAWEI Ads SDK的相干接口。 在开发利用前须要在华为开发者联盟网站上注册成为开发者并实现实名认证,具体方法可参见帐号注册认证。 参见创立我的项目和在我的项目下增加利用实现利用的创立。 2 .导入HUAWEI Ads SDK华为提供了Maven仓集成形式导入HUAWEI Ads SDK包。在开始开发前,您须要将HUAWEI Ads SDK集成到您的Android Studio开发环境中。 配置Maven仓地址。 Android Studio的代码库配置在Gradle 插件7.0以下版本、7.0版本和7.1及以上版本有所不同。请依据您以后的Gradle 插件版本,抉择对应的配置过程。 3 .配置网络权限在targetSdkVersion 28及以上的手机上容许HTTP(S)网络申请,在“AndroidManifest.xml”做以下配置。 <application ... android:usesCleartextTraffic="true" > ...</application>4 .配置混同脚本您编译APK前须要配置混同配置文件,防止混同HUAWEI Ads SDK导致性能异样。 关上Android工程利用级根目录下的“proguard-rules.pro”混同配置文件,退出排除HUAWEI Ads SDK的混同配置。 -keep class com.huawei.openalliance.ad.** { *; }-keep class com.huawei.hms.ads.** { *; }5 .初始化SDK您能够在AdSampleApplication类中调用HwAds.init(Context context)接口初始化SDK或者在Activity中初始化SDK。 • 倡议在利用启动的时候调用HwAds.init(Context context)接口初始化HUAWEI Ads SDK,您须要自行实现AdSampleApplication类。 6 .基于上下文信息申请广告HUAWEI Ads SDK在AdParam.Builder类中提供了setContentBundle办法,供您在广告申请时设置携带上下文信息。 示例代码如下所示: RewardAd rewardAd = new RewardAd(this, rewardId);AdParam.Builder adParam = new AdParam.Builder();String mediaContent = "{\"channelCategoryCode\":[\"剧集\"],\"title\":[\"西游记\"],\"tags\":[\"神魔\",\"冒险\"],\"relatedPeople\":[\"张三\"],\"content\":[\"该剧讲述了师徒四人西天取经……\"],\"contentID\":[\"123123\"],\"category\":[\"经典剧场\"],\"subcategory\":[\"时装\"],\"thirdCategory\":[\"悬疑\"]}\n";adParam.setContentBundle(mediaContent);rewardAd.loadAd(adParam.build(), new RewardAdLoadListener());理解更多详情>> ...

September 1, 2022 · 1 min · jiezi

关于android:如何通过经纬度坐标获取附近的地址信息

经纬度是确定每个地点地位的准确坐标,应用坐标形容一个地位,十分精确然而并不直观,面向用户表白并不敌对。HMS Core定位服务提供了逆天文编码性能,能够通过纬度获取左近地点的具体地址,将坐标转化为天文形容。例如,在电商App的地图里标定一个点,就能够显示具体位置;打车、外卖App里拖动地图或者点击地图上的某一点,定位标可能抉择左近适合的上车地址或者外卖地址;在物流配送App中,须要很准确直观的形容物流车辆所在的线路以及物流配送点,应用逆天文编码性能通过回传的经纬度坐标,来确认车辆地位。 HMS Core定位服务逆天文编码性能领有弱小的地址理解能力,应用更加本地化地位的表达方式,准确率高达90%,反对79种语言,低至200ms的时延。 Demo演示 开发步骤集成筹备注册成为开发者 在开发利用前须要在华为开发者联盟网站上注册成为开发者并实现实名认证,具体方法请参见帐号注册认证。 创立利用 参见创立我的项目和创立利用实现利用的创立。 生成并配置签名证书指纹 签名证书指纹用于校验利用的真实性,您须要依据签名证书在本地生成签名证书指纹,并在利用上架前将签名证书指纹配置到AppGallery Connect。 具体操作步骤见官网。 集成SDK 针对Android Studio开发环境,华为提供了Maven仓集成形式的SDK包。在开始开发前,您须要将SDK集成到您的Android Studio开发环境中。 具体操作步骤见官网。 开发步骤1. 创立天文编码服务客户端 在您的我的项目中应用到天文编码服务的GeocoderActivity中的onClick()办法中创立一个GeocoderService实例,通过该实例调用天文编码相干接口。 Locale locale = new Locale("zh", "CN");GeocoderService geocoderService = LocationServices.getGeocoderService(GeocoderActivity.this, locale);2. 获取逆天文编码信息 如果您心愿利用获取逆天文编码信息,能够应用定位服务中的GeocoderService对象提供的getFromLocation()接口。该接口会依据您设置的GetFromLocationRequest申请信息返回一个蕴含地位信息的List<HWLocation>对象。 2.1. 设置逆天文编码申请参数。 // 参数一:纬度// 参数二:经度// 参数三:返回后果最大数量 // 请传入正当的地区经纬度,否则没有相干地理信息返回。如果是非中国地区,请传入非中国地区的经纬度,且确保经纬度是精确的。GetFromLocationRequest getFromLocationRequest = new GetFromLocationRequest(39.985071, 116.501717, 5);2.2. 调用getFromLocation()接口,获取逆天文编码信息。 private void getReverseGeocoding() { //初始化GeocoderService对象 if (geocoderService == null) { geocoderService = new GeocoderService(this, new Locale("zh", "CN")); } geocoderService.getFromLocation(getFromLocationRequest) .addOnSuccessListener(new OnSuccessListener<List<HWLocation>>() { @Override public void onSuccess(List<HWLocation> hwLocation) { // TODO:接口调用胜利的解决 if (null != hwLocation && hwLocation.size() > 0) { Log.d(TAG, "hwLocation数据集数量: " + hwLocation.size()); Log.d(TAG, "CountryName: " + hwLocation.get(0).getCountryName()); Log.d(TAG, "City: " + hwLocation.get(0).getCity()); Log.d(TAG, "Street: " + hwLocation.get(0).getStreet()); } } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { // TODO:接口调用失败的解决 } });}2.3. Log日志为: ...

August 31, 2022 · 1 min · jiezi

关于android:美团组件化事件总线方案改进ModularEventBus

请点赞关注,你的反对对我意义重大。 Hi,我是小彭。本文已收录到 GitHub · AndroidFamily 中。这里有 Android 进阶成长常识体系,有气味相投的敌人,关注公众号 [彭旭锐] 带你建设外围竞争力。 前言大家好,我是小彭。2 年前,咱们在 为了组件化革新学习十几家大厂的技术博客 这篇文章里收集过各大厂的组件化计划。其中,有美团收银团队分享的组件化总线框架 modular-event 让咱们印象粗浅。然而,美团并未将该框架开源,咱们只能画饼充饥。 在学习和借鉴美团 modular-event 计划中很多优良的设计思维后,我亦发现计划中仍然存在不统一危险和有余,故我决定对计划进行改良并向社区开源。我的项目主页为 Github · ModularEventBus,演示 Demo 可间接下载:Demo apk。 欢送提 Issue 帮忙修复缺点,欢送提 Pull Request 减少新的 Feature,有用请点赞给 Star,给小彭一点创作的能源,谢谢。 这篇文章是 组件化系列文章第 5 篇,相干 Android 工程化专栏残缺文章列表: 一、Gradle 根底: 1、Gradle 根底 :Wrapper、Groovy、生命周期、Project、Task、增量2、Gradle 插件:Plugin、Extension 扩大、NamedDomainObjectContainer、调试3、Gradle 依赖治理4、Maven 公布:SHAPSHOT 快照、uploadArchives、Nexus、AAR5、Gradle 插件案例:EasyPrivacy、so 文件适配 64 位架构、ABI二、AGP 插件: 1、AGP 构建过程2、AGP 罕用配置项:Manifest、BuildConfig、buildTypes、壳工程、环境切换3、APG Transform:AOP、TransformTask、增量、字节码、Dex4、AGP 代码混同:ProGuard、R8、Optimize、Keep、组件化5、APK 签名:认证、完整性、v1、v2、v3、Zip、Wallet6、AGP 案例:多渠道打包三、组件化开发: 1、计划积攒:有赞、蘑菇街、失去、携程、支付宝、手淘、爱奇艺、微信、美团2、组件化架构根底3、ARouter 源码剖析4、组件化案例:通用计划5、组件化案例:组件化事件总线框架(本文)6、组件化案例:组件化 Key-Value 框架四、AOP 面向切面编程: 1、AOP 根底2、Java 注解3、Java 注解处理器:APT、javac4、Java 动静代理:代理模式、Proxy、字节码5、Java ServiceLoader:服务发现、SPI、META-INF6、AspectJ 框架:Transform7、Javassist 框架8、ASM 框架9、AspectJ 案例:限度按钮点击抖动五、相干计算机根底 ...

August 30, 2022 · 5 min · jiezi

关于android:HMS-Core基于地理位置请求广告流量变现快人一步

对于想买车的用户来说,如果走在路上刷社交软件时忽然在App里收到一条广告:“后方500米商圈里的某品牌汽车正在做优惠,力度大福利多。”不论买不买,八成都会去看看,起因有三:间隔近、需要匹配、有优惠。那么这就是一条胜利的投放广告,广告最重要的就是寻找要害的客户指标群,所以各App的营销人员都在思考如何在线上投放广告时,开掘高价值营销的空间地位,以求达到广告成果最大化。 捕获每一次的人群信息很要害,挪动的地理位置数据可能间接反映用户的理论生产流动,比方写字楼的白领喜爱点外卖,商圈潮人喜爱年轻化的娱乐活动,别墅区有钱人钟爱奢侈品、豪车等,能够通过地位信息提取用户属性,并进行广告匹配。 HMS Core提供了基于地理位置申请广告的能力,开发者能够很快在利用内集成,这种广告的劣势在于可能提供有针对性、与消费者间接产生场景关联的营销内容。例如用户在商圈左近刷社交App时,一些领有线下门店的品牌就会在利用内用原生广告的模式推送,通过发放优惠券等吸引用户购买;在学校左近,家长期待孩子放学看新闻类App时,教育机构能够通过贴片广告的模式推送课程,精准吸引用户;当用户去新城市出差,关上外卖App就能看到当地美食店用开屏广告模式做举荐。 为了更高效精准的推送广告,HUAWEI Ads SDK会依据您的利用是否领有地位权限,在申请广告时携带地位信息来助力您减少广告转化成果,晋升变现收益。 开发步骤指定利用权限1.Android提供了两种地位权限: ACCESS_COARSE_LOCATION(粗略的地位权限)和ACCESS_FINE_LOCATION(准确的地位权限)。须要在“AndroidManifest.xml”文件中配置权限: <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>2.(可选)在Android 10及以上版本中,如果您须要应用程序在后盾执行时也具备继续定位能力,须要在“AndroidManifest.xml”文件中配置ACCESS_BACKGROUND_LOCATION权限: <uses-permissionandroid:name="android.permission.ACCESS_BACKGROUND_LOCATION" />动静申请定位相干权限(Android 6.0及以上版本危险权限要求): // Android SDK<=28 所需权限动静申请 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) { Log.i(TAG, "android sdk <= 28 Q"); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { String[] strings = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}; ActivityCompat.requestPermissions(this, strings, 1); } } else { // Android SDK>28 所需权限动静申请,需增加“android.permission.ACCESS_BACKGROUND_LOCATION”权限 if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) { String[] strings = {android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION, "android.permission.ACCESS_BACKGROUND_LOCATION"}; ActivityCompat.requestPermissions(this, strings, 2); }}如果利用向用户申请并取得了地位权限时,SDK会默认携带地位信息;如果利用心愿在申请广告时,不携带地位信息,也能够调用接口setRequestLocation()设置是否携带。 ...

August 30, 2022 · 1 min · jiezi

关于android:携手HMS-Core统一扫码服务-兴业证券优理宝App提升用户扫码体验

兴业证券优理宝App联结华为HMS Core,集成HMS Core对立扫码服务,在晋升扫码成功率的同时,还反对C端用户用手机端APP扫描手表端二维码,实现行情在手机与手表间跨终端流转,行情信息,抬腕可见,为用户提供贴心金融服务。 为放弃品牌色调一致性,兴业证券在流动中会应用金色二维码,在接入HMS Core对立扫码服务之前,用户应用优理宝App扫码会呈现失败状况,影响用户体验。此外,用户扫码登录电脑端网上营业厅时,易受到光照条件的影响,呈现反光、分辨率低、含糊等状况,影响扫码成功率。 如何进步扫码成功率,晋升用户体验?HMS Core对立扫码服务提供了解决思路。 兴业证券优理宝App仅两周疾速实现HMS Core对立扫码服务接入,金色二维码的扫码成功率有较为显著的晋升,在测试反光场景、码放大、放大等场景下,扫码成功率都有所提高。此外,HMS Core还为兴业证券优理宝App提供了个性化的服务,反对C端用户用手机端APP扫描手表端二维码,实现行情在手机与手表间跨终端流转,行情信息,抬腕可见,摸索智能服务新触点,打造智能互联服务新体验。 兴业证券优理宝App与HMS Core在扫码服务上的单干为其余利用晋升用户扫码体验提供了无效参考,也以此为契机积极探索利用互联手机端与手表端的智能互联利用场景,真正让用户在理论业务场景中,享受到晦涩、智能的利用体验。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

August 29, 2022 · 1 min · jiezi

关于android:HMS-Core-Discovery第17期回顾音随我动秒变音色造型师

HMS Core Discovery第17期直播《音随我动,秒变音色造型师》,已于8月25日圆满结束,本期直播咱们邀请了HMS Core音频编辑服务的产品经理、技术专家以及翻新娱乐类利用“唱鸭”的创始人做客直播间,分享影音娱乐行业倒退的洞见及音频技术新玩法。一起来回顾本期精彩内容吧! 【精彩回顾】1、携手共进,唱鸭&HMS Core共探音频技术 2、玩法降级,歌声合成API助力用户轻松创作 3、“声”临其境,空间音频算法带来听觉盛宴 【专家观点】 Nelson,华为音频编辑产品经理 随同着音频内容同质化的竞争,音频行业将来会更加关注普通用户个性化表白的诉求,以歌声合成为代表的AI音频技术可能将普通用户蕴含的微小创作能量激发进去造成一个更宽泛的创作模式,从而带动更宽泛的受众群体。 Kong,华为音频编辑技术专家 提到虚拟世界,大家第一反馈都是AR、VR,在大家都关注在视觉交互层面时,对于听觉层面的改革其实也在悄悄产生,当初日渐成熟的空间音频及6Dof空间声场技术将给大家带来更加“声”临其境的听觉体验。 李阳,唱鸭APP创始人 用户能够通过AI技术和音乐创作编辑的联合,来实现过来很简单或者很难实现的工作可能是将来倒退的一个趋势,比如声音合成和歌声合成,声纹技术等,用户不须要本人录音,而是通过简略编辑后就能听到成绩,省掉了很多环节,同时能够更好的管制声音的成果。 【精彩答疑】Q1:歌声合成技术能够使用于什么畛域? A:歌声合成服务可广泛应用于音视频创意制作、影音娱乐、音乐教育、虚构偶像等畛域。例如,在虚构偶像畛域,通过歌声合成,能够让虚拟人领有特定音色歌唱能力,使其形象更活泼;在音乐创作或短视频创意编辑时,歌声合成服务能够助力用户自在创作合成歌曲,如唱鸭通过接入歌声合成,可使用户通过简略输出合成歌声,实现各种类型的演唱节奏,还能够管制歌声演唱的技巧,包含呼吸和滑音、颤音技巧等。 Q2:立体声、环绕声和三维声有什么区别? 音频从单声道、立体声、环绕声倒退到三维声。单声道的音频用户听着是左右耳完全一致,没有任何的方位感。到了立体声年代,用户是能够感触到不同的乐器在左右耳的不统一的出现,具备了肯定的空间感。环绕声则是在立体声的根底上减少了更多声音通道,使得音频的突围感更强。用音箱举例,立体声是后方左右两个音箱,而环绕声则是多个音箱盘绕播放,三维声则是在环绕声的根底上,给声音加上了高度,在头顶也有音箱播放。 Q3:如何对待空间音频的发展趋势? A:空间音频技术正朝着两个方向进行演进,一个是从专业化场地向着集体场景演进,将影院、剧院的试听感触带到终端,大家不须要再依赖某些固定场合,随处体验沉迷式高品质音频内容。另外一个则是从以后的固定声场向着6Dof自由度空间声场的演进,(6Dof是在3Dof根底上减少左右、前后、高低的位移,更贴近人在事实世界中的听觉感触。)联合AR、VR技术,生成新的音视频体验,带来更多新的交互玩法。 Q4:UGC时代,音频行业将来演进趋势是怎么的? A:创作内容方面,用户逐步从生产走向创作,音频内容会更偏差于个性化的表白及诉求,更加器重版权和增值服务带来的价值;技术方面,空间音频进一步倒退及遍及,音频空间技术会带来更好的沉迷感和故事感,大家不须要再依赖固定场合或设施,随处体验沉迷式高品质音频内容。音频创作方面,AI技术和音乐创作的联合,会使过来很简单或者很难实现的工作变得更加容易,基于语音的交互技术,能够省掉很多简单的解决。 欢送登录HMS Core音频编辑服务理解更多技术细节。 如有相干技术需要,请分割hmscore@huawei.com 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

August 26, 2022 · 1 min · jiezi

关于android:来开源吧发布开源组件到-MavenCentral-仓库超详细攻略

请点赞关注,你的反对对我意义重大。 Hi,我是小彭。本文已收录到 GitHub · AndroidFamily 中。这里有 Android 进阶成长常识体系,有气味相投的敌人,关注公众号 [彭旭锐] 带你建设外围竞争力。 小彭明天和群友探讨了一下学习办法的问题,感觉还挺感同身受的。有时候咱们遇到不懂的中央,潜意识会产生讨厌和恐怖,大脑会驱使咱们去学习和查看这个不懂的中央,后果有可能是陷入到另一个不懂的循环里,遗记了最后的目标。对于系统化学习和碎片化学习,你的想法是怎么的呢?评论区里通知我吧。 前言当一个开发者的程度晋升到肯定水平时,会有由外向外输入价值的需要,包含公布开源我的项目。而要公布开源组件,则须要将组件公布到公开的近程仓库,如 Jitpack、JenCenter 和 MavenCentral。其中,MavenCentral 是最风行的地方仓库,也是 Gradle 默认应用的仓库之一。 在这篇文章里,我将手把手带你公布组件到 MavenCentral 地方仓库。本文的示例程序应用小彭的开源我的项目 ModularEventBus 有用请给 Star,谢谢。 这不仅仅是一份攻略,还带着踩过一个个坑留下的泪和挠掉一根根落的贵重发丝~~~ 开发者系列文章: MavenCentral 仓库(本文)还在见招拆招?先看懂 APP 个人信息爱护治理机制应用 Markdown 高效率编写文档技术周报 | 2021 年第 13 周技术周报 | 2021 年第 11 周技术周报 | 2021 年第 10 周1. 概念梳理1.1 什么是 POM?POM(Project Object Model)指我的项目对象模型,用于形容我的项目构件的根本信息。一个无效的 POM 节点中次要蕴含以下参数: 参数形容举例groupId组织 / 公司名io.github.pengxuruiartifactId组件名modular-eventbus-annotationversion组件版本1.0.0packaging格局jar1.2 什么是仓库(repository)在我的项目中,咱们会须要依赖各种各样的二方库或三方库,这些依赖肯定会寄存在某个地位(Place),这个 “地位” 就叫做仓库。应用仓库能够帮忙咱们治理我的项目构件,例如 jar、aar 等等。 支流的构建工具都有 2 个档次的仓库概念: 1、本地仓库: 无论应用 Linux 还是 Window,计算机中会有一个目录用来寄存从地方仓库或近程仓库下载的依赖文件;2、近程仓库: 包含地方仓库和公有仓库。地方仓库是开源社区提供的仓库,是绝大多数开源库的寄存地位。比方 Maven 社区的地方仓库 Maven Central;公有仓库是公司或组织的自定义仓库,能够了解为二方库的寄存地位。1.3 Sonatype、Nexus 和 Maven 的关系:Sonatype: 残缺名称是 Sonatype OSSRH(OSS Repository Hosting),为开源我的项目提供收费的地方存储仓库服务。其中须要用到 Nexus 作为仓库管理器;Nexus: 残缺名称是 Sonatype Nexus Repository Manager,是 Sonatype 的另一款产品,用作提供仓库管理器。Sonatype 基于 Nexus 提供地方仓库,各个公司也能够应用 Nexus 搭建公有仓库;Maven: 残缺名称是 Apache Maven,是一种构建零碎。除了 Maven 之外,Apache Ant 和 Gradle 都能够公布组件。2. 新建 Sonatype 我的项目从这一节开始,我将带你一步步实现公布组件到地方仓库的操作(带你踩坑)。 ...

August 25, 2022 · 8 min · jiezi

关于android:版本发布公告HMS-Core-660来啦

剖析服务◆ 留存剖析反对¬将散失用户存为受众,开发者通过对散失人群的分层以及多维分析,在制订相干用户召回策略时将更有针对性; ◆ 原“受众剖析”更名为“人群洞察”,下设“用户分群”和“用户画像”模块。通过用户分群可实现不同维度的受众细分,通过用户画像则能够进一步剖析对应细分群组的人群画像与属性等特色; ◆ 原“卸载剖析”下设“卸载概览”和“卸载洞察”细分模块。其中,卸载洞察新增卸载流向报告,通过用户利用卸载前后的流向剖析,可帮忙开发者深度定位卸载根因; ◆ 页面剖析新增拜访时段散布。开发者能够通过对不同时间段内的拜访次数与拜访用户数比照剖析,充沛理解用户的产品应用偏好,把握适合的经营机会; ◆ 反对将“次日留存、3日留存、7日留存”回传至HUAWEI Ads,进一步丰盛广告投放成果评估指标。 查看详情>> 3D建模服务◆ 新增主动骨骼绑定能力。用户应用一般手机进行二足人形物体建模后,依据骨骼点主动适配,实现二足人形物体主动骨骼绑定,通过模型动静驱动实现自定义动作,升高普通用户3D动画创作门槛,晋升模型趣味性; ◆ 新增AR采集疏导模式。反对物体精准定位、实时采集疏导、关键帧检测,帮忙用户依照步骤实现建模,实现全新交互式建模体验。 查看详情>> 视频编辑服务◆ 原子能力SDK在AI算法内新增一键微笑能力。通过检测照片中的人像对表情进行批改,可由不笑到抿嘴微笑,或者露齿微笑,帮忙晋升人像表情开心水平; ◆ 原子能力SDK在AI算法内新增指标宰割能力。通过AI算法宰割出视频中的指标物体,达到疾速抠除视频背景的成果,罕用于各种应用场景中的背景抠除或替换。 查看详情>> 机器学习服务◆ 新增动作活体检测服务。反对实时捕获人脸,依据用户配合做动作可判断其是否为实在活体,防止翻拍图片、翻拍视频、面具等非活体攻打,进步人脸识别准确性,可利用于领取级人脸识别场景; ◆ 离线文本翻译服务新增克罗地亚语、马其顿语、乌尔都语等12个语种(其中马耳他语、波斯尼亚语、冰岛语、格鲁吉亚语不反对离线语种检测)。 查看详情>> 音频编辑服务◆ 云侧新增歌声合成能力。可能通过歌词和曲调,联合不同的曲风,智能生成真实度极高的歌声,反对字级别输出歌词进行音素转换,生成对应歌词的歌声,可调整音高、滑音、呼吸音、颤音等细节参数,让歌声更天然,该能力可广泛应用于音视频创意制作、音乐教育、虚构偶像等畛域; ◆ 云侧新增AI配音接口。反对Restful接口,可笼罩各种终端设备,满足不同开发者多设施集成需要; ◆ 云侧新增音源拆散异步接口。减少查问接口,通过taskId保护音源拆散工作全生命周期,解决音源拆散局部场景因工作耗时过长而导致用户退出并再次进入利用时却找不到之前工作的问题; ◆ 端侧音源拆散新增伴奏、贝斯、管弦乐、鼓、带伴唱伴奏、主唱和弦乐类型,满足更多音乐拆散应用场景。 查看详情>> 静止衰弱服务◆ 新增潜水闭气训练、潜水闭气测试静止记录数据类型,云侧新增自在潜水静止记录数据类型,反对多种静止场景下的数据记录; ◆ 端侧新增最大摄氧量静止采样数据类型。每一条数据代表肯定静止时间段内的最大摄氧量,可用于耐力静止中有氧静止能力的指标监测; ◆ 云侧新增地位原子采样统计数据类型凋谢。反对记录用户每一时刻的GPS地位信息,可用于登山、跑步等户外运动场景的数据记录; ◆ 云侧新增静止记录分段统计数据类型凋谢。反对分时间段统计静止记录,满足日常静止训练的数据记录剖析; ◆ 云侧新增场景事件订阅能力。反对订阅总步数指标事件,帮忙用户制订跑步走路指标并提供推送揭示性能。 查看详情>> 视频服务◆ 新增HDR Vivid SDK,提供HDR Vivid视频图像的OETF、Tonemapping、HDR2SDR等能力。实现亮度不过曝、暗处有细节的画面成果,打造超高清视频播放体验; ◆ 新增过程退出能力。在视频播放完结后开释资源,解决过程资源长时间占用问题; ◆ 新增获取播放片源缩率图列表能力。助力开发者获取视频播放片源的每帧图片,在用户迟缓滑动进度条时,可依据工夫点展示以后帧缩率图图片,优化播放应用体验; ◆ 新增精准滑动播放能力。能够精确定位到用户滑动播放的工夫点,解决因要害帧定位而造成的滑动播放不精准问题。 查看详情>> 图形引擎服务◆ 新增原子化接口3D流体组件。开发者能够应用该组件自定义流体边界范畴,设置流体液量,最终实现可能与用户交互的3D流体晃动成果; ◆ 新增动静漫反射全局光照插件。可在动静场景与光照中实时生成漫反射的全局光照,实现更加天然的光照渲染成果。 查看详情>> 地图服务◆ 示例代码hms-mapkit-demo应用SDK前需调用初始化接口MapsInitializer.initialize; ...

August 25, 2022 · 1 min · jiezi

关于android:左邻云安全-全程守护让园区安全看得见

平安,从来是永恒命题。在园区当中,园区平安也同样是经营方关注的重点,特地是随着近年来一系列安全事故的产生,更促使园区方将“平安”视为管理工作的重中之重。但因为当下的传统安防零碎普遍存在无奈疾速找出人、找到人、定位人的问题,无奈做到全面无效的防护。要建设真正的平安园区,对原有的平安管理手段进行数字化、智慧化降级革新是必经之路。左邻云平安平台依靠于华为云技术底座弱小的性能,联合人工智能、物联网、AI等技术手段,为园区打造了一套能实现事先预警、事发告警、预先剖析的平安解决方案,为园区构建全方位的长效爱护机制。事先预警事先预警,即要在安全事故产生之前及时发现并阻止,毁灭所有潜在危险。要实现这一点,做好日常安全检查和设施运维是要害。01.强化日常安全检查打造一个安全检查零碎,个别都会波及这些内容:(1)制订安全检查打算提前制订欠缺的安全检查打算,让管理人员有据可依、有规范可遵循。 (2)制订工作执行流程确定了查看内容,接下来就要明确具体操作流程,让工作规范化: (3)建设隐患整改制度隐患整改制度建设的目标,是为了让所有可能引发事变的安全隐患彻底毁灭在萌芽状态。可通过在安全检查零碎中,设立“整改治理”功能模块实现:◆ 制订整改工作表:在整改工作表页面,负责人能够随时查看以后需整改的工作及对应的工单号、查看类别、整改状态等信息。◆ 发送整改通知单:发现不合格的,相干责任人及时向整改对象发送整改通知单,并对事件处理过程进行全程跟踪,直至隐患彻底整改。(4)生成安全检查台账对产生过的所有查看工作进行记录,并生成安全检查台账,便于管理人员随时查看,进行危险剖析和管控。02.确保设施衰弱运行很多时候往往因为不足对园内设施的保护,导致有的设施设施特地是消防设备曾经损坏却全然不知,当事变产生时,便有可能因而错过最佳解决机会。因而,建设欠缺的设施运维管理体系必不可少。事发告警事变产生时,如果园区的安防零碎能在第一工夫智能精准辨认并联动工单零碎收回警报,让园区管理员能在最短时间内失去告警提醒,前去现场解决,这是最现实的成果。不过,当下有一些园区履行的安防零碎还停留在靠人坐在电脑前,看着监控视频画面来发现危险,在及时性上就大打折扣。围绕“事件失去及时处理”,能够这样做:01.做好底层撑持,实现智能感知、智能辨认感知层是园区数据采集和自动化管制层,相当于园区的感官神经,只有实现对园区内“人、事、地、物、情、组织”等治理因素的全面信息感知,能力进行相干性能利用的设置,达到零碎间的互通互联。在智能感知的根底上,再采纳先进的AI技术及边缘计算设施,实现精准智能辨认,打造实时监测、全局可调的平安预警系统,解决空间平安监测“受制于人”的难题。02.进行全域监控,做到实时监测、及时告警打造全场景笼罩的监控体系,如门禁治理、消防治理、低空抛物治理、电瓶车进电梯治理、水域治理、弱电井管控等,进行24小时监测,有异样及时告警,这是很多园区在平安治理上最外围的需要。举几个例子:(1)门禁治理智能门禁系统能智能剖析住户进出记录,到访人和被访人均可追溯,异常情况及时预警。(2)低空抛物治理通过AI技术实时获取低空抛物的相干视频证据,令小区物业管理员第一工夫取得告警提醒。(3)电瓶车进电梯治理电瓶车进电梯做到检测语音揭示,并联动进行运行,无效治理不文化行为。(4)消防治理通过消防管网平安监测和烟感探头监测,实时监测消防态势,有问题实时告警,并反对主动联动工单,及时消除隐患。 03.打造工单管理机制,做到闭环解决残缺的工单管理机制,能让相干责任人第一工夫收到告警推送告诉,是让事件失去闭环解决的最初一步。◆ 通过建设残缺的工作流,让所有节点负责人高深莫测,让工作链条清晰可见;◆ 搭建工单管理中心后盾,让下层可能实时查看工作执行后果,及时对超时未执行的工作进行督促,强化治理。预先剖析预先剖析是累积教训、总结教训的过程,这对发现园区平安治理中的弊病,改良欠缺相干制度措施,全面把握园区平安态势施展着至关重要的作用。左邻云平安通过创立事态感知核心,对设施故障检测、告警监控、能耗统计分析、人员车辆通行等各类波及园区平安的场景,进行全方位、多维度统计分析,及时生成数据报表,为空间平安态势剖析提供数据撑持,实现危险可控、可测。

August 24, 2022 · 1 min · jiezi

关于android:打造耳聪目明的MES系统你准备好了吗

“在制作企业的信息化建设中,MES零碎是绕不开的话题。MES用得好,有利于企业从教训治理变为数据管理,帮忙企业更好的决策,更敏锐地发现问题、剖析问题、解决问题。”随着JIT、BTO等新型生产模式的呈现,市场对生产现场治理的透明化有了更高的要求。MES开始受到越来越多的企业关注。然而企业面对MES也存在很多犹豫,放心开始时轰轰烈烈,后果弄成一地鸡毛。在MES施行过程中企业广泛面临:零碎边界含糊,需要不清晰;MES零碎功能模块多,主次难以判断;数据多样化,采集形式举棋不定;关涉部门多,多方关系须要协调。MES零碎的执行、施行展到底应该如何?怎么样正确抉择、施行和利用MES?首先要明确最基本的问题01除了跟风,到底为什么要上MES?其实很多企业在MES施行前没有想分明,左右摇摆、一味跟风,导致MES施行功效不佳,最终草草收场。本源就在于没有明确装置MES的目标。不同行业、不同生产模式的企业,对MES的需要是不同的,从你的企业本身特点登程,联合生产理论状况,须要上全套的MES零碎,还是只须要MES中的某些模块,是否须要在其根底上进行拓展利用,这些都须要深度思考,企业须要从本身和内部两个角度登程,认真掂量。透明化治理在B2B业务中的必要性越来越高。当产品产生品质问题,能够随时根据相干数据信息进行追溯。作为连贯决策层和管制层的执行层,MES买通了生产治理部门和生产执行部门的信息壁垒,从生产打算的执行、生产过程的追溯、工人的排班和激励机制等多个维度确保生产工作的高效实现。至于到底为什么要上MES,以下这些如果都中,那阐明你是真的须要!企业出于本身治理和品牌建设的需要,须要对生产过程有所把控。想要通过零部件追溯、不良品记录等,对产品质量有所管制;想要通过设施良率,排产等,对生产效率进行治理;想要通过及时获取订单生产情况,增强对交期的管制,以及时应答突发事件。如果企业的生产管理混乱、产品交付周期无奈保障、有效老本与有效费用曾经到了肉眼可见境地,而又有肯定的信息化根底(甚至说信息化曾经获得相当的功效),那的确须要须要MES零碎来实现提效增速,缩小节约,节约资源,晋升治理的指标与业务匹配的柔性能力。02上MES必须要包含哪些模块能力解决问题?MES零碎是一个非常复杂的零碎,企业要依据本身需要来抉择不同的功能模块和组装的优先程序。有三个性能是必要的:1.数据采集。如何高效的采集车间的各类数据,是决定MES我的项目施行成败的关键环节。采集的数据品种和采集伎俩可能会有所差别,但数据采集的模块是必须的;2.过程治理。没有这个模块,MES就不能施展作为执行层的实质作用;3.和其余软件系统产生数据的接口。如果没有能和ERP、PLM、CRM等零碎产生数据的接口,MES就无奈把订单、客户数据、洽购数据等集中起来,MES的执行就是一句空话,因而接口也是至关重要的局部。数据采集是利用MES进行统计分析的基本。企业MES建设中应该充分考虑其数据采集的特点,使用多种数据采集形式,来保障数据的完整性和实时性。在应用MES过程中,企业能够间接从内部取得产品编码、工序名称、工艺条件数据等或由零碎通过条码、传感器、RFID等设施自发收集工序操作的起始工夫、设施状态等生产过程数据。MES零碎的建设,从管理层的角度,是为了将一体化管控触角和理念延长到车间每道工序和每个员工;从业务的角度,是为了解决生产凌乱、车间治理无序、标准化水平低、随机性强、人机料法环的有序治理的问题。——某制作企业IT负责人03上MES,你还须要时刻牢记!MES是执行零碎,执行的前提是有指令,有打算。因而,MES零碎相对不是一个MES零碎,而是集各个上游零碎、业务管理、生产管制、变动调度为一体的后果执行者,同时须要与各个系统进行实时的数据互动与动静调整。所以MES的业务布局、规定与流程的制订、性能的实现、数据结构的设计,须要从全公司、全局的角度去思考。鼎捷助力 打造耳聪目明MES零碎不仅仅为了施行而施行,企业要时刻记得装置MES零碎是为了采集更多数据,通过开掘这些数据的关联和价值,来发现问题、剖析问题,从而驱动决策解决问题,并在之后的生产经营过程中谨防相似问题的产生,因而,打造适宜本人的、耳聪目明的MES零碎尤为重要。

August 24, 2022 · 1 min · jiezi

关于android:MobTech-ShareSDK-高级接口及配置

对于须要高阶接口实现某些性能的开发者,MobTech还提供以下从属接口和相干配置,心愿能够给你带来更欢快的开发情绪。有其余进阶配置需要可点击此链接 九宫格暗藏某个平台的显示OnekeyShare oks = new OnekeyShare();//一键分享九宫格界面暗藏QQ平台oks.addHiddenPlatform(QQ.NAME);九宫格界面增加自定义平台OnekeyShare oks = new OnekeyShare();Bitmap logo = BitmapFactory.decodeResource(MobSDK.getContext().getResources(), R.drawable.ic_launcher);String label = "ShareSDK";View.OnClickListener listener = new View.OnClickListener() { public void onClick(View v) { //增加自定义平台对应的图片点击事件 }};oks.setCustomerLogo(logo, label, listener);留神:自定义平台该接口只能增加一个平台,默认是最初九宫格最初一位展示;具体的其余自定义显示请自行浏览OneKeyShare源码更改,OneKeyShare是齐全开源的。 敞开“分享操作正在后盾进行”的提醒OnekeyShare oks = new OnekeyShare();//敞开“分享操作正在后盾进行”的提醒oks.setDisappearShareToast(true);Gradle形式集成去除OneKeyShareShareSDK默认会增加OnekeyShare库,如果你不须要这个库,能够在ShareSDK下设置“gui false”来敞开OnekeyShare // 在MobSDK的扩大中注册ShareSDK的相干信息MobSDK { appKey "Mob开发者后盾申请的AppKey" appSecret "Mob开发者后盾申请的AppSecret" ShareSDK { gui false devInfo { ... } }}Gradle形式集成固定ShareSDK的版本号MobSDK默认为ShareSDK提供最新版本的集成,如果你想锁定某个版本,能够在ShareSDK下设置“version “某个版本””来固定应用这个版本 // 在MobSDK的扩大中注册ShareSDK的相干信息MobSDK { appKey "Mob开发者后盾申请的AppKey" appSecret "Mob开发者后盾申请的AppSecret" ShareSDK { version '3.7.3' devInfo { ... } }}设置应用HTTPS协定MobSDK默认应用http网络协议,如果你想应用https协定,能够在我的项目的AndroidManifest.xml文件下减少以下配置 : ...

August 24, 2022 · 1 min · jiezi

关于android:电商行业全链路监测广告投放效果用数据驱动业务增长

哪个营销工作、营销渠道的引流用户更多? 买量用户的沉闷、留存状况如何? 哪个营销工作引流的用户后续的加购、下单转化最多? HMS Core剖析服务作为广告转化跟踪工具,广告主可实现从“曝光、点击、下载、激活、注册、留存、珍藏、退出购物车、下单、开始结算、领取胜利、复购”的全链路监测,让市场营销同学从繁冗的数据收集、整顿中解放出来,监测营销成果,疾速找到高质量用户,专一于思考投放策略的调整方向。 便捷回传,高效归因:无缝连接HUAWEI Ads,后链路转化事件便捷回传,让归因更高效,实现投放老本与获客效率的双向优化; 行业定制,多维指标剖析:深挖行业痛点,提供体系化电商强关联埋点计划,并基于此装备多样、外围的指标深度解读,一站式解决电商行业利用增长难题; 丰盛标签,精准人群分层:事件与标签的多维组合,让人群分层更加精准。AI算法加持,高潜付费人群与高风险散失人群提前预测,高效经营,无效晋升GMV; 买量辨认,量化渠道投放与转化成果:营销归因辨别买量与天然量,剖析、洞察不同人群价值转化差别,以数据掂量各渠道留存与收益转化差别,甄选优质渠道,正当调配营销资源,优化投放策略; 深度洞察,精益经营:全生命周期笼罩,多业务场景,提供留存、门路、漏斗等丰盛的分析模型,帮忙开发者实现数据驱动的精细化经营; 跨平台、多设施剖析:反对Android、iOS、Web等平台不同设施的用户进行对立剖析,用户行为特色残缺解读,不割裂。 场景一:剖析不同营销渠道、营销工作的转化贡献率,优化资源配置,晋升ROI无需开发,广告主通过剖析服务控制台将转化事件实时回传HUAWEI Ads,便可在Ads查看每个广告工作带来的转化数量,并且在剖析服务进一步剖析各营销渠道、营销工作的转化奉献状况,如哪一个渠道带来的用户下单转化量最高。通过用户奉献的商业价值来预估该工作将来的转化品质,决定是否须要调整渠道投放策略。 举荐应用剖析服务性能:营销归因剖析 剖析服务的营销归因剖析可精准还原每次转化的奉献散布。辨认营销渠道或营销工作对指标转化事件的贡献率,帮忙掂量不同渠道或营销工作的转化成果,优化资源配置。如剖析同一渠道不同工作带来的下单事件的奉献占比,对于转化贡献率高的工作继续投放,转化贡献率低的工作进行减投解决。 (此数据为虚构数据) 场景二:构建买量用户画像,深度洞察高质量用户每天新增的用户中有多少来自营销流动?买量用户又在利用内产生了多少付费?您能够在剖析服务查看买量用户的新增、沉闷与付费状况,无效掂量营销流动带来的用户品质。 举荐应用剖析服务性能:新增用户剖析、买量用户剖析 您能够在剖析服务的新增用户剖析中查看新增用户的剖析报告,包含买量用户的新增趋势和详情,通过弱小的过滤器和比照剖析性能进行下钻剖析,多维度洞察买量用户的相干状况。 此外剖析服务的买量用户剖析报告,帮忙您剖析买量用户后续的行为,您能够清晰洞察买量用户剖析的要害指标值,反对新增买量用户、沉闷买量用户、付费买量用户、买量用户付费金额、新增买量用户留存和沉闷买量用户留存剖析。 场景三:跟踪用户利用内行为,及时调整营销打算与策略对于电商产品来说,清晰的理解用户在利用中的行为门路,对验证经营思路、领导产品迭代十分重要。用户在利用内应用行为的监控与剖析,能够帮忙开发者多维度洞察用户特色,以便更精准的定制用户拉新、促活、留存与召回策略。 举荐应用剖析服务性能:事件剖析、页面剖析、会话路径分析、卸载剖析、付费剖析 用户从登录App到领取胜利,要通过首页浏览、商品搜寻、商品详情页浏览、退出购物车、提交订单、领取订单等过程。但用户实在的选购过程不肯定遵循以上程序,例如提交订单后,用户可能会返回首页持续搜寻商品,也可能勾销订单。 这时就可通过会话路径分析模型与其余模型联合,进行深刻的下钻剖析,引领用户走向更好的门路或产品设计冀望的门路。 推广不同产品的转化跟踪形式抉择: 如果您推广的电商产品不仅有利用也有网页,您能够通过剖析服务和华为DTM轻松实现转化跟踪,并在剖析服务查看推广带来的买量用户后续的行为事件剖析以及不同营销渠道、营销工作的归因剖析。 以上就是剖析服务买量洞察与渠道评估解决方案,欲了解其余精密经营场景,可通过拜访官网理解更多。即刻集成,体验更优质的广告投放体验! 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

August 24, 2022 · 1 min · jiezi

关于android:828选华为云实惠更实用为什么选择华为云CDN的企业多

网页图片多、加载慢、用户体验差,背地很大一部分起因其实是网站的服务器不给力。针对此状况,开发者就须要应用CDN 服务,为网站业务减速。而在泛滥的CDN厂商中,为何华为口碑始终很好,上面说下我对华为云CDN产品的测评,分享我的企业上云新体验。 华为云CDN是什么?内容散发网络(Content Delivery Network,简称CDN)是建设并笼罩在承载网之上,由散布在不同区域的边缘节点服务器群组成的分布式网络。CDN利用宽泛,反对多种行业、多种场景内容减速,例如:图片小文件、大文件下载、视音频点播、直播流媒体、全站减速、平安减速。简而言之,CDN就是一个加速器。 华为云CDN工作原理:网站通常将其所有的服务器都放在同一个中央,当用户群减少时,企业就必须在多个地理位置不同的服务器上部署内容,为了缩短http申请的工夫,咱们应该把大量的动态资源搁置的离用户近一点。内容散发网络CDN是一组散布在多个不同地理位置的web服务器,用于更加无效的向用户公布内容 CDN减速的基本思路:尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳固。通过在网络各处搁置节点服务器所形成的在现有的互联网根底之上的一层智能虚构网络,CDN零碎可能实时地依据网络流量和各节点的连贯、负载情况以及到用户的间隔和响应工夫等综合信息将用户的申请从新导向离用户最近的服务节点上。 CDN的基础架构:最简略的CDN网络由一个DNS服务器和几台缓存服务器组成1.当用户点击网站页面上的内容URL,通过本地DNS零碎解析,DNS零碎会最终将域名的解析权交给CNAME指向的CDN专用DNS服务器。2.CDN的DNS服务器将CDN的全局负载平衡设施IP地址返回用户。3.用户向CDN的全局负载平衡设施发动内容URL拜访申请。4.CDN全局负载平衡设施依据用户IP地址,以及用户申请的内容URL,抉择一台用户所属区域的区域负载平衡设施,通知用户向这台设施发动申请。5.区域负载平衡设施会为用户抉择一台适合的缓存服务器提供服务,抉择的根据包含:依据用户IP地址,判断哪一台服务器距用户最近;依据用户所申请的URL中携带的内容名称,判断哪一台服务器上有用户所需内容;查问各个服务器以后的负载状况,判断哪一台服务器尚有服务能力。基于以上这些条件的综合剖析之后,区域负载平衡设施会向全局负载平衡设施返回一台缓存服务器的IP地址。6.全局负载平衡设施把服务器的IP地址返回给用户。7.用户向缓存服务器发动申请,缓存服务器响应用户申请,将用户所需内容传送到用户终端。如果这台缓存服务器上并没有用户想要的内容,而区域平衡设施仍然将它调配给了用户,那么这台服务器就要向它的上一级缓存服务器申请内容,直至追溯到网站的源服务器将内容拉到本地。 华为云CDN劣势:1、稳固;面对业务突增的高并发、大流量,带宽储备是要害。华为云CDN与主导运营商合营海量资源,带宽储备能力超100 Tbps,有足够的冗余承载突发性超大流量,帮忙客户从容应对流量顶峰。华为云CDN通过哈勃零碎实时监测端到端性能,如网络时延、丢包率、可用性、首包工夫等指标状况,智能品质告警,第一工夫发现问题并主动定位修复。同时将AI学习、智能算法利用于软硬件故障的预测中,可能做到实时预测、提前感知、事先预防,保证系统的高牢靠运维。2、平安;华为云CDN建设了一整套欠缺的平面平安保障体系,首先,反对全网所有节点HTTPS加密传输,让客户享受到企业级牢靠的HTTPS减速服务;同时,反对网站防盗链等高级安全控制性能,为客户的平安防护穿上了金钟罩。此外,在CDN传输的过程中,反对内容一致性的校验并进行异样告警,及时发现被篡改内容,保障内容平安。另一方面,互联网业务网络劫持景象频频产生,间接侵害到企业与用户利益,劫持问题须要借助运营商资源解决,非厂商和客户可独立解决,华为云CDN通过与运营商高效联动机制可在24小时闭环常见劫持,比业界缩短48小时闭环时长。华为云团队7*24小时业余服务响应,并为大客户装备独立团队撑持,全方位保障客户业务。3、性价比高;在计费形式优化方面,华为云CDN推出全新“组合宝” 蕴含CDN全时流量包和CDN闲时流量包,CDN闲时流量包应用工夫为北京工夫00:00-18:00,白天都是大家学习、工作最忙碌的时段,绝对大家的忙时CDN正是闲时时段。“闲时流量包”是一种全新的计费形式,白天独自计算流量生产,闲时才应用。对于教育、医疗、政企、金融等行业的业务,刚好白天正是业务忙碌时段,错峰应用CDN是最划算不过了!这样能够破费更少的钱应用CDN减速服务,CDN组合宝忙闲时流量包搭配,综合老本比一般流量包升高20%~40%,实现业务效率和用户体验双重晋升。 华为云CDN利用场景:1、图文社群平台网站:从门户时代开始,图文门户就始终都是坚守在互联网一线的服务平台,新浪、网易、搜狐等平台都会每日散发海量的图片及文字信息给到宽广的互联网用户。从博客到论坛,再到贴吧,图文网站作为最早的社群网媒平台,具备用户数量宏大、粘性高、不易转移等特点。所以,用户对图文网站平台的拜访在近几年仍旧很高。2、在线视频,随着5G正式商用,将来用户对在线视频的数量和品质需要只会更大。如何在微小流量的涌入下,保障视频不卡顿,成为了CDN服务要害。一些热播剧、黄金综艺的汇集平台,领有宏大的用户数。流量猛增给服务器带来了微小的拜访压力,影响视频播放成果。3、短视频平台的日沉闷用户曾经过亿,人均每日刷视频工夫达到一个小时之久。随着5G时代的到来,5G用户势必逐步减少,将带来更大的流量加持,用户流量老本将继续降落,能够预感,短视频的用户会继续减少。拜访上,海量并发的拜访对源站造成微小的压力,进而导致用户关上视频的耗时长,体验差;传输上,短视频文件较大,在传输链路中,因为网络链路抖动造成用户观看卡顿等状况呈现,这是面向短视频平台的重要阻碍之一。4、网游,5G高速、低时延的时代会让游戏进入暴发增长时代,5G大环境下,高并发、用户散布广、网络环境简单多样等因素影响着用户的游戏体验。此外还有,游戏下载安装包文件大、游戏场景内容多让用户在下载或加载时限度更多。而网友对极致网速、真切画面的谋求会越来越刻薄,尤其在MOBA类游戏流行的当下,游戏的低时延以及稳定性齐全决定了手游以及端游是否胜利在这个争分夺秒的市场存活下来。这时候,CDN的减速成果能保障游戏用户优质稳固的游戏体验。5、实时生存利用,智慧城市、智慧家居、物流交通等等理论场景,都离不了CDN,尤其是一些在实时性要求比拟高的,交通、路况、天气等智慧利用。6、电商平台,电商平台是CDN服务的老话题,往年828大促,各家电商平台再一次纷纷刷新了本人的成交额记录。巨额数字的背地意味着电商交易流量的顶峰,要让电商走得更远、更顺畅,也少不了CDN技术的加持。828企业上云节,成就好生意,成为好企业。华为云CDN828企业上云节,实惠更实用,企业客户在各种业务场景中有减速需要的都能够借此机会上量晋升本身业务体验啦!

August 22, 2022 · 1 min · jiezi

关于android:华为游戏服务同一游戏同一个手机号的华为帐号登录返回的playerId不同

问题形容咱们华为渠道的一款游戏,接到现网某玩家反馈:手机和平板上登录同一个华为帐号,然而两边的游戏数据不同步。通过咱们剖析,发现该用户应用的是同一个手机号的华为帐号,登录游戏时华为游戏SDK的getCurrentPlayer接口返回的playerId不一样,导致用户数据没法互通。详细信息如下: 手机用户昵称:丁XXplayerId:118403426平板用户昵称:hwXXXplayerId:119202015问题定位分割华为技术反对(可提单)后,技术支持回答:playerId 1184*03426playerId 1192*50201 发现这两个playerId查到的华为帐号是不同的。然而手机号的确是一样的。 问题起因华为技术回答,呈现这种状况的可能起因是手机号码二次放号。用户在注册华为帐号的时候,如果这个手机号以前曾经注册过华为帐号,他又从新注册,零碎会进行提醒,请您确认这个帐号是否是本人的。如果抉择“不是,持续注册”,用户会开始以这个手机号持续注册新的华为帐号。这种状况是会呈现一个手机号码有2个华为号的状况。 问题解决这种状况,当玩家应用手机号登陆的时候,页面会提醒这个手机号有2个华为号,以前设施上登录的华为号是哪个,就抉择对应的即可,多部设施间保持一致。 如果用户不晓得他的华为号是多少,那么能够让他登录到帐号核心,点个人信息,那里会有显示,让他记住他的角色是在哪个华为号下,而后每次登录的时候选那个号登录就行。如下图信息

August 22, 2022 · 1 min · jiezi

关于android:机器学习服务文本翻译能力升级中文直译模型让译文表达更地道

HMS Core机器学习服务文本翻译能力提供多种语言和多种利用场景的翻译服务,比方,在出国游览的场景中,用户能够借助利用的语音翻译播报性能在打车、酒店入住等场景中无障碍沟通,也能够通过拍照翻译性能读懂餐厅菜单、路牌信息等。 中文直译模型让文本翻译能力降级以后支流的翻译模式大都以语料资源较为丰盛的英文作为两头语言进行“桥接”翻译,然而经英文转移后翻译精度有所损失,且计算资源加倍执行成果升高。为了响应“一带一路”倡导,助力多元凋谢的全球化过程,国内出海利用语种翻译需要明确且要求零碎本地化部署,对局部语言方向如中日、中俄等翻译品质要求较高,同时心愿这些语言方向的翻译成果继续晋升。 基于此,HMS Core机器学习服务对文本翻译能力进行降级,中日、德、法、俄四国语言的中文直译模型已在新版本中上线。相较于英文桥接翻译,中文直译模型可实现每秒并发300字符,端到端翻译速度小于150ms,翻译时延升高100%,翻译速度更快;针对中文特色词、俚语的翻译后果更纯粹,翻译品质更优。降级后的文本翻译能力能够满足中企出海或外企入华等对翻译要求更高场景的需要。 中文直译模型计划还加入了WMT2021国内机器翻译大赛子工作(Shared Task: Triangular MT: Using English to improve Russian-to-Chinese machine translation),并以显著的劣势在该工作中取得了第一名。 中文直译和桥接翻译成果比照 法译中 【原文】Smart Launcher est un lanceur pour d’applications Android qui substitue l'interface classique de votre téléphone avec une autre qui est un peu plus simple et qui vous permettra d'accéder à toutes vos applications plus rapidement et plus confortablement. 【英文桥接】智能启动器是一款Android应用程序的启动器,它能够用一个简略一点的界面取代手机的经典界面,让你更快、更舒服地拜访所有应用程序。 【中文直译】Smart Launcher是一款Android应用程序启动器,它用另一个更简略的界面取代了手机的经典界面,这将让您更快、更舒服地拜访所有应用程序。 俄译中 【原文】, , - , , , . 【英文桥接】哦,托付,在走廊里有人对你无礼,毫无疑问,是你高中时面临的最不重要的问题。 【中文直译】哦,托付,当有人在走廊里对你无礼无疑是你在高中时遇到的最小的问题。 德译中 ...

August 22, 2022 · 1 min · jiezi

关于android:如何快速开发一个健康助手实时守护用户健康

随着人们生存程度的进步,大家对衰弱越来越器重和关注,用户在应用一些衰弱App时不仅想晓得身高体重等根底状况,还想理解一些对于心率、血氧等日常数据,不便随时关注本身健康状况。这时候就须要App每天关注衰弱数据并且记录下来,如日常饮食、睡眠习惯,心率、血压血糖变动和静止数据等,并且建设一份集体衰弱档案,查看一段时间内如一周、一个月的衰弱数据变化趋势,第一工夫关注异样数据,从而及时就医或者调整生活习惯。如此一来,用户便能够更好地掌控本人的健康状况,医生也能够更精确地诊断。 那么对于衰弱App来说,如何实现以上性能呢?华为静止衰弱服务(Health Kit)为开发者凋谢根底能力。通过集成Health Kit根底能力,您能够疾速为App构建根底性能,如读取、插入、删除、更新一日或多日衰弱记录,为用户带来优质体验。 开发者利用通过接入Health Kit根底能力服务,在用户受权后,即可获取华为静止衰弱App上用户的云侧衰弱数据,并在利用上展现给用户。 成果示例 此Demo在静止衰弱服务根底能力服务示例代码根底上进行批改,感兴趣的开发者可自行下载体验优化。 开发筹备注册帐号及申请帐号服务:因Health Kit服务须要用到帐号服务的能力,需先申请华为帐号服务后能力申请Health Kit服务。申请Health Kit服务:申请产品所需的数据读写权限。在开发服务中找到并申请Health Kit服务。勾选产品须要申请的数据权限,这里咱们须要申请的身高、体重属于非受限数据,提交申请后会疾速审核通过,心率、血压、血糖、血氧饱和度属于受限数据,须要通过人工审核。 集成HMS Core SDK:在开发利用前,须要将Health Kit扩大服务能力的SDK集成到开发环境中。应用Android Studio关上我的项目工程,找到并关上我的项目工程根门路下的build.gradle文件。在“allprojects > repositories”和“buildscript > repositories”外面减少SDK的maven仓地址。 maven {url 'https://developer.huawei.com/repo/'}关上app下利用级的build.gradle文件,在“dependencies”中增加如下编译依赖。 implementation 'com.huawei.hms:health:{version}'从新关上批改完的build.gradle文件,右上方呈现Sync Now链接。点击“Sync Now”期待同步实现。 配置混同脚本:编译APK前须要配置混同配置文件,防止混同HMS Core SDK导致性能异样。在利用级根目录下关上混同配置文件“proguard-rules.pro”,退出排除HMS Core SDK的混同配置脚本。 -ignorewarnings-keepattributes *Annotation*-keepattributes Exceptions-keepattributes InnerClasses-keepattributes Signature-keepattributes SourceFile,LineNumberTable-keep class com.huawei.hianalytics.**{*;}-keep class com.huawei.updatesdk.**{*;}-keep class com.huawei.hms.**{*;}导入证书指纹、批改包名、配置JDK编译版本:依据“创立利用的Keystore文件”指南,生成Keystore文件并导入到利用中,导入后,关上利用级的“build.gradle”文件,能够看到导入的后果。 批改利用包名,利用包名应与“申请帐号服务”中填写的包名保持一致。关上App下利用级根目录的“build.gradle”文件,在“android”中新增compileOptions配置,配置格局如下: compileOptions { sourceCompatibility = '1.8' targetCompatibility = '1.8'}次要实现代码拉起登录页面进行登录受权。/** * Add scopes to apply for and obtains the authorization process Intent. */private void requestAuth() { // Add scopes to apply for. The following only shows an example. // Developers need to add scopes according to their specific needs. String[] allScopes = Scopes.getAllScopes(); // Obtains the authorization process Intent. // True indicates that the health app authorization process is enabled. False indicates disabled. Intent intent = mSettingController.requestAuthorizationIntent(allScopes, true); // The authorization process page is displayed. startActivityForResult(intent, REQUEST_AUTH);}调用 com.huawei.hms.hihealth. DataController类的readLatestData() 接口,读取衰弱相干的最新数据。包含用户的身高、体重、心率、血压、血糖和血氧。/** * read the latest data basing on data type * * @param view (indicating a UI object) */public void readLatestData(View view) { // 1. Use the specified data type (DT_INSTANTANEOUS_HEIGHT) to call the data controller to query // the latest data of this data type. List<DataType> dataTypes = new ArrayList<>(); dataTypes.add(DataType.DT_INSTANTANEOUS_HEIGHT); dataTypes.add(DataType.DT_INSTANTANEOUS_BODY_WEIGHT); dataTypes.add(DataType.DT_INSTANTANEOUS_HEART_RATE); dataTypes.add(DataType.DT_INSTANTANEOUS_STRESS); dataTypes.add(HealthDataTypes.DT_INSTANTANEOUS_BLOOD_PRESSURE); dataTypes.add(HealthDataTypes.DT_INSTANTANEOUS_BLOOD_GLUCOSE); dataTypes.add(HealthDataTypes.DT_INSTANTANEOUS_SPO2); Task<Map<DataType, SamplePoint>> readLatestDatas = dataController.readLatestData(dataTypes); // 2. Calling the data controller to query the latest data is an asynchronous operation. // Therefore, a listener needs to be registered to monitor whether the data query is successful or not. readLatestDatas.addOnSuccessListener(new OnSuccessListener<Map<DataType, SamplePoint>>() { @Override public void onSuccess(Map<DataType, SamplePoint> samplePointMap) { logger("Success read latest data from HMS core"); if (samplePointMap != null) { for (DataType dataType : dataTypes) { if (samplePointMap.containsKey(dataType)) { showSamplePoint(samplePointMap.get(dataType)); handleData(dataType); } else { logger("The DataType " + dataType.getName() + " has no latest data"); } } } } }); readLatestDatas.addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { String errorCode = e.getMessage(); String errorMsg = HiHealthStatusCodes.getStatusCodeMessage(Integer.parseInt(errorCode)); logger(errorCode + ": " + errorMsg); } });}其中的DataType对象蕴含具体的数据类型,和数据的值,进行解析即可拿到对应的数据。 ...

August 19, 2022 · 2 min · jiezi

关于android:Android-边播放边缓存视频框架AndroidVideoCache简析

一、背景当初的挪动利用,视频是一个十分重要的组成部分,如同外面不搞一点视频就不是一个失常的挪动App。在视频开发方面,能够分为视频录制和视频播放,视频录制的场景可能还比拟少,这方面能够应用Google开源的 grafika。相比于视频录制,视频播放能够抉择的计划就要多许多,比方Google的 ExoPlayer,B站的 ijkplayer,以及官网的MediaPlayer。 不过,咱们明天要讲的是视频的缓存。最近,因为咱们在开发视频方面没有思考视频的缓存问题,造成了流量的节约,而后受到用户的投诉。在视频播放中,个别有两种两种策略:先下载再播放和边播放边缓存。 通常,为了进步用户的体验,咱们会抉择边播放边缓存的策略,不过市面上大多数的播放器都是只反对视频播放,在视频缓存这块基本上没啥好的计划,比方咱们的App应用的是一个本人封装的库,相似于PlayerBase。PlayerBase是一种将解码器和播放视图组件化解决的解决方案框架,也即是一个对ExoPlayer、ijkplayer的包装库。 二、PlayerBasePlayerBase是一种将解码器和播放视图组件化解决的解决方案框架。您须要什么解码器实现框架定义的形象引入即可,对于视图,无论是播放器内的管制视图还是业务视图,均能够做到组件化解决。并且,它反对视频跨页面无缝连接的成果,也是咱们抉择它的一个起因。 PlayerBase的应用也比较简单,应用的时候须要独自的增加解码器,具体应用哪种解码器,能够依据我的项目的须要自在的进行配置。 只应用MediaPlayer: dependencies { //该依赖仅蕴含MediaPlayer解码 implementation 'com.kk.taurus.playerbase:playerbase:3.4.2'}应用ExoPlayer + MediaPlayer dependencies { //该依赖蕴含exoplayer解码和MediaPlayer解码 //留神exoplayer的最小反对SDK版本为16 implementation 'cn.jiajunhui:exoplayer:342_2132_019'}应用ijkplayer + MediaPlayer dependencies { //该依赖蕴含ijkplayer解码和MediaPlayer解码 implementation 'cn.jiajunhui:ijkplayer:342_088_012' //ijk官网的解码库依赖,较少格局版本且不反对HTTPS。 implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8' # Other ABIs: optional implementation 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8' implementation 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8' implementation 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8' implementation 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8' }应用ijkplayer + ExoPlayer + MediaPlayer dependencies { //该依赖蕴含exoplayer解码和MediaPlayer解码 //留神exoplayer的最小反对SDK版本为16 implementation 'cn.jiajunhui:exoplayer:342_2132_019' //该依赖蕴含ijkplayer解码和MediaPlayer解码 implementation 'cn.jiajunhui:ijkplayer:342_088_012' //ijk官网的解码库依赖,较少格局版本且不反对HTTPS。 implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8' # Other ABIs: optional implementation 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8' implementation 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8' implementation 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8' implementation 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8' }最初,在进行代码混同时,还须要在proguard中增加如下混同规定。 ...

August 18, 2022 · 5 min · jiezi

关于android:应用缺少POI数据如何开发地点深度信息

用户在App里搜寻某个地点时,并不满足繁多的地点信息,心愿失去更多能够帮忙其做决策的深度信息。例如有打车出行需要的用户,在打车App里搜寻地点时能够显示周边的地点,准确到某个路口,让用户能够自由选择适合的上下车点。银行金融App类能够让用户在搜寻时显示左近线下网点和营业时间、电话以及周边路线信息等。 不过在App里开发搜寻地点的相干信息性能须要大量的地点数据等信息,面对数据不够的状况,怎么能力开发提供用户在查看不同类型的地点(如酒店、餐饮、景点)时,能够获取到有针对性的深度信息(如营业时间、评分等)的能力呢? HMS Core位置服务提供一站式搜寻服务,领有2.6+亿寰球POI数据,笼罩200+国家与地区,反对寰球70+种语言。其中地点详情性能能够根据地点的惟一主键地点ID获取地点详情,地点详细信息申请返回无关指定地点的更全面的信息, 如地点名称、地址详细信息、经纬度等。比方用户关上物流类App能够搜寻到左近网点、营业时间、电话等;旅行类App提供搜寻景点具体的地位、左近的酒店、天气等;LBS类游戏也能够基于地点详情性能做相干改编,在游戏内搜寻某地点时能够查看该地点的工作、玩家、区域排名等。 Demo演示 开发步骤1. 开发筹备1.1 配置AppGallery Connect 在开发利用前,须要在AppGallery Connect中配置相干信息。 1.2 集成HMS Core SDK 针对Android Studio开发环境,华为提供了Maven仓集成形式的HMS Core SDK包。在开始开发前,您须要将HMS Core SDK集成到您的Android Studio开发环境中。 1.3 配置混同脚本 编译APK前须要配置混同配置文件,防止混同HMS Core SDK导致性能异样。 具体筹备步骤可参考华为开发者联盟官网。 2. 地点详情// 申明SearchService对象 private SearchService searchService; // 创立SearchService实例 searchService = SearchServiceFactory.create(this, "API key");// 创立申请体 DetailSearchRequest request = new DetailSearchRequest(); request.setSiteId("C2B922CC4651907A1C463127836D3957"); request.setLanguage("fr"); request.setChildren(false);// 创立搜寻后果侦听器 SearchResultListener<DetailSearchResponse> resultListener = new SearchResultListener<DetailSearchResponse>() { // 失常后果返回 @Override public void onSearchResult(DetailSearchResponse result) { Site site; if (result == null || (site = result.getSite()) == null) { return; } Log.i("TAG", String.format("siteId: '%s', name: %s\r\n", site.getSiteId(), site.getName())); } // 异样后果返回 @Override public void onSearchError(SearchStatus status) { Log.i("TAG", "Error : " + status.getErrorCode() + " " + status.getErrorMessage()); } }; // 调用地点详情接口 searchService.detailSearch(request, resultListener);理解更多详情>> ...

August 18, 2022 · 1 min · jiezi

关于android:华为应用市场APP上架流程

怎么将开发好的App上传到华为利用市场呢,上面给大家解说一下上架流程,供大家参考;    首先进入华为开发者联盟官网https://developer.huawei.com/,注册账号,并进行企业或者集体认证; 而后点击管理中心,点击利用公布,并抉择创立利用,如下图所示:     下一步就是填写利用相干信息,次要包含利用名称和利用分类;    点击确认之后,填写利用的详细信息,包含利用名称、利用介绍、利用一句简介、以及利用图标和截图,最初须要填写利用分类和官网地址;     接下来点击保留进入下一步,进入下一个页面,抉择公布的国家和地区,勾选是否凋谢测试版本;而后点击软件包治理提交apk包;并填写隐衷政策网址和版权阐明;     最初抉择能够抉择上架工夫而后点击提交审核就能够了,提交后3-5个工作日就能够有反馈了; 在上架前,能够当时筹备好材料, 这样在提交时能够一次性都提交完;对于审核被驳回的状况,本人能够先初步定位,如果有不分明的中央,能够及时给官网提工单,能够征询具体的批改措施,这样便于疾速批改并再次公布,能够放慢上架工夫;

August 17, 2022 · 1 min · jiezi

关于android:App切换到后台后如何保持持续定位

为了爱护用户隐衷,大多数利用只会在前台运行时获取用户地位,当利用在后盾运行时,定位性能会被禁止。这就导致APP在后盾或者锁屏时无奈失常记录GPS轨迹,这对打车、共享出行、跑步等须要实时记录用户轨迹的利用影响十分大,甚至影响了利用外围性能的应用体验。那对于这些利用的开发者来说,如何在用户被动受权地位信息后,让利用在后盾运行时长时间放弃继续定位呢? HMS Core定位服务提供后盾继续定位的能力,在获取用户被动受权的状况下可长久记录地位信息,实用于记轨迹录场景。 一、交融定位-后盾定位实现办法利用运行设施为非华为手机应用LocationCallback开启定位之后,当利用切到后盾之后,定位将会很快进行。为了让利用切到后盾之后,定位能力仍旧无效,所以能够应用enableBackgroundLocation办法创立一个前台服务,用以进步利用在后盾的地位更新频率。后盾定位自身不具备定位能力,后盾定位须要和LocationCallback开启的定位一起应用。定位获取的数据须要在 LocationCallback对象中的onLocationResult(LocationResult locationResult) 办法中获取。二、注意事项:反对的设施为非华为手机利用须要取得定位权限,且必须为“始终容许”利用不可被设施中的省电精灵等控电利用解冻,以vivo手机为例:关上i管家-后盾耗电治理-找到利用-把智能控电改成容许后盾高耗电。三、测试Demo时的注意事项:测试时设施最好不要是充电状态,充电状态下利用可能不会被控电。能够通过状态栏是否有 定位图表判断 设施以后是否在进行定位。以vivo手机为例:vivo手机定位开启时状态栏会展现一个定位图标,如果不开启后盾定位的话利用切后盾 定位图标会隐没。开启后盾定位能力之后,利用切后盾定位图标还是存在的。四、实现后盾定位性能集成步骤在AndroidManifest.xml中增加后盾定位服务<service android:name="com.huawei.location.service.BackGroundService" android:foregroundServiceType="location" />(可选)在Android 9及以上版本中,为保障后盾定位权限的失常应用,须要在“AndroidManifest.xml”文件中配置FOREGROUND_SERVICE权限:<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />创立Notification对象public class NotificationUtil { public static final int NOTIFICATION_ID = 1; public static Notification getNotification(Context context) { Notification.Builder builder; Notification notification; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); String channelId = context.getPackageName(); NotificationChannel notificationChannel = new NotificationChannel(channelId, "LOCATION", NotificationManager.IMPORTANCE_LOW); notificationManager.createNotificationChannel(notificationChannel); builder = new Notification.Builder(context, channelId); } else { builder = new Notification.Builder(context); } builder.setSmallIcon(R.drawable.ic_launcher) .setContentTitle("Location SDK") .setContentText("Running in the background ") .setWhen(System.currentTimeMillis()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { notification = builder.build(); } else { notification = builder.getNotification(); } return notification; }}初始化FusedLocationProviderClient对象FusedLocationProviderClient mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);开启后盾定位private void enableBackgroundLocation() { mFusedLocationProviderClient .enableBackgroundLocation(NotificationUtil.NOTIFICATION_ID, NotificationUtil.getNotification(this)) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { LocationLog.i(TAG, "enableBackgroundLocation onSuccess"); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(Exception e) { LocationLog.e(TAG, "enableBackgroundLocation onFailure:" + e.getMessage()); } });}理解更多详情>> ...

August 17, 2022 · 1 min · jiezi

关于android:深入分析FragmentPagerAdapter和FragmentStatePagerAdapter

最近遇到比拟奇怪的bug,TableLayout+ViewPager实现点击顶部tab切换viewpager视图。然而在Viewpager设置dapter时,最开始设置的是FragmentPagerAdapter,会导致tab切换后FragmentPagerAdapter内的视图未刷新(与上一个tab内容反复或展现成空白,展现成空白个别呈现在页面重启后不能实现刷新胜利)。替换成FragmentStatePagerAdapter或者FragmentStateAdapter,便解决了这一问题。这其实是个比拟常见的bug,网络上有很多举荐的解决方案。那么到底FragmentPagerAdapter、FragmentStateAdapter以及FragmentStatePagerAdapter有何具体的区别呢?在这篇文章中我将具体解答。依据类图进行剖析 FragmentPagerAdapter与FragmentPagerStateAdapter区别点:一:二者在状态保留有差别:FragmentPagerAdapter并未实现saveState()、restoreState()public class FragmentPagerAdapter{ // ...... public static final int POSITION_UNCHANGED = -1; public static final int POSITION_NONE = -2; public Parcelable saveState() { return null; } public void restoreState(Parcelable state, ClassLoader loader) { }}而FragmentPagerStateAdapter则实现了saveState()、restoreState()这俩办法: public Parcelable saveState() { Bundle state = null; if (mSavedState.size() > 0) { state = new Bundle(); Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()]; mSavedState.toArray(fss); state.putParcelableArray("states", fss); } for (int i=0; i<mFragments.size(); i++) { Fragment f = mFragments.get(i); if (f != null && f.isAdded()) { if (state == null) { state = new Bundle(); } String key = "f" + i; mFragmentManager.putFragment(state, key, f); } } return state; } @Override public void restoreState(Parcelable state, ClassLoader loader) { if (state != null) { Bundle bundle = (Bundle)state; bundle.setClassLoader(loader); Parcelable[] fss = bundle.getParcelableArray("states"); mSavedState.clear(); mFragments.clear(); if (fss != null) { for (int i=0; i<fss.length; i++) { mSavedState.add((Fragment.SavedState)fss[i]); } } Iterable<String> keys = bundle.keySet(); for (String key: keys) { if (key.startsWith("f")) { int index = Integer.parseInt(key.substring(1)); Fragment f = mFragmentManager.getFragment(bundle, key); if (f != null) { while (mFragments.size() <= index) { mFragments.add(null); } f.setMenuVisibility(false); mFragments.set(index, f); } else { Log.w(TAG, "Bad fragment at key " + key); } } } } }FragmentStatePagerAdapter对Fragment的状态进行了保留 ...

August 16, 2022 · 2 min · jiezi

关于android:如何给玩偶建模并让它跳个舞

大家小时候在玩玩具时必定都空想过这样的场景:设想着本人手上的玩具能动起来,就像《玩具总动员》里的玩具们一样有本人的性情,可能和本人一起游玩。以前我也始终认为玩具总动员只是童话,让玩具领有灵魂,可能动起来的想法只是空想。但现在HMS Core 3D建模服务让这一空想变成了事实。 原理解释 应用HMS Core 3D建模服务骨骼绑定能力就能让玩偶在手机屏幕上动起来,开发者只须要用一般手机拍摄二足人形物体的多张图像,建设动态的3D模型,通过云侧AI主动绑定算法后,主动生成模型的骨骼和蒙皮权重,通过业界支流引擎即可一键驱动。除了预置的动作还能退出本人动捕的个性化动作,让玩偶形象在屏幕上跟着节奏跳舞。 Demo演示 主动骨骼绑定能力开发步骤 在开始开发工作之前,须要先配置AppGallery Connect,同时请确保工程曾经集成HMS Core SDK并且曾经配置Maven仓地址。 应用云侧服务的能力,须要应用“agconnect-services.json”里的api_key值,在利用初始化时通过api_key或者AccessToken来设置利用鉴权信息,AccessToken的优先级较高。通过setAccessToken办法设置AccessToken,在利用启动时初始化设置一次即可,无需屡次设置。 ReconstructApplication.getInstance().setAccessToken("your AccessToken");获取Access Token可参见基于OAuth 2.0凋谢鉴权客户端模式。 通过setApiKey办法设置api_key,在利用启动时初始化设置一次即可,无需屡次设置。 ReconstructApplication.getInstance().setApiKey("your api_key");当在AppGallery Connect上注册利用时,会给您的利用调配api_key。 新建3D物体建模引擎并初始化,新建主动骨骼绑定配置器。// 新建3D物体建模引擎 Modeling3dReconstructEngine modeling3dReconstructEngine = Modeling3dReconstructEngine.getInstance(context); // 新建骨骼绑定蒙皮配置器 Modeling3dReconstructSetting setting = new Modeling3dReconstructSetting.Factory() // 设置工作模式为图片模式 .setReconstructMode(Modeling3dReconstructConstants.ReconstructMode.PICTURE) // 设置工作类型 .setTaskType(Modeling3dReconstructConstants.TaskType.AUTO_RIGGING) .create();新建上传监听器回调,用于解决拍摄的物体图片上传后果private Modeling3dReconstructUploadListener uploadListener = new Modeling3dReconstructUploadListener() { @Override public void onUploadProgress(String taskId, double progress, Object ext) { // 上传进度 } @Override public void onResult(String taskId, Modeling3dReconstructUploadResult result, Object ext) { // 上传胜利解决 } @Override public void onError(String taskId, int errorCode, String message) { // 上传失败解决 } };应用3D物体建模配置器初始化工作,并且给新建的3D物体建模引擎设置上传监听器,上传采集的图片数据。// 应用3D物体建模配置器初始化工作(该接口须要在子线程中调用) Modeling3dReconstructInitResult modeling3dReconstructInitResult = modeling3dReconstructEngine.initTask(setting); String taskId = modeling3dReconstructInitResult.getTaskId(); // 设置上传监听器 modeling3dReconstructEngine.setReconstructUploadListener(uploadListener); // 调用3D建模引擎的上传接口,上传采集的图片数据 modeling3dReconstructEngine.uploadFile(taskId, filePath);查问主动骨骼绑定工作状态// 查问3D物体建模工作状态须要初始化工作解决类 Modeling3dReconstructTaskUtils modeling3dReconstructTaskUtils = Modeling3dReconstructTaskUtils.getInstance(context); // 调用查问接口获取3D物体建模工作状态(该接口须要在子线程中调用) Modeling3dReconstructQueryResult queryResult = modeling3dReconstructTaskUtils.queryTask(taskId); // 获取建模工作状态 int status = queryResult.getStatus();新建下载监听器回调,用于解决主动骨骼绑定模型文件的下载后果private Modeling3dReconstructDownloadListener modeling3dReconstructDownloadListener = new Modeling3dReconstructDownloadListener() { @Override public void onDownloadProgress(String taskId, double progress, Object ext) { // 下载进度 } @Override public void onResult(String taskId, Modeling3dReconstructDownloadResult result, Object ext) { // 下载胜利解决 } @Override public void onError(String taskId, int errorCode, String message) { // 下载失败解决 } };新建的下载配置项并将新建的下载监听器传入新建的3D物体建模引擎,下载骨骼绑定胜利的模型文件// 设置下载配置项 Modeling3dReconstructDownloadConfig downloadConfig = new Modeling3dReconstructDownloadConfig.Factory() // 配置OBJ或glTF格局 .setModelFormat(Modeling3dReconstructConstants.ModelFormat.OBJ) // 配置一般或PBR模式 .setTextureMode(Modeling3dReconstructConstants.TextureMode.PBR) .create(); // 设置下载监听器 modeling3dReconstructEngine.setReconstructDownloadListener(modeling3dReconstructDownloadListener); // 调用3D物体建模引擎的下载接口,传入工作ID,下载地址和下载配置项,下载模型文件 modeling3dReconstructEngine.downloadModelWithConfig(taskId, fileSavePath, downloadConfig);更多利用场景 ...

August 16, 2022 · 1 min · jiezi

关于android:App封装平台源码App封装平台第八区源码

 App封装散发是向最终用户提供应用程序的部署工作流程的最初一步。对于 App封装来说,一旦挪动利用程序开发实现,它就越来越须要负责所有必须进行的部署流动。让事件变得更具挑战性的是,App封装负责散发的挪动应用程序来自外部工程团队和第三方开发人员,这导致了挪动应用程序散发的复杂性。 App封装平台源码及演示:s.appwin.top 常见的利用散发渠道 App封装能够通过多种挪动利用散发渠道向最终用户提供挪动利用。Apple 的App Store和Google Play 是家喻户晓的国外公共利用商店的例子,任何人都能够在其中查看挪动利用。而后国内企业应用程序目录,通常是对立端点治理 (UEM) 解决方案(如BlackBerry UEM 和Microsoft Intune )的一部分,可用于使挪动应用程序可供无限的用户群体(如企业员工)应用。每个挪动应用程序散发渠道对公布应用程序都有独特的要求,因而也面临着独特的挑战。 通过 Apple App Store 散发应用程序 Apple 领有最严格的挪动应用程序散发流程。这种限制性的过程既是益处也是咒骂;益处,因为应用程序通过审查,恶意软件较少,并且应用程序未来呈现兼容性问题的可能性较低;一个咒骂,因为它对于任何想要公布应用程序的人(应用程序开发人员或 DevOps)来说都很麻烦。只管常常将应用程序散发到 Apple App Store,但挪动应用程序开发人员常常会遇到问题。 配置文件充当应用程序测试设施、开发人员帐户、应用程序和 Apple App Store 中的应用程序容器之间的链接。初始签名和任何从新签名都必须应用雷同的配置文件。如果没有正确的配置文件,编码到应用程序中的权力可能不可用。显然,删除应用程序性能不适宜用户体验。 当 App封装的工作是部署应用程序时,它须要获取用于初始签名的配置文件并跟踪它以进行任何后续签名。在公司内跨部门工作时,这可能很不不便,可能会减少部署提早。想想部署由内部供应商构建的应用程序会有多艰难。尽管对于单个应用程序可能不是问题,但对于任何规模正当的挪动应用程序组合,它将迅速成为一个问题。 通过 Google Play 散发应用程序 相比之下,通过 Google Play 公布 Android 应用程序的过程有据可查的 Google 的限度要少得多。有一些技术和法律上的限度和要求,但一般来说,它们并不令人头疼。资源和文档随时可用,形容了公布应用程序所需的步骤。您能够在Play 管理中心帮忙核心找到无关利用可见性和发现问题的许多问题的答案。无论如何,通过此渠道散发挪动应用程序的流程自动化和编码的某些元素只会是无益的。 应用部署工作流对于应用程序散发至关重要 当挪动应用程序组合的规模减少时,一些在散发一两个挪动应用程序时仅仅是不便的问题变成了微小的问题。 例如,思考到 App封装必须通过多个渠道散发应用程序的状况,因为必须反对员工、承包商和参谋。一个企业应用程序目录,比方 BlackBerry UEM,将用于向员工提供挪动应用程序。Google Play 和 Apple App Store 将用于向承包商和参谋提供该应用程序,因为无奈保障这些最终用户将可能拜访公司的 BlackBerry UEM 应用程序目录。 胜利公布挪动应用程序须要进行许多流动。 通常须要进行大量的前期工作,包含组装应用程序在推送到挪动应用程序散发渠道时必须随同的工件(屏幕截图等)。如果一个挪动应用程序须要进入不同地区的多个应用程序商店,那么这些工件必须本地化。因而,工件的数量将相应地扩大。每个利用商店都有一组独特的登录凭据,必须对其进行平安保护和跟踪。 因为性能加强、谬误修复、应用程序中应用的 SDK 的更改等起因,同一挪动应用程序可能须要每年屡次通过挪动应用程序散发渠道推送。任何更改都须要重建应用程序、从新签名和另一个散发推送。将其乘以投资组合中挪动应用程序的数量,如果不以某种精心设计的形式实现,您就会看到随之而来的复杂性和出错的可能性。 手动解决多个利用散发渠道的独特要求和限度是失败的秘诀。只需部署一个应用程序,即便呈现简单状况,挪动应用程序的散发也是可治理的。但随着更宽泛的挪动应用程序组合,散发具备挑战性。对于曾经顾此失彼的App封装团队来说,即便散发三个应用程序也可能难以治理。获取和治理跨公布场合和地区扩大的工件的复杂性、配置文件以及大量应用程序都须要自动化。 开发App封装平台能够提供帮忙 如果一个组织领有宽泛的挪动应用程序组合,其中不同的应用程序进入各种公共和私人应用程序商店,那么应用手动流程跟踪所有内容是凌乱且低效的。编排自动化十分无益:自动化反复解决可能容易出错的死记硬背的散发工作,从而使挪动应用程序部署脱轨;和编排,以确保散发在正确的工夫作为部署工作流的一部分执行,并在须要手动干涉时向部署流程中波及的不同团队收回任何所需的告诉。 本人开发App封装平台平台的编排能够简化散发过程和复杂性,为不相熟各种散发渠道变幻莫测的团队节省时间和资源,包含: 跨平台散发:挪动应用程序散发能够以自动化形式跨平台到多个目的地,显着升高挪动应用程序部署失败的机会。 如何开发App封装平台 将应用程序散发编码为自动化工作流程:实现无缝部署,简化必要但无差别的沉重工作,以便将挪动应用程序提供给用户。 使重复性工作牢靠且无谬误:当您有简单的工作流程时,例如通过多个渠道散发,每个渠道中的应用程序版本略有批改,将工作编码为形象步骤能够使重复性工作牢靠。 简化大型部署:当挪动应用程序散发流动成为更大部署流程的一部分时,从从代码存储库获取挪动应用程序的更新版本到无代码集成,自动化和编排简化了整个流程。 ...

August 15, 2022 · 1 min · jiezi

关于android:Android-自定义View-柱状波形图-wave-view

前言柱状波形图是一种常见的图形。一个个柱子按顺序排列,形成一个波形图。 柱子的高度由输出数据决定。如果输出的是音频的音量,则可失去一个声波图。 在一些音频软件中,咱们也能够左右拖动声波,来扭转音频的播放进度 本文举例的自定View,实现如下性能: 以柱状模式展现数据的大小表明图形以后最两头的数据能够横向拖动进度,进度就是让某个特定的数据居中展现能够扭转左右两边的柱子色彩能够调整柱子的宽度拖动结束后监听以后进度实现首先创立类SoundWaveView继承自View 咱们能够先记录给定的宽高,不便前面找到View的两头点 private int viewWid = 1000; // pxprivate int viewHeight = 100; // px@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); viewWid = w; viewHeight = h; // ..}根本属性例如柱子的色彩,宽度。能够设置个属性来记录,并凋谢进来可由内部来设置。 private float barWidDp = 1.5f;private float barWidPx = 3f;private float barGapPx = barWidPx / 2;private int barCount = 1; // 以后宽度能绘制多少个柱子private final Paint paint = new Paint();private int leftColor = Color.GREEN;private int rightColor = Color.LTGRAY;private int middleLineColor = Color.parseColor("#55000000");设计监听器拖动结束后,能够将以后进度告诉进来。也能够间接把触摸事件传出去。 ...

August 15, 2022 · 6 min · jiezi

关于android:图片系列6不同版本上-Bitmap-内存分配与回收原理对比

请点赞关注,你的反对对我意义重大。 Hi,我是小彭。本文已收录到 GitHub · AndroidFamily 中。这里有 Android 进阶成长常识体系,有气味相投的敌人,关注公众号 [彭旭锐] 带你建设外围竞争力。 前言Bitmap 是 Android 利用的内存占用小户,是最容易造成 OOM 的场景。为此,Google 也在一直尝试优化 Bitmap 的内存调配和回收策略,波及:Java 堆、Native 堆、硬件等多种调配计划,将来会不会有新的计划呢? 深刻了解 Bitmap 的内存模型是无效发展图片内存优化的根底,在这篇文章里,我将深刻 Android 6.0 和 Android 8.0 零碎源码,为你总结出不同零碎版本上的 Bitmap 运行时内存模型,以及 Bitmap 应用的 Native 内存回收兜底策略。 知其然,知其所以然,开干! 学习路线图: 1. 意识 Bitmap 的内存模型1. 不同版本的 Bitmap 内存调配策略先说一下 Bitmap 在内存中的组成部分,在任何零碎版本中都会存在以下 3 个局部: 1、Java Bitmap 对象: 位于 Java 堆,即咱们相熟的 android.graphics.Bitmap.java ;2、Native Bitmap 对象: 位于 Native 堆,以 Bitmap.cpp 为代表,除此之外还包含与 Skia 引擎相干的 SkBitmap、SkBitmapInfo 等一系列对象;3、图片像素数据: 图片解码后失去的像素数据。其中,Java Bitmap 对象和 Native Bitmap 对象是别离存储在 Java 堆和 Native 堆的,毋庸置疑。惟一有操作性的是 3、图片像素数据,不同零碎版本采纳了不同的调配策略,分为 3 个历史期间: ...

August 14, 2022 · 13 min · jiezi

关于android:Android源码目录

浏览Android源码,最重要的是分明每个目录是干什么的。对于源码的浏览,咱们能够拜访http://androidxref.com/来浏览。这个网站更新到18年,上面咱们以网站里最新的Pie - 9.0.0_r3为例子来剖析。1.首先关上网站如下图: 2.目录剖析 Android源码根目录形容Android.bp编译配置文件,是用来代替原来的Android.mk文件的artAndroid Runtime 全新的ART运行环境bionicGoogle开发的零碎C库,以BSD许可模式开源。Android零碎与Linux内核的桥梁bootable启动疏导相干代码bootstrap.bash编译脚本build寄存零碎编译规定及generic等根底开发包配置compatibilityAndroid兼容性打算 Android源代码,Android兼容性定义文档(CDD文档),兼容性测试套件(CTS)cts寄存零碎编译规定及generic等根底开发包配置dalvikdalvik虚拟机,用于解析执行dex文件的虚拟机developers开发者目录device设施相干配置,厂商小米、OPPO、索尼、HTC、本人的产品,就能够定义在这个目录下external开源模组相干文件frameworks应用程序框架,Android系统核心局部,由Java和C++编写hardware次要是硬件形象层的代码 ,hal层代码kernelLinux内核目录libcore外围库相干文件libnativehelper动静库,实现JNI库的根底Makefile编译文件packages利用程序包,应用层位于Android零碎的最上层,开发者开发的应用程序以及零碎内置的应用程序都在应用层pdkplug development kit的缩写,本地开发套件platform_testing平台测试sdkSDK和模拟器system底层文件系统库、利用和组件test测试目录toolchain工具链文件tools工具文件其中比拟重要的目录有package、framework package源码根目录形容apps外围应用程序,零碎自带的appexperimental第三方应用程序inputmethods输入法目录screensavers屏幕爱护services通信服务,拨号appwallpapers墙纸framework源码重要根目录形容av零碎媒体库base利用框架层根底实现代码nativec++代码,OpenGL就在其中

August 12, 2022 · 1 min · jiezi

关于android:图片上的文字模糊难辨怎么才能一键变清晰

图像中的文字内容通常蕴含了很重要的信息,然而因为拍摄限度、分辨率过低、拍摄对象过远等等起因,文字内容可能模糊不清。比方在拍照上传发票时,因为聚焦不准、灯光等问题,导致App无奈自动识别发票内容;一些档案要上传到后盾资料库里时,因为年代久远,有些文字已无奈识别;被保留转发屡次的截图,因为每个利用压缩水平不一样,再发送给敌人或社交平台时变得模糊不清。为了晋升文字分辨率,给用户带来良好的应用体验,华为HMS Core的机器学习服务文字图像超分辨率能力能够帮忙。 1. 业务简介HMS Core机器学习服务文字图像超分辨率服务能够对蕴含文字内容的图片进行3倍放大,同时显著加强图片中文字的清晰度和可辨识度,轻松解决图片中文字分辨率低的问题。 DEMO演示 超分前 超分后 2. 场景介绍文字图像超分辨率服务在生活中有广泛应用。有时候咱们在拍照时,因为距离远、未聚焦等起因,导致拍摄成果不现实,拍照或图像处理App能够集成应用该性能。而对于一些年份比拟长远的书籍或档案上的文字内容日渐含糊不易识别,又须要上传到资料库里的,能够在本身的App里集成,比方图书馆、电子书等App,加强图片中文字的清晰度,晋升文字的可辨认度,让常识永恒留存。 3. 性能特点成果显著:对蕴含文字内容的图片进行3倍放大,常见的jpg压缩或者下采样图像超分成果显著。 疾速:目前该算法基于深度神经网络开发,充分利用华为手机的NPU芯片,对神经网络进行减速,减速比能达到10倍以上。 轻便:利用本API,能够大大节俭算法开发的工夫,节俭算法模型占用的ROM空间,让您的利用更加轻便。 4. 注意事项• 应用文字图像超分变率服务前须要将图片转化为ARGB格局的bitmap,通过该服务解决后输入ARGB格局bitmap。 • 对于常见的jpg压缩或者下采样图像超分成果更显著,对输出图像清晰度较好的图片,成果可能不显著。 • 文字图像超分辨率服务要求输出的图片最大分辨率为800px*800px,输出图片最小尺寸的长边不小于64px。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

August 12, 2022 · 1 min · jiezi

关于android:运动健康服务场景事件订阅让应用推送更懂用户

数据订阅是静止衰弱类利用中很常见的性能,用户订阅静止记录、衰弱记录等数据,当这些数据发生变化时,用户可能即时在App上接管到推送告诉。 例如某位用户最近正在锻炼身体,为本人设定了每天走1万步,每周达成3次的指标;惯例的数据订阅能够做到每天给用户推送当天步数,但用户须要本人进行二次计算能力得悉本人是否实现了本周指标。 而场景事件订阅能够补救这个毛病。场景事件订阅不仅仅是针对某一种数据类型,而是并重由一种或者多种数据类型组合起来的场景。还是以下面这个情景为例,一周内有任意3天走到1万步就是一个场景,若用户达成了场景指标,才会收到利用的推送揭示。 华为静止衰弱服务(Health Kit)不仅反对数据事件订阅,新版本还减少了场景事件订阅能力,让静止衰弱数据订阅更懂用户。那开发者该如何实现该能力呢?以下是具体的集成步骤。 集成办法一、注册成为订阅者在联盟卡片申请Health Kit服务时,抉择曾经创立的产品,勾选注册订阅告诉能力。可抉择HTTP订阅形式,填写回调告诉地址,并通过测试连通性来查看回调地址是否连通。目前只反对企业开发者在Healthkit卡片中开启订阅性能。 如果你的应用场景满足如下条件,也能够抉择端侧订阅形式,填写利用包名与Action: 应用端侧订阅形式订阅事件类型是场景指标事件应用apk与apk间信息告诉具体筹备步骤可参考扩大能力服务开发指南。 二、注册订阅记录HTTP申请,请参见新增/更新订阅记录接口 POSThttps://health-api.cloud.huawei.com/healthkit/v1/subscriptions申请示例: POSThttps://health-api.cloud.huawei.com/healthkit/v1/subscriptions申请体: POSThttps://health-api.cloud.huawei.com/healthkit/v1/subscriptionsContent-Type: application/jsonAuthorization: Bearer ***x-client-id: ***x-version: ***x-caller-trace-id: ***{ "subscriberId": "08666998-78f6-46b9-8620-faa06cdbac2b", "eventTypes": [ { "type": "SCENARIO_GOAL_EVENT", "subType": "ACHIEVE", "eventType": "SCENARIO_GOAL_EVENT$ACHIEVE", "goalInfo": { "createTime": 1654660859105, "startDay": 20220608, // 指标开始计算日期,留神需晚于指标创立日期 "recurrence": { "unit": 1, // 周期单位:日 "count": 30, // 整个周期30天 "expectedAchievedCount": 28 }, "goals": [ { "goalType": 1, "metricGoal": { "value": 10000, // 设置达标值10000步 "fieldName": "steps", "dataType": "com.huawei.continuous.steps.total" } } ] } } ]}三、接管达标事件音讯告诉HTTP申请,请参见订阅事件告诉接口 ...

August 11, 2022 · 1 min · jiezi

关于android:产品说明丨Android端使用MobPush快速集成方法

开发工具: Android Studio 集成形式: Gradle在线集成 安卓版本反对: minSdkVersion 19 集成筹备注册账号应用PushSDK之前,须要先在MobTech官网注册开发者账号,并获取MobTech提供的AppKey和AppSecret,详情能够点击查看注册流程 MobPush后盾配置注册MobTech账号后,须要在MobTech后盾进行相干信息的配置,详情能够点击查看具体配置信息 MobPush流程图 增加配置在我的项目Gradle文件中注册MobSDK buildscript { repositories { // 增加MobSDK Maven地址 maven { url "https://mvn.mob.com/android" } } dependencies { // 注册MobSDK classpath "com.mob.sdk:MobSDK:2018.0319.1724" }}allprojects { repositories { // 增加MobSDK Maven地址 maven { url "https://mvn.mob.com/android" }}在我的项目App Module的Gradle文件中增加插件和扩大 // 调用MobTech SDKapply plugin: 'com.mob.sdk'MobSDK { appKey "替换为MobTech官网申请的appkey" appSecret "替换为MobTech官网申请的appkey对应的appSecret" MobPush {}}在gradle.properties中增加代码 MobSDK.spEdition=FP回传用户隐衷受权后果(submitPolicyGrantResult)为保障您的App在集成MobSDK之后可能满足工信部相干合规要求,您应确保App装置首次冷启动且获得用户浏览您《隐衷政策》受权之后,调用MobSDK.submitPolicyGrantResult回传隐衷协定受权后果。 反之,如果用户不批准您App《隐衷政策》受权,则不能调用MobSDK.submitPolicyGrantResult回传隐衷协定受权后果。请参考链接合规指南 示例代码 注: 调用地位开发者能够本人指定,只需在应用SDK性能之前调用即可,强烈建议开发者在终端用户点击利用隐衷协定弹窗批准按钮后调用。

August 10, 2022 · 1 min · jiezi

关于android:突破次元壁垒让身边的玩偶手办在屏幕上动起来

因为青睐,人们会将二次元形象制作成玩偶手办,然而没有生命气味的寒冷模型并不能满足人们互动性的情感需要。如何能让带有情感寄托的玩偶手办更具表现力和感染力呢? 近日,HMS Core 3D建模服务上线主动骨骼绑定能力,能够让已建成模型的二足人形物体依据自定义动作流动起来,甚至与用户产生互动,不再只是寒冷生硬的玩偶手办。 那么,通过主动骨骼绑定能力动起来的3D模型,能够用来干什么呢? 比方,应用音视频编辑能力,能够将小朋友喜爱的玩偶建成3D模型,并加上舞蹈动作、配音和儿歌故事,剪辑成较为残缺的儿童教学视频,帮忙孩子更快更好的接管常识; 又比方,联合3D Engine的动作制作能力,通过实时骨骼动画、面部表情驱动、全身IK、多重动画状态机交融等性能,可实现晦涩的3D动画成果,再加上3D Engine的高清渲染与视觉特效、智能寻路导航等性能,即可制作一款成熟的动画游戏; 再比方,借助AR Engine的静止跟踪、人体和人脸跟踪、环境跟踪等AR能力,能够在镜头下将3D模型置入实在的场景中,并与用户产生互动。该场景可利用于AR游戏畛域,实现游戏中自定义3D模型及模型动作的性能,让AR互动游戏更具趣味性。 除此之外,咱们还能够冲破设想,在建模过程中将生存中的瓶瓶罐罐、随用物件加上两条“腿”,让主动骨骼绑定能力不再局限于特定模型类别,万物皆可流动起来,真正实现“万物复苏”的乏味现象。 实现原理主动骨骼绑定服务面向的是有3D游戏、3D动画制作等需要的开发者,通过输出一个二足人形物体的动态3D模型,即可基于AI算法进行肢体绑定,并主动生成模型的骨骼和蒙皮权重,实现主动骨骼绑定,而后通过扭转骨骼的朝向和地位,动静驱动模型实现行走、跳跃、跳舞等自定义动作,以此赋予3D模型静止的能力。 能力劣势1、 无需人工干预,即可实现一键绑定蒙皮。骨骼绑定分为手动绑定和主动绑定,目前少数高精度的主动骨骼绑定办法,除了要求模型处于规范姿势外,还须要手动搁置七八个关键点才可绑定。而华为的主动骨骼绑定能力基于AI智能算法,只须要让模型处于一个大抵正确的地位,甚至都不要求模型相对的直立、朝前,即可对模型实现准确的绑定,无需手动搁置关键点。 2、 基于海量数据,进步AI绑定算法的准确性和泛化性。那么,华为主动骨骼绑定能力是如何进行3D模型数据制作,确保AI绑定算法准确性的呢?不同于耗时耗力的传统3D模型数据制作方法,华为主动骨骼绑定能力的3D模型数据制作仅须要用一般手机拍摄采集物体图像,通过华为自研算法自动化生成3D角色数据。在针对大规模生成的数十万3D模型绑定数据进行算法训练时,只须要在大量的实在数据上进行微调,即可失去高准确性、高泛化性的AI模型。 输出模型束缚思考到3D世界模型的多样化,为了保障主动骨骼绑定能力算法的精准性,咱们对绑定算法的输出模型作出以下倡议: 起源:应用双足人形手办(不含手持物体)、毛绒玩具的照片扫描建模; 外观:从视觉上看,网格无拆散,四肢与身材无粘连,无大块的附属物,尽量双腿站立,双臂张开; 姿势:整体姿势为z轴朝前,y轴朝上,各关节可有不超过15°的扰动,不对对称性作要求; Mesh:Mesh为三角面或四边面,顶点数量不应超过80k,模型整体没有大规模面片缺失; 其余:身材和四肢比例合乎大部分玩具格调,肢体不应过细、过短(手臂和腿宽度比例不能小于模型最长边的8%),模型姿势整体竖直朝前。 华为HMS Core 3D建模服务主动骨骼绑定能力,通过智能化技术牵引,大大降低了3D模型动画的制作门槛,动画制作不再是须要简单设施的高难度的技术能力,即使非专业人士应用一般手机也能轻松实现动画制作,实现日常生活中更多的创意作品制作。 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

August 10, 2022 · 1 min · jiezi

关于android:Android中的Drawable二

PS:本文系转载文章,浏览原文可读性会更好,文章开端有原文链接 目录1、LayerDrawable2、StateListDrawable3、LevelListDrawable1、LayerDrawable本篇文章是基于Android中的Drawable(一)这篇文章来持续写的,LayerDrawable 对应的 xml 文件的标签是 layer-list,它是一种层次化的 Drawable 汇合,通过将不同的 Drawable 搁置在不同的层下面从而达到一种叠加后的成果,咱们先写一个 demo,而后再对 layer-list 标签外面的属性或者子标签的属性进行阐明。(1)在 drawable 文件夹下创立一个 my_layer_list.xml 文件;<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:shape="rectangle"> <solid android:color="#0000ff" /> </shape> </item> <item android:bottom="25dp" android:left="25dp" android:right="25dp" android:top="25dp"> <shape android:shape="rectangle"> <solid android:color="#00ff00" /> </shape> <color android:color="#FF0000"/> </item> <item android:bottom="50dp" android:left="50dp" android:right="50dp" android:top="50dp"> <shape android:shape="rectangle"> <solid android:color="#ff0000" /> </shape> </item></layer-list>(2)Activity 的布局文件 activity_main.xml ;<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ImageView android:layout_width="500px" android:background="@drawable/my_layer_list" android:layout_height="500px" /></RelativeLayout>运行后果如下所示;看咱们的 demo,my_layer_list.xml 文件外面有一个 layer-list 标签,layer-list 标签上面会有 item 标签,一个 item 标签其实就是一个 Drawable;layer-list 是有档次的概念,前面的 item 会笼罩后面的 item,通过应用多个 item 能够实现层层叠加的成果。item 标签的属性也挺多的,咱们列举一些咱们开发中罕用到的吧;1)android:top  : 绝对于 View 的顶部外部偏移量。2)android:bottom  :   绝对于 View 的底部外部偏移量。3)android:left  :  绝对于 View 的右边外部偏移量。4)android:right  :   绝对于 View 的左边外部偏移量。5)android:drawable  :  援用一个已有的 Drawable。2、StateListDrawableStateListDrawable 在 xml 布局文件中对应的是 selector 标签,它是示意 Drawable 汇合,每个 Drawable 都对应着 View 的一种状态,零碎会依据 View 的状态来抉择适合的 Drawable,StateListDrawable次要用于设置可单击的View的背景。为了更好的了解,咱们先写一个 demo;(1)在 drawable 文件夹下新建一个 my_selector.xml 文件;<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/image2" android:state_pressed="true" /> <item android:drawable="@drawable/image" /></selector>(2)在 Activity 的布局文件 activity_main.xml 援用 my_selector.xml 文件;<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:layout_width="match_parent" android:background="@drawable/my_selector" android:text="请点击这个按钮" android:onClick="onClick" android:layout_height="300px" /></RelativeLayout>(3)在名叫 MainActivity 的 Activity 上做点击事件处理;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void onClick(View v) { }}程序一开始运行的后果如下所示;点击 “请点击这个按钮” 这个按钮后的效果图如下所示;从下面的 demo 咱们就明确了,如果咱们不点击 “请点击这个按钮” 这个按钮,那么就默认选用 image 来做这个按钮的背景图片对不对?如果咱们点击了这个按钮,那么就用 image2 做按钮的背景图片对不对,到这里咱们也明确了 selector 标签下的子标签 item 也是一种 Drawable。2、1) selector 标签的属性android:constantSize  :  这里示意的是 StateListDrawable的固有大小是否不随着其状态的扭转而扭转的,它有2个值,一个是 true,一个是 false,默认值为false;true 示意 StateListDrawable 的固有大小放弃不变,这时它的固有大小是外部所有 Drawable 的固有大小的最大值,false则会随着状态的扭转而扭转。android:dither  : 是否开启抖动成果,在Android中的Drawable(一)这篇文章也有讲到过。android:variablePadding  :StateListDrawable 的 padding 示意是否随着其状态的扭转而扭转,true 示意会随着状态的扭转而扭转,false 示意 StateListDrawable 的 padding 是外部所有Drawable的 padding的最大值。2、2)selector 标签的子标签 item 的属性android:drawable  :  示意一个已有 Drawable 的资源 id。android:state_pressed  :  示意按下状态,比方 View 被按下后仍没有松开时的状态。android:state_focused  : 示意 View 曾经获取了焦点。android:state_selected  :  示意抉择了 View 。android:state_checked  :  选中了 View 。android:state_enabled  :  View 处于可用状态,也就是能够点击的状态。3、LevelListDrawable LevelListDrawable 在 xml 文件中对应的标签是 level-list,它同样示意一个 Drawable 汇合,汇合中的每个 Drawable 都有一个等级的概念,依据不同的等级,LevelListDrawable 会切换为对应的 Drawable。好了,为了不便好了解,同样我也先写一个 demo 演示一下;(1)在 drawable 文件夹下新建一个 my_level_list.xml 文件;<?xml version="1.0" encoding="utf-8"?><level-list xmlns:android="http://schemas.android.com/apk/res/android" > <!-- 1到 5显示这个图片--> <item android:drawable="@drawable/img_1" android:minLevel="1" android:maxLevel="5"></item> <!-- 6到 10显示这个图片--> <item android:drawable="@drawable/img_2" android:minLevel="6" android:maxLevel="10"></item> <!-- 11到 15显示这个图片--> <item android:drawable="@drawable/img_3" android:minLevel="11" android:maxLevel="15"></item> <!-- 16到20显示这个图片--> <item android:drawable="@drawable/img_4" android:minLevel="16" android:maxLevel="20"></item></level-list>(2)在 Activity 的 xml 布局文件 activity_main.xml 加上 my_level_list.xml 的援用;<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ImageView android:id="@+id/iv" android:layout_width="match_parent" android:src="@drawable/my_level_list" android:layout_height="500px" /> <EditText android:id="@+id/et" android:layout_below="@id/iv" android:layout_width="match_parent" android:hint="请输出1-20之间的一个数字" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:text="确认" android:onClick="onClick" android:layout_below="@id/et" android:layout_height="wrap_content" /></RelativeLayout>(3)Activity 的子类 MainActivity对 my_level_list.xml 文件进行解决;public class MainActivity extends AppCompatActivity { ImageView mIv; EditText mEt; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mIv = findViewById(R.id.iv); mEt = findViewById(R.id.et); } public void onClick(View v) { int iLevel = 0; String level = mEt.getText().toString(); LevelListDrawable levelListDrawable = (LevelListDrawable) mIv.getDrawable(); try { iLevel = Integer.valueOf(level); } catch (Exception e) { iLevel = 0; } levelListDrawable.setLevel(iLevel); }}咱们先不急着运行程序,咱们先看 img_3 的图片长什么样子(如下所示);程序一开始运行的时候如下所示;在文本框输出13,而后点击 “确认” 按钮,显示成果如下所示;看下面的 my_level_list.xml 文件,当它的最小等级为10,最大等级为15时,咱们输出13就会显示img_3 的图片;如果咱们在文本框输出4,那么就会显示img_1 这张图片,因为援用img_1 的 Drawable 的最小等级是1,最大等级是5,而输出的4刚好在1-5之间。在 my_level_list.xml 文件中,下面的语法中,每个 item 示意一个 Drawable,并且有对应的等级范畴,由 android:minLevel 和 android:maxLevel 属性来指定,在最小值和最大值之间的等级会对应此 item 中的 Drawable;Drawable 的等级是有范畴的,它的等级范畴是 0-10000,默认值是0也是最小等级,最大等级是10000;如果将 View 作为背景时,能够通过 Drawable 的 setLevel 办法来设置不同的等级从而切换具体的 Drawable 。 ...

August 10, 2022 · 2 min · jiezi

关于android:程序员的专属浪漫用3D-Engine-5分钟实现烟花绽放效果

谁说程序员不懂浪漫? 作为程序员,用本人的代码本事手搓一个技术感十足的惊喜,我感觉,这是不亚于车马慢时代手写信的古典主义浪漫。 那么,应该怎么创作出具备自我身份属性的浪漫惊喜呢? 玩法很多,明天给大家介绍一个不出错的技术控浪漫实操形式——烟花粒子动画,在虚拟空间为对方造一个漫天烟花,平行时空的浪漫,多酷。 必须的,烟花粒子动画成果除了炫浪漫,还有多种切实的利用场景,比方,游戏利用中,玩家失利后的页面出现、春节等特定节假日的游戏内气氛打造等。 看个示例: 从粒子动画走向更多精彩 烟花粒子动画是搭载HMS Core 3D Engine实现的视觉效果,借助3D Engine,还能开启虚构视界的更多精彩可能。3D Engine为开发者提供高性能、高画质、高扩展性的实时3D引擎,以及便捷高效的可视化开发工具,帮忙开发者制作高品质的3D利用。 如果你是游戏开发或者对游戏开发感兴趣,那么你用3D Engine能耍得不只是浪漫。 1、高清渲染与视觉特效,高度还原真切光影成果; 2、多线程PBR渲染,实现高性能实时3D渲染成果; 3、CPU/GPU粒子渲染,模仿爆炸、火焰、雨雪等视觉特效; 4、3D角色及晦涩动画轻松造,反对实时骨骼动画、表情动画、全身IK、动画重定向、多重动画状态机交融; 5、提供主动导航网格生成,多指标的门路布局,NPC智能寻路及智能避障性能; 6、3D Studio提供便捷开发工具,反对场景编辑、材质编辑、动画编辑、地形编辑、脚本编辑等外围性能 总之,3D Engine在手,品质3D游戏局面轻松有,不服来试! 实操指南——用3D Engine实现粒子动画烟花成果 创立关卡1、您须要创立一个新的关卡:在引擎首页菜单栏中,抉择“文件 > 新建关卡”。 2、输出Level名称,比方“Fireworks”后,点击“确认”创立胜利。实现后您将进入到玄天引擎的Level界面。 环境搭建1、在场景烟花成果之前,咱们须要适当调整关卡中的环境,首先去除咱们用不到的实体:在引擎首页“实体纲要”窗口中的默认环境找到着色球和高空网格实体,鼠标右键点击删除。 2、咱们须要模仿一个较暗的环境:选中“实体纲要”窗口默认环境组中的天空,在引擎首页右侧的“组件属性”窗口中找到高动静范畴天空盒组件,并调整曝光度属性至-3.2。 3、选中“实体纲要”窗口默认环境组中的太阳,在引擎首页右侧的“组件属性”窗口中找到定向光源组件,并鼠标右击该组件,点击“禁用组件”。 4、在“实体纲要”窗口中鼠标右击抉择“创立实体”。 5、在“实体纲要”窗口中选中新创建的实体,在组件属性中重命名为“Bloom”,并增加一个“光晕”组件和“后处理盒”组件来增强烟花粒子的光效。 6、设置光晕组件的参数如下图。 实现以上步骤后你将失去以下成果 材质编辑1、接下来咱们须要为烟花粒子创立一些光效材质,首先在引擎首页的全局菜单栏中点击“工具 > 材质编辑器”关上材质编辑器。 2、在材质编辑器的菜单栏中点击“文件 > 新建”,创立一个新的材质文件。 3、在弹出的窗口中抉择材质类型为“ParticleMesh”,并在工程目录中的Assets文件夹中新建一个“Material”文件夹,将材质放弃到此文件夹中,重命名为“Particle”。 4、材质编辑器的“材质属性”窗口中展现以后材质类型及可输出参数配置,您能够在此批改其相应的参数设置,参数设置如下图。 ·根底色彩:应用根底色彩中的色彩,能够在输出栏中间接输出RGB值,也能够点击色彩方块关上“抉择色彩”窗口调整色彩。 ·自发光:应用自发光属性,须要先关上“开启”开关。色彩应用形式与根底色彩属性相似,强度决定了自发光的强度。 5、为了丰盛咱们的粒子光效,咱们须要反复2~4步骤,从新创立两个不同色彩的光效材质,并命名为“Particle_02”和“Particle_03”,参数设置如下图。 粒子编辑1、返回引擎首页,在全局菜单栏中点击“工具 > 粒子编辑器”关上粒子编辑器。 ...

August 9, 2022 · 1 min · jiezi

关于android:华为分析联运活动助您提升游戏总体付费

ARPU如何晋升?付费率如何晋升?流动ROI如何晋升?这些都是游戏经营人员较常遇到的难题。华为剖析与联运流动能够帮忙经营晋升这些用户付费指标,通过对玩家打标签和用户画像,对目标群体的进行精准推送,实现对特定用户进行特定“刺激”,让他们进步游戏关上率,从而进步游戏的总体付费。 华为剖析&联运流动晋升付费计划在华为剖析中的人群洞察里通过用户分群性能,圈选游戏中付费志愿较高的人群,通过利用市场推送性能给这些人群发送优惠券、礼包,促使该人群产生付费,从而晋升整体付费与ARPU值。 胜利案例某搁置类手游,月活用户已达40万,但总体付费率较行业偏低,经营人员尝试通过利用内的福利优惠吸引用户付费,然而几场流动下来付费率有所晋升,然而ROI却降落重大。 经营人员尝试应用华为剖析&联运流动来晋升用户付费。首先在华为剖析圈选出“游戏付费志愿较高”的标签人群;接着在华为利用市场创立优惠券礼包,并通过利用市场给用户推送优惠券信息;标签人群收到利用市场优惠券揭示,吸引用户关上游戏应用优惠券产生付费。最终本次经营流动帮忙该手游的大盘人群付费率晋升2.99%,大盘人群ARPU值晋升17.11% 应用华为剖析与联运流动付费晋升性能的操作步骤,可参考应用领导。 以上是联合HMS Core剖析服务联合联运流动晋升游戏总体付费的简略介绍,欲了解其余精益经营场景,使可通过拜访官网理解更多。即刻集成,晋升手游ARPU值! 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

August 5, 2022 · 1 min · jiezi

关于android:百度APP-Android包体积优化实践三资源优化

01 前言百度APP Android包体积优化实际系列文章的前两篇别离介绍了体积优化的整体计划和Dex行号优化的具体内容。Dex行号优化基于尽可能减少Dex文件中的DebugInfo 体积来优化包体积。资源优化则通过优化APK中的资源项来优化包体积,本文咱们会介绍百度APP 在资源优化上的实际。首先介绍 APK 中资源局部的构造,而后比照剖析现存的资源优化工具,介绍百度App自定义优化开发计划,最初还会介绍一些带来其余收益的资源优化。 百度APP Android包体积优化实际系列文章回顾: 百度APP Android包体积优化实际(一)总览 百度APP Android包体积优化实际(二)Dex行号优化 02 APK资源项如下图所示,能够看到APK 中有三局部内容与资源相干:res/ 目录、resources.arsc、assets/ 目录。除了assets/ 目录外,其余两个资源项初始设计目标是为了实现更不便的机型适配和语言适配等,进步兼容性,因而存在一些优化的空间。 APK 构造 丨**2.1 res/res/ 资源通常包含用到的各种动态内容,如位图,色彩,布局定义,用户界面字符串,动画等等,这些资源个别搁置在我的项目的 res/ 下特定子目录中。 对应资源目录名称格局如下: <resources\_type\_name>-<qualifier\_1>-<qualifier\_2> resources\_type\_name 即资源类型,必须齐全匹配,否则不会被编译链接到APK中。Qualifier 即配置标识,可增加多个 qualifier 以匹配到最适宜的资源,是多机型适配的根底。qualifier 的内容及程序必须齐全匹配,否则会编译失败,提醒Invalid resource directory name。 除了res/raw/下可放任意类型资源外,其余目录下资源文件格式均受严格控制。如果搁置了范畴外的类型文件会编译失败,提醒 The file name must end with <指定的扩展名>,由此可见文件后缀名是编译校验的一部分。后缀名校验通过后,AAPT2还会对资源文件内容进行校验,理论格局与后缀名不匹配的话也会报错。 丨**2.2 resources.arscresource.arsc文件是Apk打包过程中由 AAPT2 依据 res/ 目录下资源生成的一个资源索引文件,负责将代码中的资源援用映射到 res/ 下最合适的资源文件或资源内容。 下图中能够看出 arsc 中的重点信息包含:包名、资源类型、资源ID、资源名、资源配置。 arsc次要信息 通过浏览在arsc中寻找对应资源的源码,能够看到在 LoadedPackage::GetEntryOffset 办法中,有两种资源 entry 偏移量定位形式,其中 SPARSE 格局在Android O+ 引入。咱们以下图为例,假如 0x7f020010 和 0x7f020011 两个 ID 对应的entry为空,则两种形式的布局如下图所示,能够发现 SPARSE 格局在体积上会有优化,但查找资源的工夫复杂度会从O(1)回升到O(logn)。 ...

August 4, 2022 · 3 min · jiezi

关于android:Android逆向rpc调用某安App的XAppToken签名函数

1.指标在学习的过程中,会遇到有些算法比拟麻烦,没有方法间接还原。那咱们就另辟蹊径,不去剖析具体的算法实现。间接应用rpc的形式调用算法函数,本文章以某安App的X-App-Token签名函数为例。 2.操作环境 mac零碎frida-dexdump:导出加固后dex文件Charles:抓取http接口已Root安卓机:脱壳Python3.8:实现rpc性能Jadx:导出dex文件为源码Android Studio:动态剖析3.流程寻找切入点通过Charles抓包获取到关键词为X-App-Token,这也就是咱们的切入点:动态剖析应用查壳工具发现该apk应用的是360加固,启动App后,应用frida-dexdump的frida-dexdump -FU命令导出dex文件:因为dex文件较多,不不便查问,应用jadx把多个dex文件导出为源码: import osfor file in os.listdir(os.curdir):     if file.find(".dex") > 0:        sh = 'jadx -j 1 -r -d ./ ./' + file         print(sh)        os.system(sh)将以上的python脚本放到dex同级目录,切换到dex目录,并执行以上脚本,执行实现后会生成sources文件夹,应用Android Studio关上该文件夹,全局搜寻X-App-Token:找到要害函数: private final String[] m13135() {        String str;        Locale locale = Locale.getDefault();        String valueOf = String.valueOf(Build.VERSION.SDK_INT);        String str2 = locale.getLanguage() + '-' + ((Object) locale.getCountry());        byte[] bytes = (this.f16167.m13205() + "; ; ; " + this.f16167.m13207() + "; " + ((Object) Build.MANUFACTURER) + "; " + ((Object) Build.BRAND) + "; " + ((Object) Build.MODEL) + "; " + ((Object) Build.DISPLAY) + "; " + ((Object) C4765.m13174().m12851())).getBytes(Charsets.UTF_8);        Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)");        String encodeToString = Base64.encodeToString(bytes, 0);        Intrinsics.checkNotNullExpressionValue(encodeToString, "encodeToString(device.to…eArray(), Base64.DEFAULT)");        String sb = new StringBuilder(encodeToString).reverse().toString();        Intrinsics.checkNotNullExpressionValue(sb, "StringBuilder(device).reverse().toString()");        String replace = new Regex("\\r\\n|\\r|\\n|=").replace(sb, BuildConfig.FLAVOR);        String as = AuthUtils.getAS(this.f16166, replace);        if (C4765.m13166().m13307()) {            str = "1";       } else {            str = C4765.m13166().m13300() ? "2" : "0";       }        Intrinsics.checkNotNullExpressionValue(as, "appToken");        String r1 = this.f16167.m13203();        Intrinsics.checkNotNullExpressionValue(r1, "appMetadata.channel");        return new String[]{"User-Agent", this.f16170, "X-Requested-With", "XMLHttpRequest", "X-Sdk-Int", valueOf, "X-Sdk-Locale", str2, "X-App-Id", "com.coolapk.market", "X-App-Token", as, "X-App-Version", this.f16168, "X-App-Code", String.valueOf(this.f16169), "X-Api-Version", "12", "X-App-Device", replace, "X-Dark-Mode", str, "X-App-Channel", r1, "X-App-Mode", this.f16167.m13197().toString(), "X-App-Supported", String.valueOf(this.f16167.m13199())};   }删除无关代码后: ...

August 4, 2022 · 3 min · jiezi

关于android:接入华为游戏防沉迷点击防沉迷弹窗后游戏闪退

问题形容咱们游戏接入华为游戏服务sdk 6.1.0.301版本后,应用华为帐号(实名信息为未成年人)测试,登录后呈现SDK的防沉迷提醒弹框,点击“晓得了”,游戏闪退,报错如下: java.lang.NullPointerException Attempt to invoke virtual method &apos;android.content.res.Resources android.content.Context.getResources()&apos; on a null object reference com.huawei.hms.utils.ResourceLoaderUtil.getStringId(ResourceLoaderUtil.java:1) com.huawei.hms.jos.games.player.AntiAddictionService$c.run(Unknown Source:33) android.os.Handler.handleCallback(Handler.java:900) android.os.Handler.dispatchMessage(Handler.java:103) android.os.Looper.loop(Looper.java:219) android.app.ActivityThread.main(ActivityThread.java:8668) java.lang.reflect.Method.invoke(Native Method)问题剖析看报错类是华为sdk外部类谬误,不分明报错起因,分割华为技术反对申请帮忙看下问题(可提单分割),技术回复是上下文Context为null,应该是没有设置上下文,初始化接口调用之前须要设置上下文Context,代码在文档和demo中都有示例,让我认真查看代码,附参考文档: ResourceLoaderUtil.setmContext(this); 问题解决依照技术回复增加代码后问题解决。咱们是间接从游戏sdk旧版本升级到新版原本的,只批改了init接口调用,没有依照官网文档从头接入才呈现的问题,当前接入sdk肯定要从头查看。

August 4, 2022 · 1 min · jiezi

关于android:华为游戏服务SDK获取玩家高清头像的URI地址为null

问题形容近期公司新业务须要接入华为渠道游戏服务SDK,在测试游戏登录性能时,发现登录胜利后调用接口getCurrentPlayer返回Player实例,接着调用getHiResImageUri()接口,依照官网文档上介绍,可获取到玩家高清头像的URI地址,但理论测试获取到的后果为空,与文档不统一。 华为游戏登录文档: 如下截图是接口调试日志: 问题起因和解决通过仔细阅读文档后我发现,如果getHiResImageUri()办法获取不到玩家头像,倡议从登录胜利后返回的AuthHuaweiId或AuthAccount获取。 依照上述思路,我进一步做了测试。 上面是代码截图和运行后果: 测试后果:能够胜利获取到头像地址。 问题失去解决。

August 4, 2022 · 1 min · jiezi

关于android:手搓一个七夕限定用3D-Engine-5分钟实现烟花绽放效果

七夕来咯!又到了给重要的人送惊喜的时刻。 往年,除了将情意融入花和礼物,作为程序员,用本人的代码本事手搓一个技术感十足“七夕限定”惊喜,我感觉,这是不亚于车马慢时代手写信的古典主义浪漫。 那么,应该怎么创作出具备自我身份属性的浪漫七夕惊喜呢? 玩法很多,明天给大家介绍一个不出错的技术控浪漫实操形式——烟花粒子动画,在虚拟空间为对方造一个漫天烟花,平行时空的浪漫,多酷。 必须的,烟花粒子动画成果除了炫浪漫,还有多种切实的利用场景,比方,游戏利用中,玩家失利后的页面出现、春节等特定节假日的游戏内气氛打造等。 看个示例: 从粒子动画走向更多精彩 烟花粒子动画是搭载HMS Core 3D Engine实现的视觉效果,借助3D Engine,还能开启虚构视界的更多精彩可能。3D Engine为开发者提供高性能、高画质、高扩展性的实时3D引擎,以及便捷高效的可视化开发工具,帮忙开发者制作高品质的3D利用。 如果你是游戏开发或者对游戏开发感兴趣,那么你用3D Engine能耍得不只是浪漫。 1、高清渲染与视觉特效,高度还原真切光影成果; 2、多线程PBR渲染,实现高性能实时3D渲染成果; 3、CPU/GPU粒子渲染,模仿爆炸、火焰、雨雪等视觉特效; 4、3D角色及晦涩动画轻松造,反对实时骨骼动画、表情动画、全身IK、动画重定向、多重动画状态机交融; 5、提供主动导航网格生成,多指标的门路布局,NPC智能寻路及智能避障性能; 6、3D Studio提供便捷开发工具,反对场景编辑、材质编辑、动画编辑、地形编辑、脚本编辑等外围性能 总之,3D Engine在手,品质3D游戏局面轻松有,不服来试! 实操指南——用3D Engine实现粒子动画烟花成果 创立关卡1、您须要创立一个新的关卡:在引擎首页菜单栏中,抉择“文件 > 新建关卡”。 2、输出Level名称,比方“Fireworks”后,点击“确认”创立胜利。实现后您将进入到玄天引擎的Level界面。 环境搭建1、在场景烟花成果之前,咱们须要适当调整关卡中的环境,首先去除咱们用不到的实体:在引擎首页“实体纲要”窗口中的默认环境找到着色球和高空网格实体,鼠标右键点击删除。 2、咱们须要模仿一个较暗的环境:选中“实体纲要”窗口默认环境组中的天空,在引擎首页右侧的“组件属性”窗口中找到高动静范畴天空盒组件,并调整曝光度属性至-3.2。 3、选中“实体纲要”窗口默认环境组中的太阳,在引擎首页右侧的“组件属性”窗口中找到定向光源组件,并鼠标右击该组件,点击“禁用组件”。 4、在“实体纲要”窗口中鼠标右击抉择“创立实体”。 5、在“实体纲要”窗口中选中新创建的实体,在组件属性中重命名为“Bloom”,并增加一个“光晕”组件和“后处理盒”组件来增强烟花粒子的光效。 6、设置光晕组件的参数如下图。 实现以上步骤后你将失去以下成果 材质编辑1、接下来咱们须要为烟花粒子创立一些光效材质,首先在引擎首页的全局菜单栏中点击“工具 > 材质编辑器”关上材质编辑器。 2、在材质编辑器的菜单栏中点击“文件 > 新建”,创立一个新的材质文件。 3、在弹出的窗口中抉择材质类型为“ParticleMesh”,并在工程目录中的Assets文件夹中新建一个“Material”文件夹,将材质放弃到此文件夹中,重命名为“Particle”。 4、材质编辑器的“材质属性”窗口中展现以后材质类型及可输出参数配置,您能够在此批改其相应的参数设置,参数设置如下图。 ·根底色彩:应用根底色彩中的色彩,能够在输出栏中间接输出RGB值,也能够点击色彩方块关上“抉择色彩”窗口调整色彩。 ·自发光:应用自发光属性,须要先关上“开启”开关。色彩应用形式与根底色彩属性相似,强度决定了自发光的强度。 5、为了丰盛咱们的粒子光效,咱们须要反复2~4步骤,从新创立两个不同色彩的光效材质,并命名为“Particle_02”和“Particle_03”,参数设置如下图。 粒子编辑1、返回引擎首页,在全局菜单栏中点击“工具 > 粒子编辑器”关上粒子编辑器。 ...

August 4, 2022 · 1 min · jiezi

关于android:七夕活动浪漫上线别让网络拖慢和小姐姐的开黑时间

七夕情人节到了,各种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(文件上传/下载集成)和示例代码。 当适配版本为Android6.0(API Level 23)及以上时,须要动静申请读写手机存储权限(每个利用只需胜利申请一次)。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。UploadManager upManager = (UploadManager) new UploadManager .Builder("uploadManager") .build(context);结构申请体对象。咱们以上传文件file1和file2为例。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申请回调类。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统一则文件上传工作启动胜利。 ...

August 3, 2022 · 2 min · jiezi

关于android:AI智能剪辑仅需2秒一键提取精彩片段

现在短视频已成为人们娱乐社交的次要模式,很多用户也开始由观众逐步转变为短视频制作传播者,然而简单的视频剪辑工具却令他们望而止步。如何能力升高短视频制作剪辑门槛,让更多无教训者也能制作出优质的短视频内容,并乐于分享生存趣事呢? 华为HMS Core视频编辑服务6.6.0版本近期上线AI精彩片段能力,可能基于人工智能自动识别并宰割视频镜头,依据用户自定义时长智能生成精彩片段视频。同时,还能够将精彩片段能力和已有的模板能力组合应用,构建一键成片能力,无需人工剪辑即可疾速生成残缺成熟的视频作品,尤其实用于旅拍、日常拍摄等视频内容的剪辑。 设计原理视频编辑服务精彩片段能力联合了用户调研和测评,剖析出用户最关怀的视频属性,采纳了包含美学评估、内容标签、人物表情、镜头品质、运镜形式等在内的多维度评分计划,以此表征镜头的精彩水平,满足用户视频剪辑的价值需要。 美学评估是通过构图、光照、色调等维度规范数据所构建的数据集,是精彩片段能力实现的重要参考规范;内容标签和人物表情指的是精彩片段能力智能辨认并更偏向于剪辑出的内容,比方有人物和动物呈现的视频内容,或者有人物大笑表情的视频内容,都会被优先剪辑出现在精彩片段中;此外,精彩片段能力会过滤掉含糊、虚焦、过曝,以及非常抖动的镜头画面,取其精华,去其糟粕,最终出现优质成熟的精彩片段,整个处理过程通常在2秒以内。 能力劣势1、 通过迭代优化设计模型和打分策略,视频编辑服务精彩片段能力的业余评测和众测打分成果优于业界友商,可助力利用充沛开掘用户视频创作的价值。 2、 为晋升精彩片段的生成运行效率,通过“稠密采样-浓密采样”两阶段算法,联合大量用户视频的散布法则,采纳缓存帧等策略疾速找到符合要求的片段;利用线程池调度,生产者-消费者模型实现视频解码和模型并行,助力算法高效运行。 DEMO演示 集成办法1. 开发筹备具体筹备步骤可参考华为开发者联盟官网 2. 编辑工程集成2.1 设置利用的鉴权信息 能够通过api_key或者Access Token来设置利用鉴权信息。 通过setAccessToken办法设置Access Token,在利用启动时初始化设置一次即可,无需屡次设置。 MediaApplication.getInstance().setAccessToken("your access token");通过setApiKey办法设置api_key,在利用启动时初始化设置一次即可,无需屡次设置。 MediaApplication.getInstance().setApiKey("your ApiKey");2.2设置惟一标识ID,即License ID。 License ID是进行管控的无效凭证,您要保障设置License ID的唯一性。 MediaApplication.getInstance().setLicenseId("License ID");2.2.1初始化Editor运行环境 创立编辑工程,须要首先创立Editor对象并初始化其运行环境。当来到编辑工程时,应开释Editor实例。 (1) 创立Editor对象 HuaweiVideoEditor editor = HuaweiVideoEditor.create(getApplicationContext());(2) 指定预览窗口的布局地位 预览窗口负责视频图像画面的渲染,由视频编辑原子能力SDK外部创立SurfaceView来实现。在创立窗口之前,须要在您的App中指定预览窗口的布局地位。 <LinearLayout android:id="@+id/video_content_layout" android:layout_width="0dp" android:layout_height="0dp" android:background="@color/video_edit_main_bg_color" android:gravity="center" android:orientation="vertical" />// 指定预览窗口 LinearLayout mSdkPreviewContainer = view.findViewById(R.id.video_content_layout);// 设置预览窗口承载的布局 editor.setDisplay(mSdkPreviewContainer);(3) 初始化运行环境,如果License鉴权失败,会抛出LicenseException。 当Editor对象创立之后,此时还没有占用理论的系统资源,须要手动抉择其环境初始化的机会,此时视频编辑原子能力SDK外部会创立必须的线程和定时器等。 try { editor.initEnvironment(); } catch (LicenseException error) { SmartLog.e(TAG, "initEnvironment failed: " + error.getErrorMsg()); finish(); return; }3. “精彩片段”能力集成// 创立精彩片段解决对象HVEVideoSelection hveVideoSelection = new HVEVideoSelection();// 初始化精彩片段AI引擎hveVideoSelection.initVideoSelectionEngine(new HVEAIInitialCallback() { @Override public void onProgress(int progress) { // 初始化进度 } @Override public void onSuccess() { // 初始化胜利 } @Override public void onError(int errorCode, String errorMessage) { // 初始化失败 }}); // 初始化胜利后,提取精彩片段,filePath为视频的门路,duration为须要提取片段的长度hveVideoSelection.getHighLight(filePath, duration, new HVEVideoSelectionCallback() { @Override public void onResult(long start) { // 精彩片段提取胜利 }});// 开释精彩片段AI引擎hveVideoSelection.releaseVideoSelectionEngine();理解更多详情>> ...

August 2, 2022 · 1 min · jiezi

关于android:AI目标分割能力无需绿幕即可实现快速视频抠图

绿幕抠图是影视制作过程中常见的技术手段,罕用于视频中抠除并替换背景,通过前期加工实现视频剪辑制作的更多可能性。然而,绿幕抠图技术制作老本费时费力,无奈利用于日常生活。 华为视频编辑服务近期上线指标宰割能力,可通过AI智能抠图精细化宰割视频中的指标物体,并且不局限于特定的物体类别,在主体明确、背景绝对简略的视频中进行主体和背景的宰割,能够获得不错的解决成果。 利用场景指标宰割能力多利用于视频直播、在线教育、论坛会议等场景。比方,在卖货直播的场景中,能够将直播背景替换成商品详情页的轮播画面,便于用户及时理解商品;在线上论坛或者视频会议中,将背景替换成PPT内容或者办公场景,营造学习办公的庄重气氛。同样,指标宰割能力也可满足用户日常趣味剪辑,用户能够通过指标宰割能力剪辑人像视频,而后将背景切换各国名景,足不出户便能实现“周游世界”。 除了更换视频背景,指标宰割能力还可利用于影视播放,通过指标抠图,防止弹幕遮挡剧情主体,优化用户观看体验。联合其余技术能力,还能够将宰割后的指标物体进行复制和删除,甚至调整指标物体的动作工夫,打造更具创意的视频作品。 实现原理那么,指标宰割能力是怎么实现的呢? 首先,用户须要抉择指标物体,而后再进行AI指标宰割。通过给定视频第一帧图像须要宰割指标物体的对应掩码,AI模型会主动在后续每一帧的视频帧中匹配这个物体并尝试宰割进去。并且,模型将会保留两头帧宰割成果好的后果掩码与第一帧的掩码信息相结合,在后续视频帧中进行匹配,能够精准勾画指标物体的边缘细节,进一步晋升指标宰割的准确度。 DEMO演示 集成形式1. 开发筹备具体筹备步骤可参考华为开发者联盟官网 2. 编辑工程集成2.1 设置利用的鉴权信息 能够通过api_key或者Access Token来设置利用鉴权信息。 通过setAccessToken办法设置Access Token,在利用启动时初始化设置一次即可,无需屡次设置。 MediaApplication.getInstance().setAccessToken("your access token");通过setApiKey办法设置api_key,在利用启动时初始化设置一次即可,无需屡次设置。 MediaApplication.getInstance().setApiKey("your ApiKey");2.2设置惟一标识ID,即License ID。 License ID是进行管控的无效凭证,您要保障设置License ID的唯一性。 MediaApplication.getInstance().setLicenseId("License ID");2.2.1初始化Editor运行环境 创立编辑工程,须要首先创立Editor对象并初始化其运行环境。当来到编辑工程时,应开释Editor实例。 (1) 创立Editor对象 HuaweiVideoEditor editor = HuaweiVideoEditor.create(getApplicationContext());(2) 指定预览窗口的布局地位 预览窗口负责视频图像画面的渲染,由视频编辑原子能力SDK外部创立SurfaceView来实现。在创立窗口之前,须要在您的App中指定预览窗口的布局地位。 <LinearLayout android:id="@+id/video_content_layout" android:layout_width="0dp" android:layout_height="0dp" android:background="@color/video_edit_main_bg_color" android:gravity="center" android:orientation="vertical" />// 指定预览窗口 LinearLayout mSdkPreviewContainer = view.findViewById(R.id.video_content_layout);// 设置预览窗口承载的布局 editor.setDisplay(mSdkPreviewContainer);(3) 初始化运行环境,如果License鉴权失败,会抛出LicenseException。 当Editor对象创立之后,此时还没有占用理论的系统资源,须要手动抉择其环境初始化的机会,此时视频编辑原子能力SDK外部会创立必须的线程和定时器等。 try { editor.initEnvironment(); } catch (LicenseException error) { SmartLog.e(TAG, "initEnvironment failed: " + error.getErrorMsg()); finish(); return; }3. “指标宰割”能力集成// 初始化指标宰割AI引擎videoAsset.initSegmentationEngine(new HVEAIInitialCallback() { @Override public void onProgress(int progress) { // 初始化进度 } @Override public void onSuccess() { // 初始化胜利 } @Override public void onError(int errorCode, String errorMessage) { // 初始化失败 }});// 初始化胜利后,抉择须要宰割的指标进行宰割,返回抉择宰割指标的的处理结果// bitmap蕴含须要宰割的指标的视频帧图片;timeStamp为视频帧图片在工夫线上的工夫戳;points为基于视频帧图片的坐标点汇合,左上角为原点坐标,坐标点应位于须要宰割的指标内,且个数倡议大于等于2,需依据坐标点轨迹来确定抉择的指标int result = videoAsset.selectSegmentationObject(bitmap, timeStamp, points);// 指标宰割的处理结果胜利后,增加指标宰割AI特效videoAsset.addSegmentationEffect(new HVEAIProcessCallback() { @Override public void onProgress(int progress) { // 指标宰割AI特效解决进度 } @Override public void onSuccess() { // 指标宰割AI特效解决胜利 } @Override public void onError(int errorCode, String errorMessage) { // 指标宰割AI特效解决失败 }});// 中断指标宰割AI特效解决videoAsset.interruptSegmentation();// 移除指标宰割AI特效videoAsset.removeSegmentationEffect();// 开释指标宰割AI引擎videoAsset.releaseSegmentationEngine();理解更多详情>> ...

August 1, 2022 · 1 min · jiezi

关于android:Android中的Drawable一

PS:本文系转载文章,浏览原文可读性会更好,文章开端有原文链接 目录1、Drawable 的分类2、BitmapDrawable3、ShapeDrawable1、Drawable 的分类示意一种图像的概念,然而它们又不全是图片,也是能够通过色彩来结构出各式各样的图像的成果;咱们应用最多的是 Drawable 被用来作为 View 的背景应用,Drawable 作为 View 的背景应用就有2种形式了,一种是通过 XML 布局文件来设置,一种是应用逻辑代码(Java语言、kotlin语言)给 View 设置 Drawable;Drawable 是一个抽象类,它是所有 Drawable 子类的基类,比方 BitmapDrawable、ShapeDrawable、LayerDrawable 和 StateListDrawable 等;好,咱们看看这 BitmapDrawable、ShapeDrawable、LayerDrawable 和 StateListDrawable  这几个类的申明; StateListDrawable 继承的 DrawableContainer 最终是继承 Drawable。2、BitmapDrawable讲 BitmapDrawable 的属性之前,咱们先写一个 BitmapDrawable 的 demo;(1)在 drawable 文件夹下新建一个 bitmap.xml ;<?xml version="1.0" encoding="utf-8"?><bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/img_back" android:dither="true" ></bitmap>(2)Activity 的布局文件 activity_main.xml ;<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/bitmap"/></RelativeLayout>程序运行后果如下所示;咱们下面写的 demo 是通过 bitmap.xml 文件来形容 BitmapDrawable 的,上面咱们一一列举形容 BitmapDrawable 的所用属性。android:src  :示意图片的资源 id;android:antialias  : 示意是否开启抗锯齿性能,true 示意曾经开启,如果开启了抗锯齿,那么图片就会变得平顺起来,什么意思呢?就比如说,一张图片的边是呈波浪线的,如果开启了抗锯齿性能,那么图片的边就趋向于直线的。android:dither  : 是否开启抖动成果,当图片的像素配置和手机屏幕的像素配置不统一时,开启这个选项能够让高质量的图片在低质量的屏幕上还能放弃较好的显示成果。android:filter  : 是否开启过滤成果;当图片尺寸被拉伸或者压缩时,开启过滤成果能够放弃较好的显示成果。android:gravity  : 当图片小于容器的尺寸时,设置此选项能够对图片进行定位。android:minMap  : 这是一种图像相干的解决技术,也叫纹理映射,默认值为 false。android:tileMode  : 平铺模式,这个属性有如下几个值:disabled、clamp、repeat 和 mirror,disable 它是示意敞开平铺模式,这是默认值;repeat 示意的是简略的程度和竖直方向上的平铺成果, mirror 示意一种在程度和竖直方向上的镜面投影成果,clamp 示意的成果就是图片周围的像素会扩大到四周区域。3、ShapeDrawable它可了解为通过色彩来结构的图形,能够是纯色的图形,也能够是具备突变成果的图形;咱们先写一个 demo,而后再对它的属性一一阐明;(1)在 drawable 目录下新建一个 shape_drawable.xml 文件;<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="38px"/> <solid android:color="#1756F1" /> <!--<gradient android:centerColor="#00FF00"/>--> <padding android:bottom="10px" android:top="10px" android:left="10px" android:right="10px"/> <size android:width="100px" android:height="100px"/> <!--<stroke android:width="10px"--> <!--android:dashGap="3px"--> <!--android:dashWidth="3px"--> <!--android:color="#FF0000"/>--></shape>(2)Activity 的布局文件 activity_main.xml ;<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:layout_width="match_parent" android:text="开心" android:textSize="30px" android:textColor="#FF0000" android:background="@drawable/shape_drawable" android:layout_height="wrap_content" /></RelativeLayout>程序运行的后果如下所示;咱们这里写的 ShapeDrawable 的成果是通过 shape_drawable.xml 文件的 shape 标签出现进去的;好,咱们当初解说一下 shape 标签的属性以及 shape 的子标签的其余属性;1) shape 标签的属性android:shape  : 示意图形的形态,有 rectangle、oval、line 和 ring 这4个值,rectangle 是矩形,oval 是圆形,line 是横线,ring 是圆环,它的默认值是矩形,另外 line 和 ring 这两个值必须要通过 shape 的子标签 stroke 标签来指定线的宽度和色彩等信息,才达到预期的显示成果。2)shape 标签的子标签属性2、1)corners 标签android:radius  : 实用于 shape 标签的 android:shape 属性值 rectangle,示意4个角的圆角角度,它比 android:topLeftRadius、android:bottomLeftRadius、android:bottomRightRadius 和 android:topRightRadius 这几个属性的优先级低。android:topLeftRadius   :左上角的角度。android:bottomLeftRadius  :左下角的角度。android:bottomRightRadius  :右下角的角度。android:topRightRadius  : 右上角的角度。2、2)gradient 标签它与 solid 标签是相互排挤的,其中 solid 示意纯色填充,而 gradient 则示意突变成果。android:angle  :  示意突变的角度,默认为0,其值必须为 45 的倍数,0 示意从左到右,90示意从下到上。android:centerX  :  突变中心点的横坐标。android:centerY  :  突变中心点的纵坐标。android:startColor  : 突变的起始色彩。android:centerColor  :突变的中间色。android:endColor  :  突变的完结色。android:gradientRadius  :  突变的半径。android:type  :  突变的类别,其值有 linear、radial 和 sweep 这3种,linear 是线性突变,radial 是径向突变,sweep 是扫描性突变,默认值是线性突变。2、3)solid 标签android:color  : 将整个 shape 标签给填充色彩。2、4)stroke 标签android:width  : 描边的宽度。android:color  :  描边的色彩。android:dashWidth  :  组成虚线线段的宽度。android:dashGap  :  组成虚线线段的距离。 留神:如果 android:dashWidth 和 android:dashGap 有任意一个为0,那么就没有虚线的成果。2、5)padding 标签android:left  :这个不是示意 shape 区域 的空白,而是示意蕴含 shape  的 view 的右边内边距空白。android:right :  这个不是示意 shape区域的空白,而是示意蕴含 shape 的view的左边内边距空白。android:top : 这个不是示意 shape 区域的空白,而是示意蕴含 shape 的 view 的顶部内边距空白。android:buttom : 这个不是示意 shape 区域的空白,而是示意蕴含 shape 的 view 的底部内边距空白。2、6) size 标签shape 的大小,有两个 android:width 和 android:height 属性,别离示意 shape 的宽和高;这个示意的是 shape 的固有大小,然而一般来说它并不是 shape 最终显示的大小,对于 shape 来说它并没有宽和高的概念,作为 View 的背景它会自适应 View 的宽和高;Drawable 的两个办法 getIntrinsicWidth 和 getIntrinsicHeight 示意的是 Drawable的固有宽和高,对于有些 Drawable 比方图片来说,它的固有宽和高就是图片的尺寸;而对于 shape 一般来说,它是没有固有宽和高这个概念的,size 标签设置的宽和高就是 ShapeDrawable 的固有宽和高,作为 View 的背景时,shape 会适配为 View 的大小。 ...

July 31, 2022 · 2 min · jiezi

关于android:Android-AIDL-使用教程

AIDL(Android Interface Definition Language)是一种 IDL 语言,用于生成能够在 Android 设施上两个过程之间进行过程间通信(IPC)的代码。 通过 AIDL,能够在一个过程中获取另一个过程的数据和调用其裸露进去的办法,从而满足过程间通信的需要。通常,裸露办法给其余利用进行调用的利用称为服务端,调用其余利用的办法的利用称为客户端,客户端通过绑定服务端的 Service 来进行交互。官网文档中对 AIDL 有这样一段介绍: Using AIDL is necessary only if you allow clients from differentapplications to access your service for IPC and want to handlemultithreading in your service. If you do not need to performconcurrent IPC across different applications, you should create yourinterface by implementing a Binder or, if you want to perform IPC, butdo not need to handle multithreading, implement your interface using aMessenger. Regardless, be sure that you understand Bound Servicesbefore implementing an AIDL. ...

July 29, 2022 · 3 min · jiezi

关于android:HMS-Core音频编辑服务音源分离与空间音频渲染助力快速进入3D音频的世界

从单声道、立体声、环绕声倒退到三维声,音频回放技术的迭代演进是为了还原真实世界的声音。其中,三维声技术应用信号处理的办法对达到两耳的声音信号进行模仿,将声场还原为三维空间,更靠近真实世界。凭借这个技术,各厂商在游戏、影视、音乐等场景中为用户发明更实在天然且沉迷的听觉体验,也实现了更好的用户订阅增长。 传统3D音频的制作需获取原始的分轨素材(如录制的人声、钢琴声等),并应用业余的数字音频工作站(DAW)和3D混音插件手工制作,因而制作周期长、生产效率低、老本高、门槛高。此外,开发者因为没有歌曲的原始分轨,因而通过传统办法进行3D音频制作的难度很大。HMS Core音频编辑服务(Audio Editor Kit)提供了音源拆散(获取分轨)、空间音频渲染能力,开发者仅需输出立体声,就能疾速生成3D音频内容,晋升用户音频体验和晋升产品竞争力! HMS Core音频编辑服务3D音频生成示意图 音源拆散技术因为咱们以后接触到的音频大都是立体声,所有音频对象(如音乐中的人声、钢琴、吉他等)都曾经混合在左右两个声道当中,无奈轻易地离开,更不要提将其渲染搁置在不同的空间地位,因而将立体声中的特定元素拆散是3D化的一个核心技术。 华为算法团队通过对大量的音乐进行深度学习建模,并联合传统信号处理能力最终实现音源拆散:首先利用短时傅里叶变换(STFT)将一维的音频信号变换到二维的时频谱;而后将失去的二维的时频谱与原始的一维时域信号一起作为双流输出,通过多层的残差编码及大量数据的训练,取得指标乐器的隐空间表白;最初进一步通过一系列的变换矩阵最终还原成原始的对象立体声信号。上述处理过程中应用的变换矩阵和网络结构是华为的独特技术,是针对不同的乐器音色特点专门设计的,可能确保每一个乐器都能尽可能的拆散残缺且洁净,为3D化提供足够优质的分轨素材。其波及的外围能力包含: 1、 音频信号特征提取:包含通过编码器从时域信号间接提取特色,以及通过短时傅里叶变换从时域信号提取时频谱特色; 2、 深度学习模型构建:退出残差模块与注意力机制,加强对不同乐器谐波建模能力与时序关联能力; 3、 多通道维纳滤波:联合传统信号处理的能力,通过深度学习建模预测对象与非对象功率谱关系,构建与解决滤波系数。 音频拆散技术示意图 目前,HMS Core已对外开放了12种音源拆散的能力(人声、伴奏、鼓、小提琴、贝斯、钢琴、木吉他、电吉他、弦乐、主唱、带伴唱伴奏和管弦乐),帮忙开发者疾速地提取出本人想要的乐器进行3D化编辑。 空间音频渲染技术仅通过两只耳朵收听内部声音,人类为什么可分辨声源的地位呢?这是因为从声源传递到两只耳朵的声音实际上存在轻微的差别,包含达到工夫、接管到的能量、以及相位差等信息。而这些信息差综合体当初一系列传递函数,称为头相干传递函数(HRTF)。通过将HRTF叠加到单点声源,咱们就能够虚构出真实世界中声音的方位直达声的局部。为解决因头型、肩宽等人体体征的差别带来的HRTF因人而异的难题,咱们通过大量数据的剖析,设计了一套较普适的HRTF,能够让每个人都能享受到3D音频。另外为了营造空间中声音的反射、散射、干预等物理现象,咱们还通过叠加一系列的房间相应函数(RIR)来构建实在的空间,造成所谓的混响。因而,通过一系列的HRTF和RIR对声源进行滤波,咱们就能够将之前拆散的素材进行3D化,造成3D音乐。 空间音频渲染技术示意图 目前,HMS Core音频编辑服务提供的音源拆散、空间音频渲染服务这套组合拳曾经利用在华为音乐的高级音效当中,用户能够进入华为音乐音效页面,在高级音效栏目中抉择声空音效或声乐纯享,感触3D音频的魅力。 华为音乐声空音效与声乐纯享性能 以上技术来自华为2012实验室,通过HMS Core音频编辑服务面向开发者凋谢,在音乐音频畛域为用户带来差异化的3D音频体验。其余更多对于HMS Core音频编辑服务的信息,请拜访华为开发者联盟-HMS Core音频编辑服务官网 理解更多详情>> 拜访华为开发者联盟官网 获取开发领导文档 华为挪动服务开源仓库地址:GitHub、Gitee 关注咱们,第一工夫理解 HMS Core 最新技术资讯~

July 29, 2022 · 1 min · jiezi