使用闪存测速工具AndroBench50以上。现在华为应用市场已经下架此软件。请注意:华为还将对P10、P10 plus、Mate9推送系统更新,新系统除了加入新的功能以外,还会对消费者从第三方下载的Androbench软件进行干预,消费者安装androbench软件时会出现“不兼容”提示,从而无法安装。所以买回来测试闪存速度请不要更新系统。
具体如下:
1、简介
华为手机隶属于华为消费者业务,作为华为三大核心业务之一, 华为消费者业务始于2003年底,经过十余年的发展,在中国、俄罗斯、德国、瑞典、印度及美国等地设立了16个研发中心。
2、公司历史
截止2015年,华为的产品和服务遍及170多个国家,服务于全球1/3人口,在中国、俄罗斯、德国、瑞典、印度及美国等地设立了16个研发中心。消费者业务是华为三大业务之一,产品全面覆盖手机、移动宽带和家庭终端。
3、手机研发
华为在中国、德国、瑞典、俄罗斯及印度等多地设立16个研究所,集全球不同地区优势,把美欧日中等技术优势的创新资源有机地结合起来,构建全球的创新能力。
1Android运行环境的搭建
进行安卓系统的软件设计,那么JDK的开发环境搭建必须是首要的。我们选择Windows10 64位 *** 作系统。同时在JDK版本的选择中选用Windows x64版本的Java SE Development Kit 8u5,该版本稳定,应用广泛而且开源免费,获取方便。在安装的过程中要注意不要重复安装,应安装完毕后立即删除安装包,否则如果不小心再次点到安装包,该安装包会立刻删除所安装的程序并询问是否重新安装。在JDK的安装过程中,要注意开发工具,源代码,公共JRE三项都要选中,而且要安装到C盘默认目录下,同时将其附带的JRE同样安装到相同目录下,同时硬盘至少应该留有2G的空间。
选择好JDK的版本并进行安装后,我们的JAVA环境就安装好了,众所周知,安卓系统是由JAVA语言架构的,所以在搭建安卓运行环境之前必须要先安装JAVA环境。安装完JAVA环境之后,我们进行安卓开发环境的搭建。我们就要进行Android SDK版本的选择。我们这里选择android-sdk_r2441-windows版本。这个版本是与安卓80同时发布的,同时它的发布时间也在我们的安卓测试机红米NOTE5A型号之后,可以完美兼容我们的安卓测试机所运行的安卓712版本。
图1 Android运行环境的搭建
Fig1 Setup of the Android operating environment
2 Windows10系统环境变量的配置
环境变量是在 *** 作系统中的一个对象,该对象具有特定的名字,用来指定 *** 作系统在运行时的一些参数。在电脑属性的高级系统属性中进行环境变量的编辑。首先新增两个系统变量,变量名称分别为%JAVA_HOME%和%ANDROID_HOME%,变量值分别为各自安装目录。然后修改系统变量中的PATH变量,我们这里采用的是Windows10系统,修改PATH变量相对于Windows7来说更为方便快捷,在PATH环境变量中新建四条属性,如图2所示。
图2系统环境变量配置
Fig2 System environment variable configuration
3 SDK的下载与安装
配置完系统的环境变量后进行SDK的下载与安装。上文提到了我们选择的版本为android-sdk_r2441-windows版本,将其下载好的压缩包进行解压缩,然后打开Android SDK安装目录下的SDK MANAGER程序,在TOOLS目录下安装Android SDK Tools 2441、Android SDK Platform-tools 2701、Android SDK Build-tools 2703,系统提示的版本是否升级我们选择否选项,因为该版本与我们相应的JDK80以及安卓测试机运行版本都能够相匹配,如果选择更新到最新版本可能会导致一系列因为兼容性或者不匹配性所导致的错误。
API方面选则从API15到API27,即Android401到Android 810,API(Application Programming Interface)是应用程序编程接口,其工作原理是是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。在Windows10运行环境下我们自然需要相应的API进行安卓软件的开发。在Extras目录下安装Google Play services和Google USB Driver,Google Play services和IOS系统下的GameCenter的作用是相同的。
当我们打开游戏软件应用时就会出现在主屏上。可以使用谷歌的账号登录,然后创建一个昵称,可以添加一个电子邮件地址,以便与好友联系。当用户登录一个已有的谷歌账号或者注册一个新账号时,载有服务条款的界面即会呈现给用户。此时使用者可新建一个独一无二的游戏账号,而昵称和其他一些信息则用于接收其他玩家向你发出的好友邀请,当然其他游戏玩家也可以通过电子邮件来查找你。除此之外,只需点击该服务中相应的链接即可下载游戏。我们可以使用它玩相应的类似《部落战争》的游戏。
至于Google USB Driver,则使我们的安卓系统开发具有利用USB接口传输数据的能力,可以让我们所开发的软件可以通过USB接口进行相应的输入和输出。USB即插即用、支持热插拔、传输速度快、可通过扩展连接多达127个 USB 设备,不用担心 USB 加密锁与打印机等外设的冲突,极大的提高的我们所开发软件的适应性与传播性。
在相应的Build tools,API,Extras服务都安装完毕后,我们的安卓SDK就可以正常运行了,不过在此之前需检查安装目录下的tools文件夹是否存在zipalign文件,如果不存在的话将会无法运行接下来的步骤。我们需要手动将安装目录下的build-tools文件夹中的相应版本的zipalign文件复制到tools对应文件夹下。从Android 16 SDK版本开始,SDK中就包含了一个用于优化APK的新工具zipalign。
它提高了优化后的Applications与Android系统的交互效率,从而可以使整个系统的运行速度有了较大的提升。Android小组强烈建议开发者在发布新Apps之前使 用zipalign优化工具,而且对于已经发布但不受限于系统版本的Apps,建议用优化后的APK替换现有的版本。使用zipalign工具,会提升我们的APP性能,降低内存使用率,降低手机发热程度,这对于我们的由小米手机厂商开发的红米NOTE5A手机来说是“至关重要”的。使用cmd命令符进行zipalign优化如图3所示。
图3 zipalign优化
Fig3 the optimization of zipalign
4 Android SDK接口的设置及APK的生成
手机屏幕尺寸在主视窗口Game模块下将Free Aspect修改为16:10 LandScape屏幕比例,以适应大部分安卓手机。
SDK与JDK的接口设置:在unity编译器中选择SDK,JDK安装目录进行环境配置,安卓API选择Android50版本,并更新项目名称,将SDK版本升级到Sdk18以上。在Build Setting中将设置修改为安卓50。
5 总结
本次主要介绍了系统软件环境的搭建与生成,从Android运行环境的搭建,Windows系统环境变量设置,Android SDK的配置, SDK接口和APK生成几个方面分别介绍了具体步骤,让我们了解了本文安卓系统软件开发的环境配置。
以上就是安卓环境和下载和安装啦,按步骤来 *** 作对小白来说也是相对简单的,只要注意一些文中说明的细节,现在就开始行动起来一起学unity吧。
深入理解Android Runtime申国骏
2022-08-08 12:31·字数:2599·阅读:2340
imagepng
上图是Android整体的架构,Android Runtime之于Android而言相当于心脏之于人体,是Android程序加载和运行的环境。这篇文章主要针对Android Runtime部分进行展开,探讨Android Runtime的发展以及目前现状,并介绍应用Profile-Guided Optimization(PGO)技术对应用启动速度进行优化的可行性。转载请注明来源「申国骏」
App运行时演进
JVM
Android原生代码使用Java或者Kotlin编写,这些代码会通过javac或者kotlinc编译成class文件,在Android之前,这些class文件会被输入到JVM中执行。JVM可以简单分为三个子系统,分别是Class Loader、Runtime Data Area以及Execution Engine。其中Class Loader主要负责加载类、校验字节码、符号引用链接及对静态变量和静态方法分配内存并初始化。Runtime Data负责存储数据,分为方法区、堆区、栈区、程序计数器以及本地方法栈。Execution Engine负责二进制代码的执行以及垃圾回收。
imagepng
Execution Engine中,会采用Interpreter或者JIT执行。其中Interpreter表示在运行的过程中对二进制代码进行解释,每次执行相同的二进制代码都进行解释比较浪费资源,因此对于热区的二进制代码会进行JIT即时编译,对二进制代码编译成机器码,这样相同的二进制代码执行时,就不用再次进行解释。
imagepng
DVM(Android 21/22)
JVM是stack-based的运行环境,在移动设备中对性能和存储空间要求较高,因此Android使用了register-based的Dalvik VM。从JVM转换到DVM我们需要将class文件转换为dex文件,从class转换到dex的过程需要经过 desugar -> proguard -> dex compiler三个过程,这三个过程后来逐步变成 proguard -> D8(Desugar) 直到演变到今天只需要一步R8(D8(Desugar))。
imagepng
我们主要关注Android中Runtime Engine与JVM的区别。在Android早期的版本里面,只存在Interpreter解释器,到了Android22版本将JIT引入,这个版本Dalvik与JVM的Runtime Engine区别不大。
imagepng
ART-AOT(Android 44/50)
为了加快应用的启动速度和体验,到了Android44,Google提供了一个新的运行时环境ART(Android Runtime),到了Android50,ART替换Dalvik成为唯一的运行时环境。
imagepng
ART运行时环境中,采用了AOT(Ahead-of-time)编译方式,即在应用安装的时候就将dex提前编译成机器码,经过AOT编译之后dex文件会生成oat文件。这样在应用启动执行的时候,因为不需要进行解释编译,大大加快了启动速度。
imagepng
然而AOT带来了以下两个问题:
应用安装时间大幅增加,由于在安装的过程中同时需要编译成机器码,应用安装时间会比较长,特别在系统升级的时候,需要对所有应用进行重新编译,出现了经典的升级等待噩梦。
imagepng
应用占用过多的存储空间,由于所有应用都被编译成oat机器码,应用所占的存储空间大大增加,使得本来并不充裕的存储空间变得雪上加霜。
进一步思考对应用全量进行编译可能是没有必要的,因为用户可能只会用到一个应用的部分常用功能,并且全量编译之后更大的机器码加载会占用IO资源。
ART-PGO(Android 70)
从Android70开始,Google重新引入了JIT的编译方式,不再对应用进行全量编译,结合AOT、JIT、Interpreter三者的优势提出了PGO(Profile-guided optimization)的编译方式。
在应用执行的过程中,先使用Interpreter直接解释,当某些二进制代码被调用次数较多时,会生成一个Profile文件记录这些方法存储起来,当二进制代码被频繁调用时,则直接进行JIT即时编译并缓存起来。
当应用处于空闲(屏幕关闭且充电)的状态时,编译守护进程会根据Profile文件进行AOT编译。
当应用重新打开时,进行过JIT和AOT编译的代码可以直接执行。
这样就可以在应用安装速度以及应用打开速度之间取得平衡。
imagepng
imagepng
JIT 工作流程:
imagepng
ART-Cloud Profile(Android 90)
不过这里还是有一个问题,就是当用户第一次安装应用的时候并没有进行任何的AOT优化,通常会经过用户多次的使用才能使得启动速度得到优化。
imagepng
考虑到一个应用通常会有一些用户经常使用执行的代码(例如启动部分以及用户常用功能)并且大多数时候会有先行版本用于收集Profile数据,因此Google考虑将用户生成的Profile文件上传到Google Play中,并在应用安装时同时带上这个Profile文件,在安装的过程中,会根据这个Profile对应用进行部分的AOT编译。这样当用户安装完第一次打开的时候,就能达到较快的启动速度。
imagepng
imagepng
Profile in cloude 需要系统应用市场支持,在国内市场使用Google Play的占比非常低,因此cloud profile的优化在国内几乎是没有作用的,不过Profile的机制提供了一个可以做启动优化的思路。早在2019年,支付宝就在秒开技术的回应的里面提到过profile-based compile的技术,参考:如何看待今日头条自媒体发布谣言称「支付宝几乎秒开是因为采用华为方舟编译器」?,这也是我们一直研究Profile技术的原因。困扰着我们的一直有两个问题,第一个问题是如何生成Profile文件,第二个问题是怎么使用生成的Profile文件。对于第一个问题的解决相对还是有思路的,因为app运行就会生成profile文件,因此我们手动运行几次app就能在文件系统中收集到这个文件,不过如何以一种较为自动化的手段收集仍然是个问题。第二个问题我们知道Profile文件最终生成的位置,因此我们可以把生成的文件放到相应的系统目录,不过大多数手机和应用都没有权限直接放置这个文件。因此Profile优化技术一直都没有落地,直到Baseline Proflie让我们看到了希望。
Baseline Profile
Baseline Profile是一套生成和使用Profile文件的工具,在2022年一月份开始进入视野,随后在Google I/O 2022随着Jetpack新变化得到广泛关注。其背景是Google Map加快了发版速度,Cloud Profle还没完全收集好就上新版,导致Cloud Proflie失效。还有一个背景是Jetpack Compose 不是系统代码,因此没有完全编译成机器码,而且Jetpack Compose库比较大,因此在Profile生成之前使用了Jetpack Compose的应用启动会产生性能问题。最后Google为了解决这些问题,创造了收集Profile的BaselineProfileRule Macrobenchmark以及使用Profile的ProfileInstaller。
使用Baseline Profile的机制可以在Android7及以上的手机上得到应用的启动加速,因为从上述知道Android7就已经开始有PGO(Profile-guided optimization)的编译方式。生成的Profile文件会打包到apk里面,并且会结合Google Play的Cloud Profile来引导AOT编译。虽然在国内基本上用不了Cloud Profile,不过Baseline Profile是可以独立于Google Play单独使用的。
imagepng
在使用了Baseline Proflie之后,有道词典的启动速度从线上统计上看,冷启动时间有15%的提升。
这篇文章主要介绍了Android Runtime的演进以及对于应用启动的影响,下一篇文章我会详细介绍关于Profile&dex文件优化、Baseline Profile工具库原理,以及在实际 *** 作上如何使用的问题,敬请大家期待一下!3)查看进程列表:adb shell "ps",同时也能获取到应用的UID,方式如下(不需root权限):
u0_a开头的都是Android的应用进程,Android的应用的UID是从10000开始,到19999结束,可以在Processjava中查看到(FIRST_APPLICATION_UID和LAST_APPLICATION_UID),u0_a后面的数字就是该应用的UID值减去FIRST_APPLICATION_UID所得的值,所以,对于截图这个应用进程,它是u0_a155,按前面的规制,它的UID就是155 + FIRST_APPLICATION_UID = 10155。
VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS
使用 adb shell "dumpsys meminfo -s <pakagename | pid>"命令,输出结果分以下4部分:
PS:在apk内调用运行获取其他app的内存数据则需要root权限
adb命令:adb shell dumpsys gfxinfo <package | pid>
正常情况下帧率应该在1667ms左右,1秒60帧,执行结果如下:
详细计算方法如下:
还有一个命令是: adb shell dumpsys SurfaceFlinger --latency LayerName
其中LayerName在各个不同系统中获取的命令是不一样的
在Android 6系统直接就是SurfaceView
在Android 7系统中可以通过 dumpsys window windows | grep mSurface | grep SurfaceView 然后通过数据截取到
在Android 8系统中可以通过 dumpsys SurfaceFlinger | grep android包名获取到
执行命令结果如下:
计算方法比较简单,一般打印出来的数据是129行(部分机型打印两次257行,但是第一部分是无效数据,取后半部分),取len-2的第一列数据为end_time,取len-128的第一列数据为start_time
fps = 127/((end_time - start_time) / 10000000)
至于为啥要取第一列数据,这里不做过多介绍,欢迎参看这两篇文章
老罗的文章SurfaceView原理
Android性能测试之fps获取
至于为啥要处于1000000,因为命令打印出来的是纳秒单位,要转为毫秒进行计算,127就是因为命令一次打印出来127帧的数据而已
有两种方法可以获取
1) adb shell "top -n 5 | grep <package | pid>" ,第三列就是实时监控的CPU占用率(-n 指定执行次数,不需root权限),这边top命令执行需要2到3s左右,一般可以采用busybox 的top命令执行,效率会快很多
2) adb shell "dumpsys cpuinfo | grep <package | pid>"
两种方法直接区别在于,top是持续监控状态,而dumpsys cpuinfo获取的实时CPU占用率数据
adb命令:adb shell "dumpsys batterystats < package | pid>" (Android 50后引入)
获取单个应用的耗电量信息,具体返回结果待研究
adb命令:adb shell "dumpsys battery"
出现信息解读:
AC powered:false 是否连接AC(电源)充电线
USB powered:true 是否连接USB(PC或笔记本USB插口)充电
Wireless powered:false 是否使用了无线电源
status: 1 电池状态,2为充电状态,其他为非充电状态
level:58 电量(%)
scale: 100 电量最大数值
voltage: 3977 当前电压(mV)
current now: -335232 当前电流(mA)
temperature:355 电池温度,单位为01摄氏度
adb 命令:adb shell "dumpsys< package | pid> | grep UID" [通过ps命令,获取app的UID(安装后唯一且固定)]
adb shell cat /proc/uid_stat/UID/tcp_rcv [cat为查看命令,读取tcp_rcv获取应用接收流量信息(设备重启后清零)]
adb shell cat /proc/uid_stat/UID/tcp_snd [cat为查看命令,读取tcp_snd获取应用发送流量信息(设备重启后清零)]
计算流量消耗步骤:
或者还有一种方式获取应用流量消耗:
首先判断类型:
cat /sys/class/thermal/thermal_zone/type
只有红框框出来的是有效的
cat /sys/class/thermal/thermal_zone/temp
获取CPU温度
dumpsys battery | grep temperature 单位01摄氏度
获取/proc/stat文件内容(无权限限制)
总的cpu时间片是 total = user+nice+system+idle+iowait+irq+softirq
忙碌时间为 notidle = user+nice+system +iowait+irq+softirq
cpu使用率计算方法为,先取开始的total值和忙碌时间notidle,隔一段时间片,再取一次计算total2,notidle2, cpuuse = (notidle2 – notidle) 100 / (total2 - total)%
PS:由于Android 8权限收紧,在Android 8系统手机内apk内读取文件内容为空,需要shell权限才可获取文件内容,下同
读/sys/devices/system/cpu/cpuX/cpufreq/scaling_cur_freq文件的值,X不定,看是几核手机,scaling_cur_freq是否存在也不一定,需要判断
至于为啥不取cpuinfo_cur_freq文件的值,原因是android 6,7系统获取的时候,这个文件shell没有读取权限,需要root权限
参考文章: >MyDiskTest ChipGenius ATTO Disk Benchmark 以上三种软件都是比较好的检测TF卡读写速度的软件。 另外,建议你,如果你的手机配置不是很高端话,不要装32G卡,那样手机在开机或读取下载到卡里的软件时会很慢。一般8G比较合适。你可以去淘宝里看看“闪迪SanDisk至尊高速”TF卡,读取速度达到可怕的30M/S,价格也不贵。三星也有一款Class 10 的卡,质量也是很好的,但是很难买到正版。BroadcastReceiver(广播接收器)是Android四大组件之一,顾名思义,通过广播的方式进行消息传递,其本质是一个全局的监听器,可以监听到各种广播,可以用来实现不同组件之间的通信。广播最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的,通过这样的形式来达到接、收双方的完全解耦合。
又称无序广播,这种广播完全是异步的,所有与广播Intent匹配的BroadcastReceiver,都可以收到这条广播,并且不分先后顺序,视为同时收到,通过ContextsendBroadcast()方法发送。这种广播的效率比较高,但缺点是接收器不能将处理结果传递给下一个接收器,并且无法在中途终止广播。
这是一种同步执行的广播,通过ContextsendOrderedBroadcast()方法发送,这种广播发出后,通过receiver的intent-filter中的android:priority属性来设置优先级,优先级从-1000~1000,数越大,优先级越高,使用setResult()方法把结果传递给下一个接收者,通过getResult()方法获取上一个接收者传递过来的结果,并可以通过abortBroadcast()方法丢弃该广播,使该广播不再传递给下一个接收者。
粘性广播通过ContextsendStickBroadcast()方法来发送,用此方法发送的广播会一直滞留,当有匹配此广播的接收器被注册后,该广播接收器就会收到此广播。使用此广播时,需要获得BROADCAST_STICKY权限。(在 android 50/api 21后不再推荐使用)
Android系统中内置了多个系统广播,只要涉及到手机的基本 *** 作,基本上都会发出相应的系统广播。如:开启启动,网络状态改变,拍照,屏幕关闭与开启,点亮不足等等。每个系统广播都具有特定的intent-filter,其中主要包括具体的action,系统广播发出后,将被相应的BroadcastReceiver接收。系统广播在系统内部当特定事件发生时,有系统自动发出。
以上广播都属于全局广播,发出去的广播,只要有匹配的接收者,就可以收到广播。这样一来会造成一些问题,一是消耗性能,二是容易引起安全性的问题,为了能够简单的解决这方面的问题,Android引入了一套广播本地广播机制,使用该机制发出的广播只能够在本应用内部进行传递,并且广播接收器也只能接收来自本应用发出的广播。
使用方法
1注册本地广播接收器
2发送本地广播
3注销本地广播接收器
本文用到的BroadcastReceiver
Android 80(API级别26)取消大部分静态注册广播,建议使用动态广播
>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)