当前位置:首页 » 安卓系统 » android加载bitmap

android加载bitmap

发布时间: 2023-07-19 07:25:16

A. 怎么给bitmap赋值 android

Bitmap是Android系统中的图像处理的最重要的类之一。用它可以获取图像文件信息,对图像进行旋转,剪切,放大,缩小等操作。

Bitmap代表一张位图,使我们在开发中常用的资源,下面就对Bitmap进行简单的介绍。

Bitmap的获取方法:

1、使用BitmapDrawable

BitmapDrawable里封装的图片就是一个Bitmap对象,我们要把Bitmap包装成BitmapDrawable对象,可以调用BitmapDrawable的构造方法:

BItmapDrawbale drawable = new BItmapDrawable(bitmap);

如果要获取BitmapDrawable所包装的Bitmap对象,则可调用BitmapDrawable的getBitmap()方法:

Bitmap bitmap = drawbale.getBitmap();

2、Bitmap提供了一些静态方法来创建Bitmap对象(仅列举几个):

createBitmap(Bitmap source,int x,int y,int width,int height):从原位图source的指定坐标(x,y)开始,从中挖取宽width,高heigtht的一块出来,创建新的Bitmap对象。

createScaledBitmap(Bitmap source,int width,ing height,boolean fliter):对源位图进行缩放,缩放称宽width,高heigth的新位图。

createBitmap(int width,int height,Bitmap.Config config):创建一个宽width,高height的可变的新位图。

createBitmap(Bitmap source, int x,int y,int width,int height ,Matrix m,boolean fliter):从源位图source的指定坐标(x,y)开始,挖取宽width,高height的一块来,创建新的Bitmap对象,并按照Matrix指定的规则进行变换。

3、通过对资源文件的解析获取Bitmap对象

在这里就要用到BitmapFactory这个工具类,提供的方法如下:

decodeByteArray(byte[] data, int offset,int length):从指定字节数组的offset位置开始,将长度为length的字节数据解析成Bitmap对象。

decodeFIle(String pathName):从pathName指定的文件中解析、创建Bitmap对象。

decodeFileDescriptor(FileDescriptor fd):用于从FileDescriptor对应的文件中解析、创建Bitmap对象。

decodeResource(Resource res,int id):用于根据给定的资源ID从指定的资源文件中解析、创建Bitmap对象。

decodeStream(InputStream is):用于从指定输入流中介解析、创建Bitmap对象。

但是,在系统不断的解析、创建Bitmap的过程中,可能会由于内存小或其他原因,导致程序运行时发生OutOfMemory错误。

为此,Android为Bitmap提供了内存回收方法:

void recycle():强制回收Bitmap对象。

还有用于判断Bitmap 对象是否被回收的方法:

boolean isRecycle();

如果Android应用需要访问系统相册,都需要借助BitmapFactory解析、创建Bitmap对象。

4 从安卓无忧中看bitmap的几种例子,下面是加载bitmap的例子,可以看里面的源码


如果您对答案满意,请您关注一下名字中微博。

B. android 加载大量图片速度慢是什么原因,是访问sd卡慢,还是使用bitmap的时候慢

android 加载大量图片速度慢原因一般是访问sd卡慢,SD卡读取速度较慢造成的加载文件速度慢。
加载,汉语词语,字面意思是增加装载量。现多用于计算机相关领域,表示启动程序时文件或信息的载入。
位图文件(Bitmap),扩展名可以是.bmp或者.dib。位图是Windows标准格式图形文件,它将图像定义为由点(像素)组成,每个点可以由多种色彩表示,包括2、4、8、16、24和32位色彩。例如,一幅1024×768分辨率的32位真彩图片,其所占存储字节数为:1024×768×32/8=3072KB
位图文件图像效果好,但是非压缩格式的,需要占用较大存储空间,不利于在网络上传送。jpg格式则恰好弥补了位图文件这个缺点。

C. Android 图片加载(一)高效加载Bitmap 基础篇

由于Bitmap的特殊性以及Android对单个应用所规定的最大内存限制,我们在同时加载大量Bitmap时很容易发生内存溢出,即我们通常所说的OutOfMemoryError(OOM),因此高效加载Bitmap就成为了每个Android开发者的必备技能。

在学习如何高效地加载Bitmap之前,首先介绍一下如何加载一个Bitmap。我们都知道,Bitmap在Android中通常指的是一张图片,那么如何将JPG、PNG等格式的图片转换成Bitmap对象呢?BitmapFactory类给我们提供了一些方法:

