| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 移动开发 -> Android:Bitmap类的使用及其原理分析 -> 正文阅读 |
|
[移动开发]Android:Bitmap类的使用及其原理分析 |
文章目录前言本篇记录笔者在学习Bitmap过程中的思路和心得 一、起因在之前为Android界面设置图片的过程中,笔者对于设置图片大致有两种做法
但是笔者在一次本地加载清晰大图到视图上的时候,因为图片过于庞大,且数目较多(用于轮播图),熟悉Android运行期间给应用分配主存存储空间的都知道,这样的做法最终只会导致项目OOM,然后崩溃 那么如何在不对原图使用其他修图软件的基础上,加载清晰图片到自己的应用视图上同时避免OOM呢,那么便需要引入我们本篇介绍的主人公——Bitmap 二、学习Bitmap的前置知识Android屏幕显示pxpx,即像素,是屏幕上显示数据的最基本的点,在PS里面也是其最根本的单位,所有的图形都是在此基础上生成的,平时我们经常讲的手机屏幕分辨率就是以像素作为单位的,比如在android中我们经常说的手机像素是1080X1920,其实它所表达的意思是在该手机上面在横向上面有1080个像素点,在纵向上有1920个像素点。 sp在android中用来形式字体大小的单位,正常情况下会按照手机系统设置的文本大小来显示文字,但是同时也会与系统设置的文本保持一致,比如在有些老年机上面为了更好的操作手机有些人会将字体设置为较大字体,这个时候使用sp作为单位的字体也会随之变大,但是如果将字体大小的单位设置为dp,则不会随着系统字体的变化而变化。 ppi在每次的手机厂商新品发布会上,我们都会听到关于手机的介绍,比如手机的屏幕分辨率,多大尺寸等等。而当我们知晓一个手机的屏幕分辩率和手机尺寸的时候,就可以计算出手机的物理像素密度,其计算公式为: dpi屏幕密度与dpi密切相关,dpi是每英寸的点数。也就是说,密度越大,每英寸内容纳的点数就越多。 dpi十分重要,dpi 决定了应用在显示 drawable 时是选择哪一个文件夹内的切图。每个 drawable 文件夹都对应不同的 dpi 大小,Android 系统会自动根据当前手机的实际 dpi 大小从合适的 drawable 文件夹内选取图片,不同的后缀名对应的 dpi 大小就如以下表格所示。如果 drawable 文件夹名不带后缀,那么该文件夹就对应 160dpi 具体关系如下: dpdp和dip是一样的,设备独立像素,这个和设备硬件有关,不同设备有不同的显示效果。而通常在做android项目的时候,为了适配市场上面众多的手机屏幕分辩率,我们一般都会采用dp。dp是Android基于物理设备的PPI抽象出来的一个单位。它是以160dpi的屏幕为基准定义的,在160dpi的屏幕上1dp=1px,那么由此我们就可以得出其计算公式: 要想知道屏幕具体的dp,我们可以通过DisplayMetrics类获得,其中density属性表示模拟器上,每dp对应的px 三、Bitmap和内存之间的关系我们这里尝试将一张1920*1080px的图片保存到 drawable-xxhdpi 文件夹内,然后将其显示在一个宽高均为 180dp 的 ImageView 上,该 Bitmap 所占用的内存就通过 bitmap.byteCount来获取;我们来看看它最终占用了多少内存空间 下面我们通过一段代码来查看Bitmap最终用了多少空间
将19201080的图片置于mipmap-xxhdpi文件夹下,查看执行结果 inDensity代表的是系统最终选择的 mipmap 文件夹类型对应的dpi,这里可以看到hdpi对应的240,xxhdpi对应的是640; inTargetDensity代表的是目标设备对应的dpi,这里我们始终看到虚拟机对应的dpi为320 这里我们可以总结出如下事实
四、BitmapFactoryBitmapFactory提供如下方法进行加载Bitmap对象
DecodeResource方法也会调用到decodeResourceStream方法,decodeResourceStream方法如果判断到inDensity 和 inTargetDensity 两个属性外部没有主动赋值的话,就会根据实际情况进行赋值 相关代码如下:
五、BitmapConfigBitmap.Config 定义了四种常见的编码格式,分别是:
六、优化Bitmap相关在之前的前言中提到,笔者加载大图未经过任何处理直接加载到imageView上,导致了OOM的出现,那么这种情况下,势必要减小Bitmap图片的体积,保证应用的成功运行
进行考虑 进行第一种做法,我们观察到图片的宽为2560px,高为1440px; inSampleSize于是我们通过设置inSampleSize,对图片的宽和高进行压缩
我们设置inSampleSize=2,添加如下代码
结果如下 inTargetDensity如果我们不主动设置 inTargetDensity 的话,decodeResource 方法会自动根据当前设备的 dpi 来对 Bitmap 进行缩放处理,我们可以通过主动设置 inTargetDensity 来控制缩放比例,从而控制 Bitmap 的最终宽高。 Bitmap.ConfigBitmapFactory 默认使用的编码图片格式是 ARGB_8888,每个像素点占用四个字节,我们可以按需改变要采用的图片格式。例如,如果要加载的 Bitmap 不包含透明通道的,我们可以使用 RGB_565,该格式每个像素点占用两个字节 这里就不进行展示了 七、Bitmap内存存放位置
2.3-7.1之间,Bitmap的像素存储在Dalvik的Java堆上,当然,4.4之前的甚至能在匿名共享内存上分配(Fresco采用),而8.0之后的像素内存又重新回到native上去分配,不需要用户主动回收,8.0之后图像资源的管理更加优秀,极大降低了OOM。 相关的Bitmap内存分配情况监控案例可以参考这篇博客,本篇文章仅是对其进行总结
关于内存回收,NativeAllocationRegistry类为Android 8.0引入的一种辅助自动回收native内存的一种机制,当Java对象被GC机制回收的时候,NativeAllocationRegistry可以辅助回收Java对象所申请的native内存,所以Native层的对象回收并不需要我们手动支持 总结关于Bitmap类的学习笔者用以下的图进行整理 |
|
移动开发 最新文章 |
Vue3装载axios和element-ui |
android adb cmd |
【xcode】Xcode常用快捷键与技巧 |
Android开发中的线程池使用 |
Java 和 Android 的 Base64 |
Android 测试文字编码格式 |
微信小程序支付 |
安卓权限记录 |
知乎之自动养号 |
【Android Jetpack】DataStore |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 18:27:57- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |