-
高通、联发科在5G行动晶片战火已延烧许久,去年底更将战线延伸到旗舰市场,联发科天玑9000剑指高通Snapdragon 8 Gen 1,但其实不只是智慧机领域,双方其实在元宇宙恐也将是场硬战,高通在CES上宣布将与微软合作,共啖元宇宙商机,而联发科先前执行长蔡力行就喊话过,元宇宙不会缺席,联发科同样也获外资点名,将会是元宇宙行情下受惠的关键台股之一。高通在本次国际消费电子展(CES)宣布与微软合作,扩大并加速扩增实境(AR)在消费者和企业领域的应用,双方对元宇宙的发展充满信心,高通也正与微软在多项计画中展开合作,共同推动生态系的发展,包括打造客制化AR晶片以驱动新一代高效能、轻巧的AR眼镜,进而带来丰富的沉浸式体验;并计画整合Microsoft Mesh和Snapdragon SpacesXR开发者平台等软体。高通技术公司副总裁暨XR部门总经理Hugo Swart表示,此次和微软的合作反映了双方针对XR和元宇宙共同承诺的下一步计画。提供最先进的技术、打造XR专用晶片并透过软体平台和硬体参考设计驱动生态系,一直是高通技术公司的XR核心策略。联发科执行长蔡力行就说,联发科拥有全方位且多元的产品组合,在跨平台全球市场领到地位,手握终端运算、通讯联网领先技术,扮演元宇宙以及数位转型关键,其中技术就是联发科的优势,联发科产品必须具有低耗能、低延迟、终端运算、巨量物联网、宽频连网、AR/VR以及元宇宙优势,儘管元宇宙的发展还需要时间,但不管是谁的终端先进入,相信联发科在技术上绝对都不会缺席。全球一线大厂挤进元宇宙,包含脸书(meta)、苹果的扩增实境(AR)、虚拟实境(VR)装置将是带动元宇宙成功的关键。就目前产业数据估算,2021-2025年将带动镜头产业年复合成长91%,云端服务厂商2022年可望年增19%,而整体额外的运算产值上看400亿美元。换言之,为争夺庞大元宇宙大饼,联发科、高通后续恐也难逃一战。
-
去年2月份,谷歌与福特达成合作,签署了一项为期六年的合同。福特宣布从2023年开始,旗下的汽车和卡车都将预装谷歌地图、助手和游戏商店。福特首席执行官吉姆·法利称这个美国汽车制造商与搜索巨头之间的合作,标志着“重塑”汽车的机会——使其成为车轮上的办公室,拥有比任何手机或笔记本电脑都更多的连接。此外,谷歌还将帮助福特在供应链物流和生产等领域使用人工智能。在智能汽车方面,谷歌于2015年3月推出Android Auto,是专为在汽车中使用而设计的特殊Android界面。它由三个核心功能组成:精细导航、电话支持和音频播放。用户既可以直接在手机显示屏上运行Android Auto,也可以在受汽车支持的信息娱乐系统上运行。只需按下麦克风按钮即可立即访问Google的数字助手,例如询问天气、发送短信、播放特定歌曲等。在谷歌地图的加持下,用户还可以向它询问最近的加油站或附近可以吃点东西的地方。不只Android Auto,谷歌母公司Alphabet旗下的Waymo是全球领先的自动驾驶技术公司。Waymo是Google X实验室于2009年推出的自动驾驶计划,2016年12月从谷歌独立,成为Alphabet子公司。Waymo专注自动驾驶核心技术研发,并连续多年在路测里程、路测脱离率(自动驾驶汽车每行驶1千英里需要人工干预的次数)、路测车辆数量等关键指标方面,排名行业前列(数据来自美国加州交通管理局发布的《DMV年度路测数据报告》)。未来谷歌可基于在Android Auto、人工智能、云计算、AR/VR等领域的技术积累,进一步增强在智能汽车、自动驾驶产业生态中的产品与技术优势。 转载于CSDN公众号
-
日前,小米正式发布了小米12/Pro/X 三款新机,目前三款新机的内核源码已公开。小米已在GitHub页面放出了小米12/Pro和小米 12X的存储库,都是基于Android 12的,该系列预装了MIUI 13系统。(新浪科技)
-
按照谷歌要求,系统在推送到用户设备之前要经过谷歌验证。但是因为圣诞节放假,谷歌员工正在休假,微软工程师将Surface Duo Android 11最终版本发给谷歌之后就没有了下文,这就是Surface Duo迟迟没有收到Android 11更新的原因。
-
您好,我在鲲鹏服务器上安装android模拟器,遇到如下问题[root@localhost home]# emulator -avd qemu_android_1 -no-window -cores 4 -writable-system -gpu host -qemu --enable-kvm -m 4096 -vnc :1emulator: WARNING: System image is writabledefaultIniHostName=/home/android-sdk-9-linux_920/android-sdk-linux/tools/lib/advancedFeaturesCanary.iniCouldn't statvfs() path: No such file or directoryFound invalid RAM file. Deleting snapshotemulator: WARNING: encryption is offsetCurrentRenderer: gpuMode=hostemuglConfig_setupEnv: config->enabled=1, config->backend=hostSegmentation fault (core dumped)参考的官方文档是https://support.huaweicloud.com/dpmg-kunpengcps/kunpengcps920_02_0017.html服务器硬件信息如下请教各位大佬,是哪个环节出问题了,该怎么弄呢?
-
一、关于Global Platform Tech StudioGlobal Platform Tech Studio(以下及后续简称GPTS)是针对GlobalPlatform智能IC卡(以下及后续简称GP卡)的安全域、安全通道、内容、密钥的可视化管理及通用脚本化、命令化处理的工具平台;GPTS适用于GP卡管理、应用个人化、应用开发调试等GP卡操作及个人化开发或者测试人员使用,需要有一定的GP卡相关技术规范知识体系;GPTS的IC卡读写器类型支持本地PCSC及远程读写器,能够满足对远程PC的PCSC、Android(NFC读写、eSE/SIM、OMA、SDK)及iPhone SDK的远程APDU操作;脚本语言选择ECMAScript [ECMA_262]标准即Javascript,参考《GlobalPlatform Systems Profile and Scripting Specifications v1.1》规范;GPTS以注重轻量便捷使用为设计思路,不需要安装,下载后直接使用,并助提供在线的版本更新服务。二、能够做什么可视化管理GP卡内容、Key、安全域;远程协助IC卡、eSE或者其它开发者自定义形式的“卡”操作;使用GP系统脚本语言(JavaScript)操作IC卡;使用GP卡Shell命令操作IC卡;Android的HCE调试。三、可能需要的外部设备(非必备)PCSC智能卡读写器;支持NFC读写模式的Android手机;支持OMA的Android手机;iPhone手机。注:不局限于以上设备。四、适合谁使用GP标准的智能IC卡(Java卡为主)的开发及测试人员;Java卡应用(Applet)开发及测试人员;支持ISO7816/ISO14443的APDU要求的CPU卡应用开发及测试人员;想要能够通用化及快捷化的个人化开发及测试人员。五、使用授权免费使用六、主界面1)、设计风格:主界面采用传统的开发IDE风格,类似VS开发工具。后续版本会增加开发者扩展插件,插件管理。打开文件以脚本片段代码、Shell批命令为打开文件,后续版本会增加工程模式或解决方案的打开方式。2)、布局:开发者工具布局,从下到下,从左到右,分别为:菜单栏、工具栏、读写器快捷栏、工作空间、APDU显示区、Shell命令输入栏、输出信息框、用户或游客开发者登录状态、当前坐标及选择数。工作空间、APDU显示区、输出信息框的大小在每次退出时会自动记忆,并且在再次打开时恢复。工作空间、APDU显示区、输出信息框可以根据开发者偏好,设定浮动、停靠、自动隐藏等个性化属性。注:在Windows下只能同时开启一个开发者工具进程七、IC卡读写器功能查看刷新:查看读写器列表,刷新本地PCSC读写器;连接读写器:选择用于全局的读写器进行连接上电复位,包括本地PCSC或者远程读写器;管理本地读写器的远程访问:选择本地PCSC读写器,生成或删除“远程连接码”,设置是否允许远程访问;管理远程读写器:新增、删除远程读写器,会保存至本地配置,下次打开时可以再次选择或者管理;测试常规APDU:测试选择文件、读记录文件、读二进制文件等常规APDU。远程连接读写器:选择远程读写器,连接等待远程读写器接受访问,建立远程连接会话;八、基于Javascript的GP脚本九、最新版本v1.2更新日期:2017.08.1更新说明:修改GP系统脚本的扩展的一系列bug,Grypto、GPScp03、File等类。下载十、GPTS在线指引http://guide.gpts.zchrit.com/cn
-
蓝牙耳机 与 听筒 切换
-
我们基于鲲鹏920模拟器方案,想适配Android11模拟器,环境信息:1:模拟器kernel版本:4.142:Android系统版本:Android11-gsi根据Android 9的转码补丁,适配android11系统,系统启动后发现zygote32进程不停的重启:使用strace查看内核的系统调用信息:syscall_0x80000000(0xe7d0c3cc, 0x81, 0x7fffffff, 0, 0, 0) = 0 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 syscall_0x80000000(0xe7d0c3cc, 0x81, 0x7fffffff, 0, 0, 0) = 0 syscall_0x80000000(0xe7d0c3cc, 0x81, 0x7fffffff, 0, 0, 0) = 0 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 syscall_0x80000000(0xe7d0c3cc, 0x81, 0x7fffffff, 0, 0, 0) = 0 syscall_0x80000000(0xe7d0ba28, 0x81, 0x7fffffff, 0, 0, 0) = 0 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 syscall_0x80000000(0xe7d0ba28, 0x81, 0x7fffffff, 0, 0, 0) = 0 futex(0x781d8c7c00, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Try again) futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x781d8c7c00, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Try again) futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x781d8c7c00, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Try again) futex(0x781d8c7c00, FUTEX_WAIT_PRIVATE, 2, NULL) = 0 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x781d8c7950, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Try again) futex(0x781d8c7950, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Try again) futex(0x781d8c7c00, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Try again) futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x781d8c7a10, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Try again) futex(0x781d8c7a10, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Try again) futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7950, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Try again) futex(0x781d8c7950, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 0 futex(0x781d8c7c00, FUTEX_WAKE_PRIVATE, 1) = 1 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} --- rt_sigreturn({mask=[HUP INT QUIT ABRT USR1 USR2 PIPE ALRM TERM STKFLT CHLD CONT TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR RTMIN]}) = 0 rt_sigprocmask(SIG_SETMASK, ~[ILL TRAP BUS FPE SEGV SYS], NULL, 8) = 0 prlimit64(0, RLIMIT_CORE, NULL, {rlim_cur=0, rlim_max=RLIM64_INFINITY}) = 0 rt_sigaction(SIGSEGV, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, NULL, 8) = 0 getpid() = 1601 rt_tgsigqueueinfo(1601, 1601, SIGSEGV, {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL}) = 0 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} --- +++ killed by SIGSEGV +++目前这个问题一直没解决,求助。
-
该文件用于定义与设备对应的张量。 一个量, 在不同的参考系下按照某种特定的法则进行变换, 就是张量 在这里应该是用于后续的深度学习等建立一个数据模型。#include "minddata/dataset/core/de_tensor.h"#include "minddata/dataset/core/device_tensor.h"#include "minddata/dataset/include/dataset/constants.h"#include "minddata/dataset/core/type_id.h"#ifndef ENABLE_ANDROID#include "utils/log_adapter.h"#define EXCEPTION_IF_NULL(ptr) MS_EXCEPTION_IF_NULL(ptr)#else#include "mindspore/lite/src/common/log_adapter.h"#define EXCEPTION_IF_NULL(ptr) MS_ASSERT((ptr) != nullptr)#endif/* 以上判断若是Android环境下 则引入utils/log_adapter.h数据处理头文件,并有例外情况下的信息定义*/namespace mindspore {namespace dataset {// 定义张量DETensor::DETensor(std::shared_ptr<dataset::Tensor> tensor_impl): tensor_impl_(tensor_impl),name_("MindDataTensor"),type_(static_cast<mindspore::DataType>(DETypeToMSType(tensor_impl_->type()))),shape_(tensor_impl_->shape().AsVector()),is_device_(false) {}// Android环境下定义张量#ifndef ENABLE_ANDROIDDETensor::DETensor(std::shared_ptr<dataset::DeviceTensor> device_tensor_impl, bool is_device): device_tensor_impl_(device_tensor_impl), name_("MindDataDeviceTensor"), is_device_(is_device) {// 在Dvpp模块中,形状的顺序是(宽度、宽度步幅、高度、高度步幅)// 我们需要将[1]widthStride和[3]heightStride添加到shape\属性中,它们是实际的YUV图像形状uint8_t flag = 0;for (auto &i : device_tensor_impl->GetYuvStrideShape()) {if (flag % 2 == 1) {int64_t j = static_cast<int64_t>(i);shape_.emplace_back(j);}++flag;}std::reverse(shape_.begin(), shape_.end());MS_LOG(INFO) << "This is a YUV420 format image, one pixel takes 1.5 bytes. Therefore, the shape of"<< " image is in (H, W) format. You can search for more information about YUV420 format";// 这是一个YUV420格式的图像,一个像素需要1.5字节。因此,图像的形状是(H,W)格式。您可以搜索有关YUV420格式的更多信息。}#endifconst std::string &DETensor::Name() const { return name_; }// 若是Android下,设备张量输入转为对应的设备数据类型。enum mindspore::DataType DETensor::DataType() const {#ifndef ENABLE_ANDROIDif (is_device_) {EXCEPTION_IF_NULL(device_tensor_impl_);return static_cast<mindspore::DataType>(DETypeToMSType(device_tensor_impl_->DeviceDataType()));}#endifEXCEPTION_IF_NULL(tensor_impl_);return static_cast<mindspore::DataType>(DETypeToMSType(tensor_impl_->type()));}// 下面是尺寸大小size_t DETensor::DataSize() const {#ifndef ENABLE_ANDROIDif (is_device_) {EXCEPTION_IF_NULL(device_tensor_impl_);return device_tensor_impl_->DeviceDataSize();}#endifEXCEPTION_IF_NULL(tensor_impl_);return static_cast<uint32_t>(tensor_impl_->SizeInBytes());}const std::vector<int64_t> &DETensor::Shape() const { return shape_; }// 获取本地缓存区的内容std::shared_ptr<const void> DETensor::Data() const {#ifndef ENABLE_ANDROIDif (is_device_) {EXCEPTION_IF_NULL(device_tensor_impl_);return std::shared_ptr<const void>(device_tensor_impl_->GetHostBuffer(), [](const void *) {});}#endifreturn std::shared_ptr<const void>(tensor_impl_->GetBuffer(), [](const void *) {});}// 获取设备可变缓冲区void *DETensor::MutableData() {#ifndef ENABLE_ANDROIDif (is_device_) {EXCEPTION_IF_NULL(device_tensor_impl_);return static_cast<void *>(device_tensor_impl_->GetDeviceMutableBuffer());}#endifEXCEPTION_IF_NULL(tensor_impl_);return static_cast<void *>(tensor_impl_->GetMutableBuffer());}bool DETensor::IsDevice() const { return is_device_; }// 返回张量输入以及所适配设备的信息std::shared_ptr<mindspore::MSTensor::Impl> DETensor::Clone() const {#ifndef ENABLE_ANDROIDif (is_device_) {EXCEPTION_IF_NULL(device_tensor_impl_);return std::make_shared<DETensor>(device_tensor_impl_, is_device_);}#endifreturn std::make_shared<DETensor>(tensor_impl_);}} // namespace dataset} // namespace mindspore
-
```C++ // 导入同名的.h头文件 #include "minddata/dataset/core/global_context.h" // 导入系统自带的标准库文件 #include #include // 导入有关的.h头文件 #include "minddata/dataset/core/config_manager.h" // 判断宏ENABLE_ANDROID是否被定义,若已定义,执行随后的语句 #ifndef ENABLE_ANDROID #include "minddata/dataset/core/cv_tensor.h" #endif #include "minddata/dataset/core/device_tensor.h" #include "minddata/dataset/core/tensor.h" #include "minddata/dataset/util/allocator.h" #include "minddata/dataset/util/system_pool.h" // 双重命名空间 namespace mindspore { namespace dataset { // 单例 GlobalContext 的全局静态指针 std::unique_ptr GlobalContext::global_context_ = nullptr; std::once_flag GlobalContext::init_instance_flag_; // 声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化 constexpr int GlobalContext::kArenaSize; constexpr int GlobalContext::kMaxSize; constexpr bool GlobalContext::kInitArena; // 单例初始化器 GlobalContext *GlobalContext::Instance() { // 如果尚未创建单个全局上下文,则创建它。 否则 // 返回现有的。 std::call_once(init_instance_flag_, []() { global_context_.reset(new GlobalContext()); // Status为函数类型(当return值为函数结果状态时用) // 但并不是c语言中原带的关键字,而是自己定义的 Status rc = global_context_->Init(); if (rc.IsError()) { std::terminate(); } }); return global_context_.get(); } Status GlobalContext::Init() { config_manager_ = std::make_shared(); mem_pool_ = std::make_shared(); // 为了测试,我们可以使用虚拟池代替 // 为不同类型创建一些张量分配器并将它们挂接到池中。 tensor_allocator_ = std::make_unique>(mem_pool_); // 判断宏ENABLE_ANDROID是否被定义,若已定义,执行随后的语句 #ifndef ENABLE_ANDROID cv_tensor_allocator_ = std::make_unique>(mem_pool_); #endif device_tensor_allocator_ = std::make_unique>(mem_pool_); int_allocator_ = std::make_unique(mem_pool_); return Status::OK(); } // 通常用于调试的打印方法 void GlobalContext::Print(std::ostream &out) const { // GlobalContext 包含以下默认配置 out "GlobalContext contains the following default config: " *config_manager_ "\n"; } } // 命名空间 dataset } // 命名空间 mindspore ```
-
1.根据上次如何获取华为云平台数据的建议,我采取了第一条。然后在华为云如下界面里,复制右侧的Java代码到了Android Studio里。具体代码如下其中的ak和sk,通过以下两张图示内容而获得。在Android Studio运行后,结果如下因为所学知识有限,不太懂如上错误出现的原因,以及该如何修改。希望能给点建议,因为这个问题困扰我太久了,我需要在Android studio中获取到华为云上的数据。2.还有一个问题就是关于URL,下图真实请求URL,在网页里打不开。并且会报如下错误,这到底是为什么呢?
-
【功能模块】BoostKit ARM在 ECS ARM 云主机上搭建 ROBOX 环境启动 Android 系统,为了验证熟悉 ROBOX 开源方案的效果【操作步骤&问题现象】1、docker 镜像与实例启动正常,session-manager 启动正常2、Docker 中的 Android 系统启动失败日志截图【日志信息】(可选,上传日志内容或者附件)
-
一 前言介绍正好最近又看到热更新,对以前Android 热修复核心原理:ClassLoader类加载机制做了点补充。从16年开始开始,热修复技术开始在安卓界流行,它以classloader类加载机制为核心,可以不发布新版本就修复线上 bug ,让线上版本有能力去进行全量或者增量更新。常见的思路有两种:类加载方案,即 dex 插桩。该方案以腾讯系为主,包括微信的 Tinker、饿了么的 Amigo;底层替换,即修改替换 ArtMethod。方案以阿里系的 AndFix 等为主;本文主要介绍第一种方案。1.1 ART 和 DalvikDex :全称为Dalvik Executable Format,由很多 .class 文件处理压缩后的产物,最终可以在 Android 运行时环境执行。它适合于内存和处理器速度有限的系统。Dalvik:Google设计的Android平台的Java虚拟机。支持转换为.dex格式的Java程序运行。DVM默认使用CMS垃圾回收器。ART:Android Runtime,于Android 4.4 引入,在 Android 5.0 及更高版本作为默认的 Android 运行时。ART做出的具体改进可看安卓官方文档介绍:运行时:Android Runtime (ART) 和 Dalvik。ART 和 Dalvik 都是运行 Dex 字节码的兼容运行时,因此 ART 向下兼容Dalvik 开发的应用。AOT:ART在应用安装的时候预编译字节码到机器语言,这一机制叫Ahead-Of-Time(AOT)预编译。执行该操作后,应用程序安装会变慢,但是执行将更有效率,启动更快。1.2 dexopt与dexaotdexopt:Dalvik虚拟机加载dex文件时,会对 dex 文件进行验证和优化,得到odex(Optimized dex) 文件。odex文件只是对dex文件使用了一些优化操作码。dex2oat:dex或者odex文件经过 AOT 预编译,即得到OAT(实际上是ELF文件)可执行文件(机器码)。(相比做过odex优化,未做过优化的dex转换成OAT要花费更长的时间)1.3 ART 和 Dalvik 对比在Dalvik下,应用运行需要解释执行,常用热点代码通过即时编译器(JIT)将字节码转换为机器码,运行效率低。而在ART 环境中,应用在安装时,字节码预编译(AOT)成机器码,安装慢了,但运行效率会提高。ART占用空间比Dalvik大(字节码变为机器码), “空间换时间"。预编译也可以明显改善电池续航,因为应用程序每次运行时不用重复编译了,从而减少了 CPU 的使用频率,降低了能耗。二 ClassLoader2.1 Android运行流程Android程序编译的时候,会将.java文件编译时.class文件,然后将.class文件打包为.dex文件。Android程序运行时,Android的Dalvik/ART虚拟机就会加载.dex文件从中获得.class文件到内存中来使用。2.2 类加载工具ClassLoader任何 Java 程序都是由一个或多个 class 文件组成,在程序运行时,需要通过 Java 的类加载机制将 class 文件加载到 JVM 中才可以使用。Java程序启动时不会一次性加载所有类,而是先把保证运行的基础类加载到jvm,其它类要用时再加载。这样的好处是节省了内存的开销,用时再加载这也是java动态性的一种体现。这些类的加载就是通过ClassLoader来的,每个 Class 对象的内部都有一个 classLoader 字段来标识自己是由哪个 ClassLoader 加载的。安卓的ClassLoader小改了java的ClassLoader。class Class<T> { ... private transient ClassLoader classLoader; ...}12345常见的Android类加载器有如下四种:BootClassLoader :加载Android Framework层中的class字节码文件(类似java的BootstrapClassLoader)PathClassLoader :只能加载已经安装到Android系统中的Apk的 class 字节码文件,是Android默认使用的类加载器;(类似java的 AppClassLoader )DexClassLoader :可以加载加载制定目录的dex/jar/apk/zip文件文件(类似java中的 Custom ClassLoader ),比 PathClassLoader 更灵活,是实现热修复的重点;BaseDexClassLoader : PathClassLoader 和 DexClassLoader 的父类Log.e(TAG, "Activity.class 由:" + Activity.class.getClassLoader() +" 加载");Log.e(TAG, "MainActivity.class 由:" + getClassLoader() +" 加载");//输出:Activity.class 由:java.lang.BootClassLoader@b1202a1 加载MainActivity.class 由:dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.enjoy.enjoyfix-1/base.apk"],nativeLibraryDirectories=[/data/app/com.enjoy.enjoyfix-1/lib/x86, /system/lib, /vendor/lib]]] 加载它们之间的关系如下:public class DexClassLoader extends BaseDexClassLoader { public DexClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) { super(dexPath, new File(optimizedDirectory), librarySearchPath, parent); }} public class PathClassLoader extends BaseDexClassLoader { public PathClassLoader(String dexPath, ClassLoader parent) { super(dexPath, null, null, parent); } public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent){ super(dexPath, null, librarySearchPath, parent); }}PathClassLoader 与 DexClassLoader 在构造函数中都调用了父类的构造函数,两者唯一的区别在于:DexClassLoader多传了一个optimizedDirectory参数,并且会将其创建为File对象传给super,而PathClassLoader则直接给到null。因此两者都可以加载指定的dex,以及jar、zip、apk中的classes.dexPathClassLoader pathClassLoader = new PathClassLoader("/sdcard/xx.dex", getClassLoader()); File dexOutputDir = context.getCodeCacheDir();DexClassLoader dexClassLoader = new DexClassLoader("/sdcard/xx.dex",dexOutputDir.getAbsolutePath(), null,getClassLoader());其实optimizedDirectory参数就是dexopt的产出目录(odex)。DexClassLoader不仅仅可以加载 dex文件,还可以加载jar、apk、zip文件中的dex。而jar、apk、zip其实就是一些压缩格式,要拿到压缩包里面的dex文件就需要解压,所以,DexClassLoader在调用父类构造函数时会指定一个解压的目录。那PathClassLoader创建时,这个目录为null,就意味着不进行dexopt?并不是,optimizedDirectory为null时的默认路径为:/data/dalvik-cache。在API 26源码中,将DexClassLoader的optimizedDirectory标记为了 deprecated 弃用,实现也变得和PathClassLoader一摸一样了:public DexClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) { super(dexPath, null, librarySearchPath, parent);}2.3 双亲委托机制可以看到创建ClassLoader需要接收一个ClassLoader parent参数。这个parent的目的就在于实现类加载的双亲委托。即:某个类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{ // 检查class是否有被加载 Class c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { //如果parent不为null,则调用parent的loadClass进行加载 c = parent.loadClass(name, false); } else { //parent为null,则调用BootClassLoader进行加载 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { } if (c == null) { // 如果都找不到就自己查找 long t1 = System.nanoTime(); c = findClass(name); } } return c;}值得注意的是:c = findBootstrapClassOrNull(name);按照方法名理解,应该是当parent为null时候,也能够加载BootClassLoader加载的类。但是实际上,Android当中的实现为:(Java不同)private Class findBootstrapClassOrNull(String name){ return null;
-
内核已经打入Exagear补丁,在android容器内有些32位程序可以跑,比如zygote32,dexdump,目前两个问题:1. 如果用swiftshader做渲染,32位app会crash在renderthread,而64位正常运行。 所以exagear是否兼容swiftshader?2. crash发生之后,无法dump core,经过调试发现是在clone系统调用出错,如下在android8.1, debuggerd_handler.cpp中:failed to spawn debuggerd dispatch thread:invalid argumnet所以想问,调用失败是exagear引起的吗? 如何解决?pid_t child_pid = clone(debuggerd_dispatch_pseudothread, pseudothread_stack, CLONE_THREAD | CLONE_SIGHAND | CLONE_VM | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID, &thread_info, nullptr, nullptr, &thread_info.pseudothread_tid); if (child_pid == -1) { fatal_errno("failed to spawn debuggerd dispatch thread"); }
上滑加载中
推荐直播
-
OpenHarmony应用开发之网络数据请求与数据解析
2025/01/16 周四 19:00-20:30
华为开发者布道师、南京师范大学泰州学院副教授,硕士研究生导师,开放原子教育银牌认证讲师
科技浪潮中,鸿蒙生态强势崛起,OpenHarmony开启智能终端无限可能。当下,其原生应用开发适配潜力巨大,终端设备已广泛融入生活各场景,从家居到办公、穿戴至车载。 现在,机会敲门!我们的直播聚焦OpenHarmony关键的网络数据请求与解析,抛开晦涩理论,用真实案例带你掌握数据访问接口,轻松应对复杂网络请求、精准解析Json与Xml数据。参与直播,为开发鸿蒙App夯实基础,抢占科技新高地,别错过!
回顾中 -
Ascend C高层API设计原理与实现系列
2025/01/17 周五 15:30-17:00
Ascend C 技术专家
以LayerNorm算子开发为例,讲解开箱即用的Ascend C高层API
回顾中
热门标签