接下来开始介绍如何高效地加载Bitmap,其实核心思想很简单: 就是采用BitmapFactory.Options参数来调整图片尺寸来适配控件的大小。

假如我们显示图片的控件ImageView宽高为100×100像素,而图片的尺寸为1024×1024像素,这个时候如果将整个图片加载进来并显示到控件上,自然是很占用内存资源的。这个时候可以通过BitmapFactory.Options按一定的采样率加载缩小后的图片,再将缩小后的图片显示到ImageView中,这样就能减小内存占用从而在一定程度上避免OOM的发生。

通过BitmapFactory.Options来缩放图片,主要是使用它的inSampleSize参数,也就是前面提到的采样率。当采样率inSampleSize为1时,采样后的图片大小为原图大小;当采样率inSampleSize>1,比如为2时,采样后的图片宽高都为原图的1/2,即像素降为原图的1/4,占用的内存大小也就是原图的1/4;比较特殊的是,当采样率inSampleSize<1时,系统会自动将该值当做1来处理。 因此可以得出一个结论:采样率inSampleSize必须是大于1的整数图片才会有缩小的效果,并且采样率同时作用于宽高,也就是说采样后的图片会缩小到原图的1/(inSampleSize^2)。比如inSampleSize=4,那么缩放比例为1/16。

我们现在知道了,通过采样率可以提高图片的加载效率,那么如何才能计算出最合适的采样率?我们可以按照如下流程:

接下来以decodeFile方法为例实现图片的缩放,其他三个方法处理方式类似。

下一篇: Android 图片加载(二)图片加载框架Glide 入门篇

《Android开发艺术探索》

D. Android图片加载及虚化效果

[TOC]

使用如下方式加载图片

会导致OOM,android对于直接通过资源id载入的资源需做cache,下次再需要此资源的时候直接从cache中得到。但这样做也造成了用过的资源都会在内存中,这样的设计不是很适合使用了很多大图片资源的应用,这样累积下来应用的内存峰值是很高的。

当使用诸如
imageView.setBackgroundResource
imageView.setImageResource
BitmapFactory.decodeResource
这样的方法来设置一张大图片时,在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存。因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的 source,decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。如果在读取时加上图片的Config参数,可以有效减少加载的内存,从而有效阻止抛OOM异常。

实际使用中,可以针对bitmap做如下操作

RenderScript是Google在API11中引入的类,可看作业android内置的图片处理框架(区别于Glide等图片处理框架,RenderScript注重于图片的处理而不是加载)。RenderScript实际操作基于RenderScript Intrinsics,一些可以帮助RenderScript快速实现各种图片处理的操作类。该类包含诸多操作功能,比如利用ScriptIntrinsicBlur,就可以简单高效地实现高斯模糊效果,可通过参数radius设置虚化的程度。

1920*1080的原始图片未经压缩读取时间可能会超过1s,使用该图片作为背景图片加载时会有明显的卡顿。此时就需要设置BitmapFactory.Options实现对待加载图片的压缩。可参照 https://blog.csdn.net/u012124438/article/details/66087785 逐步优化Bitmap加载。对于加载图片较多较频繁的功能,建议使用第三方的图片加载框架,如Glide或者Picasso。

需要注意的是,此处doBlur有两个重载,可根据需要设置图片的缩放比例.这种方式和前文通过BitmapFactory.Options设置Bitmap取样格式的效果是一致的,都是为了减小Bitmap加载的资源消耗,提高加载效率。

E. Android:窗口、自定义view、bitmap

1、ViewRoot 对应于 ViewRootImpl 类,它是连接 WindowManager 和 DecorView 的纽带,View 的三大流程均是通过 ViewRoot 来完成的。在 ActivityThread 中,当 Activity 对象被创建完毕后,会将 DecorView 添加到 Window 中,同时会创建 ViewRootImpl 对象,并将 ViewRootImpl 对棚弯象和 DecorView 建立关联

2、 自定义View-绘制流程概述

4、 Android Handler
6、 Android Bitmap

2、MeasureSpec:

3、一般来说,使用多进程会造成以下几个方面的问题:

5、Window 概念与分类:
Window 是一个抽象类,它的具体实现是 PhoneWindow。WindowManager 是外界访问 Window 的入口,Window 的具体实现位于 WindowManagerService 中,WindowManager 和 WindowManagerService 的交互是一个 IPC 过程。Android 中所有的视图都是通过 Window 来呈现,因此 Window 实际是 View 的直接管理者。

6、window的三大操作:addView、upView、removeView
7、 Bitmap 中有两个内部枚举类:

