androidxmlbitmap
‘壹’ 怎么给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的例子,可以看里面的源码:
如果您对答案满意,请您关注一下名字中微博。
‘贰’ 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 优化
‘叁’ 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日)
‘肆’ 怎样使用Android中资源文件
1.在代码中使用资源文件在代码中访问资源文件,是通过R类中定义的资源文件类型和资源文件名称来访问的。具体格式为:R.资源文件类型.资源文件名称另外,除了访问用户自定义的资源文件,还可以访问系统中的资源文件。访问系统中的资源文件的格式为:android.R. 资源文件类型.资源文件名称2.在其他资源文件中引用资源文件经常会在布局文件中引用图片、颜色资源、字符串资源和尺寸资源。在其他资源中引用资源的一般格式是:@[包名称:]资源类型/资源名称使用颜色资源颜色值定义的开始时一个#号,后面是Alpha-RGB的格式。例如:#RGB#ARGB#RRGGBB#AARRGGBB引用资源格式:Java代码中:R.color.color_nameXML文件中:@[package:]color/color_name使用时在res\values\目录下,定义一个colors.xml文件,里面存放颜色名字和颜色值的键值对。如:<resources> <color name="red_bg">#f00</color> <color name="blue_text">#0000ff</color></resources>其他资源如字符串、尺寸都是类似的方法。使用字符串资源创建字符串资源文件strings.xml.里面内容也是键值对在Java代码中引用字符串资源R.string.string_name可如下取得:String str = getString(R.string.string_name).toString();在xml文件中引用字符串资源:@[package:]string/string_name使用尺寸资源尺寸资源被定义在res\values\dimens.xml文件中。相对屏幕物理密度的抽象单位
sp和精度无关的像素和dp类似,与刻度无关的像素,主要处理字体大小引用尺寸资源:在Java代码中: R.dimen.dimen_name在xml文件中:@[package:]dimen/dimen_name使用原始XML资源XML文件定义在工程的res\xml\目录下,通过Resources.getXML()方法来访问。获得原始XML文件的思路是,通过getResources().getXml()获得XML原始文件,得到XmlResourceParser对象,通过该对象来判断是文档的开始还是结尾、是某个标签的开始还是结尾,并通过一些获得属性的方法来遍历XML文件,从而访问XML文件的内容。使用drawables资源drawable资源是一些图片或者颜色资源,主要用来绘制屏幕,通过Resources.getDrawable()方法获得。drawable资源分为三类:Bitmap File(位图文件)、Color Drawable(颜色)、Nine-Patch Image(九片图片)。Android中支持的位图文件有png、jpg和gif。引用位图资源的格式:Java代码中:R.drawable.file_nameXML文件中:@[package:]drawable/file_name使用布局(layout)资源 布局资源是Android中最常用的一种资源,将屏幕中组件的布局方式定义在一个XML文件中,类似于Web中的HTML页面。 布局文件位于res\layout\中,名称任意。Android通过LayoutInflater类将XML文件中的组件解析为可视化的视图组件。在Activity中,调用Activity.setContentView()方法,将布局文件设置为Activity的界面,使用findViewById()方法来得到布局中的组件。
‘伍’ 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开发艺术探索》
‘陆’ android怎么生成bitmap
1、
[java] view plain
public Bitmap convertViewToBitmap(View view){
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
Bitmap.Config.ARGB_8888);
//利用bitmap生成画布
Canvas canvas = new Canvas(bitmap);
//把view中的内容绘制在画布上
view.draw(canvas);
return bitmap;
}
2、
[java] view plain
/**
* save view as a bitmap
*/
private Bitmap saveViewBitmap(View view) {
// get current view bitmap
view.setDrawingCacheEnabled(true);
view.buildDrawingCache(true);
Bitmap bitmap = view.getDrawingCache(true);
Bitmap bmp = plicateBitmap(bitmap);
if (bitmap != null && !bitmap.isRecycled()) { bitmap.recycle(); bitmap = null; }
// clear the cache
view.setDrawingCacheEnabled(false);
return bmp;
}
public static Bitmap plicateBitmap(Bitmap bmpSrc)
{
if (null == bmpSrc)
{ return null; }
int bmpSrcWidth = bmpSrc.getWidth();
int bmpSrcHeight = bmpSrc.getHeight();
Bitmap bmpDest = Bitmap.createBitmap(bmpSrcWidth, bmpSrcHeight, Config.ARGB_8888); if (null != bmpDest) { Canvas canvas = new Canvas(bmpDest); final Rect rect = new Rect(0, 0, bmpSrcWidth, bmpSrcHeight);
canvas.drawBitmap(bmpSrc, rect, rect, null); }
return bmpDest;
}
‘柒’ Android怎么解析带图片的xml数据
前言的前言:因为内容较多,此系列将分多篇文章记载。
1、关于图片格式
android使用的图片格式有3种:png、jpg、gif。
官方推荐使用png格式的图片。
jpg格式的图片是不被推荐使用的。
gif格式的图片是建议不使用的。
2、图片资源调用
1、通过resource ID进行Bitmap资源的调用,例如getDrawable(int)、android:drawable或者android:icon等,一般bitmap资源文件放在res/drawable-XXXX文件夹下,这也是推荐的存放位置,因为放在此文件夹下的图片资源android aapt工具会自动优化图片资源文件,例如将24-bit位图或者32-bit位图降色到8-bit位图,以节省内存,同时也不会失真。
2、如果你不希望对图片进行优化处理,可以将图片
‘捌’ Android Bitmap 与 Drawable之间的区别和转换
Android bitmap和drawable的区别和转换如下:
1.bitmap 转换 drawable
Bitmapbitmap=newBitmap(...);Drawabledrawable=newBitmapDrawable(bitmap);
//Drawabledrawable=newFastBitmapDrawable(bitmap);
2.Drawable to Bitmap
BitmapDrawable, FastBitmapDrawable直接用getBitmap
b. 其他类型的Drawable用Canvas画到一个bitmap上
Canvascanvas=newCanvas(bitmap)
drawable.draw(canvas);
Drawabled=ImagesList.get(0);Bitmapbitmap=((BitmapDrawable)d).getBitmap();
区别如下:
1.Bitmap - 称作位图,一般位图的文件格式后缀为bmp,当然编码器也有很多如RGB565、RGB888。作为一种逐像素的显示对象执行效率高,但是缺点也很明显存储效率低。
2.Drawable - 作为Android平下通用的图形对象,它可以装载常用格式的图像,比如GIF、PNG、JPG,当然也支持BMP,当然还提供一些高级的可视化对象,比如渐变、图形等。
另外还有如下相类似的格式:
Canvas - 名为画布,可以看作是一种处理过程,使用各种方法来管理Bitmap、GL或者Path路径,同时它可以配合Matrix矩阵类给图像做旋转、缩放等操作,同时Canvas类还提供了裁剪、选取等操作。
Paint - 可以把它看做一个画图工具,比如画笔、画刷。管理了每个画图工具的字体、颜色、样式。