保存图片资源:

图片压缩:

基本使用:

8、Context 本身是一个抽象类,是对一系列系统服务接口的封装,包括:内部伏丛资源、包、类加载、I/O操作、权限、主线程、IPC 和组件启动等操作的管理。ContextImpl, Activity, Service, Application 这些都是 Context 的直接或间接子类

9、SharedPreferences 采用key-value(键值对)形式, 主要用于轻量级的数据存储, 尤其适合保存应用的配置参数, 但不建议使用 SharedPreferences 来存储大规模的数据, 可能会降低性能

10、SharedPreferences源码有用synchronize进行加锁同步

11、Handler 有两个主要用途:
(1)安排 Message 和 runnables 在将来的某个时刻执行;
(2)将要在不同链厅闷于自己的线程上执行的操作排入队列。(在多个线程并发更新UI的同时保证线程安全。)
只有主线程能对UI进行操作,所以在对UI进行跟改之前,ViewRootImpl 对UI操作做了验证,这个验证工作是由 ViewRootImpl的 checkThread 方法完成:

12、ThreadLocal 是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,其他线程则无法获取。Looper、ActivityThread 以及 AMS 中都用到了 ThreadLocal。当不同线程访问同一个ThreadLocal 的 get方法,ThreadLocal 内部会从各自的线程中取出一个数组,然后再从数组中根据当前 ThreadLcoal 的索引去查找对应的value值:

13、Android 提供了几种途径来从其他线程访问 UI 线程:

Android单线程模式必须遵守的规则:

14、HandlerThread 集成了 Thread,却和普通的 Thread 有显着的不同。普通的 Thread 主要用于在 run 方法中执行一个耗时任务,而 HandlerThread 在内部创建了消息队列,外界需要通过 Handler 的消息方式通知 HanderThread 执行一个具体的任务。

15、IntentService 可用于执行后台耗时的任务,当任务执行后会自动停止,由于其是 Service 的原因,它的优先级比单纯的线程要高,所以 IntentService 适合执行一些高优先级的后台任务。在实现上,IntentService 封装了 HandlerThread 和 Handler。IntentService 第一次启动时,会在 onCreatea 方法中创建一个 HandlerThread,然后使用的 Looper 来构造一个 Handler 对象 mServiceHandler,这样通过 mServiceHandler 发送的消息最终都会在 HandlerThread 中执行。每次启动 IntentService,它的 onStartCommand 方法就会调用一次,onStartCommand 中处理每个后台任务的 Intent,onStartCommand 调用了 onStart 方法。可以看出,IntentService 仅仅是通过 mServiceHandler 发送了一个消息,这个消息会在 HandlerThread 中被处理。mServiceHandler 收到消息后,会将 Intent 对象传递给 onHandlerIntent 方法中处理,执行结束后,通过 stopSelf(int startId) 来尝试停止服务。(stopSelf() 会立即停止服务,而 stopSelf(int startId) 则会等待所有的消息都处理完毕后才终止服务)。

16、RecyclerView 优化

F. Android Bitmap 内存以及OOM问题讨论

都知道在悔敏厅Android中, 每个应用所使用的内存是有限的,现在的手机通常最大的内存使用为256M, 目前还没发现Android中一个应用的最大内存分配超过256M的(经测试华为手机的最大内存是385M)

相关API:

ActivityManager.getMemoryClass(),首先获取系统服务中的ActivityManager

如下:

(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

可以获取到相关信息

最近一直被项目的OOM问题困扰, 在网上查阅相关资料,前前后后读了不下于30篇,这些篇幅讲解的东西都是千篇一律,并没有解决到实际问题

也在慕课网学习了内存优化章节

这是慕课网讲师的PPT,我截屏的

这里来仔细分析一下:

第一个,  注意临时Bitmap对象的及时回收, 来碧隐看下相关API

直接上图

经过我无数次的使用Android studio工具自带的MAT分析工具后, 得出一个很严谨的结论, 此方法并不奏效...

Android中Bitmap的内存存放在堆区, Google 的Bitmap的recycle方法注释也可以了解到

Android历史版本不是很清楚, 据说Android3.0之前Bitmap是存放在native区域,可以进行手动释放,然而3.0之后Bitmap是存放在Java层的堆区,没错是heap, 内存管理直接交由系统GC管理,你还这样释放资源有意义?无非是给自己的一点心理安慰罢了, 告诉你没卵用

又有人在说要释放内存使用System.gc() ???  对就是主动触发垃圾回收,这个API是开发者自行调用的吗?那么系统管理内存还有什么意义?这不是误人子弟吗,这个API不能调用的, 因为没卵用的, 具体自己参照MAT工具自行分析.即便垃圾回收真的被触发了, 所有线程停滞由系统来清理垃圾, 造成的后果是严重卡顿!!!

再看一个API:

我在网上苦苦追寻内存过高的问题后,发现了这个API,经过无数次实践后我得出一个结论,没卵用...开发者可以抛弃它

综上所诉, 第一点讲解的内存优化拿塌问题可以直接PASS掉, 无非给自己一点心理安慰: 我已经处理好了内存问题, 程序不会OOM?

第二点. 避免Bitmap的浪费

直接说结论, 这个是非常行之有效的,并且是一定能解决问题的

具体怎么操作呢? 自己实现LruCache这个类, 就是这么弄, 原理就是解码复用, 在内存中已经解码好的Bitmap直接拿出来使用, 没有的在加载到内存进行解析, 这个非常有效,但是并不能让你避免OOM

第三点, try-catch某些大内存分配的操作

这点上,我又要开始疑问了, 我Java功底不是很好

Java中发生内存溢出时,抛出的是OutOfMemoryError, 它的父类是VirtualMachineError

这玩意能catch住? 它属于Error范畴, 你能捕获?请Java大神出来说一下,我解释不清楚

第四点, 加载Bitmap 缩放比例, 解码格式, 局部加载

先来分析一下缩放比例:

按照市面上主流的手机分辨率来分析现在Android主流的分辨率是1920X1080, 如果一个ImageView控件刚好就是屏幕全屏,怎么说?直接占用掉8M内存, 想想一个实际的需求情况

一个查看大图的页面, 不断的关闭,打开查看新的大图,问题就来了,内存一直在暴增,迟早会突破界限OOM掉

分辨率是2K屏呢? 更恐怖了, 随着手机设备的屏幕分辨率提升, 加载图像需要的内存也是倍增的, 因为应用的最大内存并没有增加

结论: 缩放比例可以有效的降低内存占用问题, 但不是绝对的救命稻草, 该缩放的还是要缩放,而且必须缩放,就是采样  现在通常都是图片加载框架来完成,类似Glide.Picasso,Fresco等,他们可以帮助你减少工作量, 内存问题还是存在

再来分析一下解码格式:

这个跟缩放比例效果差不多, 只是同样的分辨率的图片加载到内存中时占用内存减少了

比如ARGB_8888 共32位

RGB_565  共16位

ARGB_4444 共16位

很明显这样格式图片加载的内存情况是ARGB_8888是其他格式的两倍内存

另外的问题是ARGB_8888看起来很清晰的, 其它的看起来图片有种糊了的感觉,自己选择吧

结论, 降低内存占用非常有效

最后一个是局部加载, 并没有怎么使用到,也不清楚就不说了

最后还有一个方法避免OOM, 开启largeHeap属性, 但是但是, 以前我们开启这个属性后被Oppo应用市场认定为占用内存过高, 不建议用户安装......所以我们又取消了!

总的来说, Bitmap在内存是变现的是不可控, 我项目OOM问题一直没有得到有效解决,因为图片编辑视频编辑之类的功能占用内存过高,继续使用OOM是必然的, 跟IOS的同学交流了一番,他们说IOS的应用内存可以占用到1个G以上, 轻松跑到500M是没问题的, IOS的内存机制可以持续给内存使用, 具体我也不清楚,并且他们可以手动释放内存?malloc, free这样子?

如果大家有比较好的方案,还望留言交流互相帮助 [笑脸.gif]

补充: Android8.0开始Bitmap数据内存存在native层, 单个应用可用的内存显着增长, 极大的降低了OOM的概率(2018年3月22日)

热点内容
苹果耳塞怎么改安卓也能用 发布:2025-02-05 14:50:54 浏览:557
安卓如何鉴别手机真假 发布:2025-02-05 14:28:15 浏览:119
ffmpeglinux编译 发布:2025-02-05 14:28:04 浏览:544
服务器如何做界面 发布:2025-02-05 14:27:23 浏览:290
访问学者单位推荐意见 发布:2025-02-05 14:13:05 浏览:853
微信密码锁忘了怎么办 发布:2025-02-05 14:11:07 浏览:311
web是什么文件夹 发布:2025-02-05 14:11:05 浏览:235
对信访问题调查 发布:2025-02-05 14:09:39 浏览:984
singlephp 发布:2025-02-05 14:09:24 浏览:774
数据库的字段命名规则 发布:2025-02-05 13:53:16 浏览:684