Bitmap的加载和Cache
1.Bitmap的高效加载
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int rewHeight){final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res,resId,options);options.inSampleSize = calculateInSampleSize(options, reqWidth, rewHeight);options.inJustDecodeBounds = true;return BitmapFactory.decodeResource(res,resId,options);}public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int rewHeight){final int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if (height > rewHeight || width > reqWidth) {final int halfHeight = height/2;final int haleWidth = width/2;while ((halfHeight / inSampleSize) >= rewHeight&& (haleWidth/inSampleSize) >= reqWidth){inSampleSize *= 2;}}return inSampleSize;}
mImageView.setImageBitmap(BitmapUtil.decodeSampledBitmapFromResource(getResources(),R.mipmap.ic_launcher,100,100));
2. Android中的缓存策略
2.1LruCache
int maxMemory = (int)(Runtime.getRuntime().maxMemory()/1024);int cacheSize = maxMemory /8;mMemoryCache = new LruCache<String, Bitmap>(cacheSize){@Overrideprotected int sizeOf(String key, Bitmap bitmap) {return bitmap.getRowBytes() * bitmap.getHeight() / 1024;}};
mMemoryCache.get(key);
mMemoryCache.put(key,bitmap);
2.2 DiskLruCache
public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)throws IOException
File diskCacheDir = getDiskCacheDir(mContext, "bitmap");if (!diskCacheDir.exists()){diskCacheDir.mkdirs();}try {mDiskLruCache = DiskLruCache.open(diskCacheDir, 1, 1, DISK_CACHE_SIZE);} catch (IOException e) {e.printStackTrace();}
private String hashKeyFromUrl(String url){String cacheKey;try {final MessageDigest digest = MessageDigest.getInstance("MD5");digest.update(url.getBytes());cacheKey = bytesToHexString(digest.digest());} catch (NoSuchAlgorithmException e) {cacheKey = String.valueOf(url.hashCode());}return cacheKey;}private String bytesToHexString(byte[] bytes){StringBuilder sb = new StringBuilder();for (int i=0; i< bytes.length; i++) {String hex = Integer.toHexString(0xFF & bytes[i]);if (hex.length() == 1){sb.append("0");}sb.append(hex);}return sb.toString();}
String key = hashKeyFromUrl(url);try {DiskLruCache.Editor editor = mDiskLruCache.edit(key);if (editor != null) {OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX);}} catch (IOException e) {e.printStackTrace();}
private boolean downloadUrlToStream(String urlString, OutputStream outputStream){HttpURLConnection urlConnection = null;BufferedInputStream in = null;BufferedOutputStream out = null;try {final URL url = new URL(urlString);urlConnection = (HttpURLConnection)url.openConnection();in = new BufferedInputStream(urlConnection.getInputStream());out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);int b;while ((b = in.read())!=-1){out.write(b);}return true;} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (urlConnection != null){urlConnection.disconnect();}MyUtils.close(out);MyUtils.close(in);}return false;}
OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX);if (downloadUrlToStream(url, outputStream)){editor.commit();} else {editor.abort();}mDiskLruCache.flush();
Bitmap bitmap = null;String key = hashKeyFromUrl(url);try {DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);if (snapshot != null) {FileInputStream fileInputStream = (FileInputStream)snapshot.getInputStream(DISK_CACHE_INDEX);FileDescriptor descriptor = fileInputStream.getFD();bitmap = BitmapUtil.decodeSampledBitmapFromFileDescriptor(descriptor,reqWidth,rewHeight);if (bitmap != null){addBitmapToMemoryCache(key,bitmap);}}} catch (IOException e) {e.printStackTrace();}return bitmap;
2.3 ImageLoader的实现
public class ImageResizer {public ImageResizer() {}public Bitmap decodeSampledBitmapFromFileDescriptor(FileDescriptor descriptor, int reqWidth, int rewHeight ){final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFileDescriptor(descriptor, null,options);options.inSampleSize = calculateInSampleSize(options, reqWidth, rewHeight);options.inJustDecodeBounds = false;return BitmapFactory.decodeFileDescriptor(descriptor, null,options);}public Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int rewHeight){final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res,resId,options);options.inSampleSize = calculateInSampleSize(options, reqWidth, rewHeight);options.inJustDecodeBounds = false;return BitmapFactory.decodeResource(res,resId,options);}public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int rewHeight){if (reqWidth == 0 || rewHeight == 0) {return 1;}final int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if (height > rewHeight || width > reqWidth) {final int halfHeight = height/2;final int haleWidth = width/2;while ((halfHeight / inSampleSize) >= rewHeight&& (haleWidth/inSampleSize) >= reqWidth){inSampleSize *= 2;}}return inSampleSize;}
}
2.内存缓存和磁盘缓存的实现
private LruCache<String, Bitmap> mMemoryCache;private DiskLruCache mDiskLruCache;public ImageLoader(Context context) {mContext = context.getApplicationContext();int maxMemory = (int)(Runtime.getRuntime().maxMemory()/1024);int cacheSize = maxMemory /8;mMemoryCache = new LruCache<String, Bitmap>(cacheSize){@Overrideprotected int sizeOf(String key, Bitmap bitmap) {return bitmap.getRowBytes() * bitmap.getHeight() / 1024;}};File diskCacheDir = getDiskCacheDir(mContext, "bitmap");if (!diskCacheDir.exists()){diskCacheDir.mkdirs();}if (getUsableSpace(diskCacheDir) > DISK_CACHE_SIZE) {try {mDiskLruCache = DiskLruCache.open(diskCacheDir, 1, 1, DISK_CACHE_SIZE);mIsDiskLruCacheCreated = true;} catch (IOException e) {e.printStackTrace();}}}
private Bitmap getBitmapFromMemoryCache(String key){return mMemoryCache.get(key);}private void addBitmapToMemoryCache(String key, Bitmap bitmap){if (getBitmapFromMemoryCache(key) == null) {mMemoryCache.put(key, bitmap);}}
private Bitmap loadBitmapFromDiskCache(String url,int reqWidth, int rewHeight) throws IOException{if (Looper.myLooper() == Looper.getMainLooper()){throw new RuntimeException("can not visit network from UI thread.");}if (mDiskLruCache == null){return null;}Bitmap bitmap = null;String key = hashKeyFromUrl(url);DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);if (snapshot != null) {FileInputStream fileInputStream = (FileInputStream)snapshot.getInputStream(DISK_CACHE_INDEX);FileDescriptor descriptor = fileInputStream.getFD();bitmap = mImageResizer.decodeSampledBitmapFromFileDescriptor(descriptor,reqWidth,rewHeight);if (bitmap != null){addBitmapToMemoryCache(key,bitmap);}}return bitmap;}private Bitmap loadBitmapFromHttp(String url,int reqWidth, int rewHeight)throws IOException{if (Looper.myLooper() == Looper.getMainLooper()){throw new RuntimeException("can not visit network from UI thread.");}if (mDiskLruCache == null){return null;}String key = hashKeyFromUrl(url);DiskLruCache.Editor editor = mDiskLruCache.edit(key);if (editor != null) {OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX);if (downloadUrlToStream(url, outputStream)){editor.commit();} else {editor.abort();}mDiskLruCache.flush();}return loadBitmapFromDiskCache(url, reqWidth, rewHeight);}
public Bitmap loadBitmap(String url,int reqWidth, int rewHeight){Bitmap bitmap = loadBitmapFromMemoryCache(url);if (bitmap != null) {return bitmap;}try {bitmap = loadBitmapFromDiskCache(url,reqWidth,rewHeight);if (bitmap != null) {return bitmap;}bitmap = loadBitmapFromHttp(url,reqWidth,rewHeight);} catch (IOException e) {e.printStackTrace();}if (bitmap == null && !mIsDiskLruCacheCreated) {bitmap = downloadFromUrl(url);}return bitmap;}
if (Looper.myLooper() == Looper.getMainLooper()){throw new RuntimeException("can not visit network from UI thread.");}
public void bindBitmap(final String uri, final ImageView imageView,final int reqWidth, final int reqHeight){imageView.setTag(TAG_KEY_URI, uri);final Bitmap bitmap = loadBitmapFromMemoryCache(uri);if (bitmap != null) {imageView.setImageBitmap(bitmap);return;}final Runnable loadBitmapTask = new Runnable() {@Overridepublic void run() {Bitmap bitmap1 = loadBitmap(uri,reqWidth,reqHeight);if (bitmap1 != null) {LoaderResult result = new LoaderResult(imageView, uri, bitmap);mMainHandler.obtainMessage(MESSAGE_POST_RESULT, result).sendToTarget();}}};THREAD_POOL_EXECUTOR.execute(loadBitmapTask);}
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();private static final int CORE_POOL_SIZE = CPU_COUNT + 1;private static final int MAX_POOL_SIZE = CPU_COUNT*2 + 1;private static final long KEEP_ALIVE = 10L; private static final ThreadFactory sThreadFactory = new ThreadFactory() {private final AtomicInteger mCount = new AtomicInteger(1);@Overridepublic Thread newThread(@NonNull Runnable r) {return new Thread(r, "ImageLoader#" + mCount.getAndIncrement());}};public static final Executor THREAD_POOL_EXECUTOR =new ThreadPoolExecutor(CORE_POOL_SIZE,MAX_POOL_SIZE,KEEP_ALIVE, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>(), sThreadFactory);
private Handler mMainHandler = new Handler(Looper.getMainLooper()){@Overridepublic void handleMessage(Message msg) {LoaderResult result = (LoaderResult) msg.obj;ImageView imageView = result.imageView;String uri = (String) imageView.getTag();if (uri.equals(result.uri)){imageView.setImageBitmap(result.bitmap);} else {Log.d(TAG, "set image bitmap, but uri has changed,ignored!");}}};
public class ImageLoader {private static final String TAG= "ImageLoader";private static final int MESSAGE_POST_RESULT = 1;private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();private static final int CORE_POOL_SIZE = CPU_COUNT + 1;private static final int MAX_POOL_SIZE = CPU_COUNT*2 + 1;private static final long KEEP_ALIVE = 10L;private static final int IO_BUFFER_SIZE = 8 * 1024;private static final int TAG_KEY_URI = R.id.imageloader_url;private static final long DISK_CACHE_SIZE = 1024 * 1024 *50;private static final int DISK_CACHE_INDEX = 0;private boolean mIsDiskLruCacheCreated = false;private static final ThreadFactory sThreadFactory = new ThreadFactory() {private final AtomicInteger mCount = new AtomicInteger(1);@Overridepublic Thread newThread(@NonNull Runnable r) {return new Thread(r, "ImageLoader#" + mCount.getAndIncrement());}};public static final Executor THREAD_POOL_EXECUTOR =new ThreadPoolExecutor(CORE_POOL_SIZE,MAX_POOL_SIZE,KEEP_ALIVE, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>(), sThreadFactory);private Handler mMainHandler = new Handler(Looper.getMainLooper()){@Overridepublic void handleMessage(Message msg) {LoaderResult result = (LoaderResult) msg.obj;ImageView imageView = result.imageView;String uri = (String) imageView.getTag();if (uri.equals(result.uri)){imageView.setImageBitmap(result.bitmap);} else {Log.d(TAG, "set image bitmap, but uri has changed,ignored!");}}};private Context mContext;private LruCache<String, Bitmap> mMemoryCache;private DiskLruCache mDiskLruCache;private ImageResizer mImageResizer;private ImageLoader(Context context) {mImageResizer = new ImageResizer();mContext = context.getApplicationContext();int maxMemory = (int)(Runtime.getRuntime().maxMemory()/1024);int cacheSize = maxMemory /8;mMemoryCache = new LruCache<String, Bitmap>(cacheSize){@Overrideprotected int sizeOf(String key, Bitmap bitmap) {return bitmap.getRowBytes() * bitmap.getHeight() / 1024;}};File diskCacheDir = getDiskCacheDir(mContext, "bitmap");if (!diskCacheDir.exists()){diskCacheDir.mkdirs();}if (getUsableSpace(diskCacheDir) > DISK_CACHE_SIZE) {try {mDiskLruCache = DiskLruCache.open(diskCacheDir, 1, 1, DISK_CACHE_SIZE);mIsDiskLruCacheCreated = true;} catch (IOException e) {e.printStackTrace();}}}public static ImageLoader build(Context context){return new ImageLoader(context);}private Bitmap getBitmapFromMemoryCache(String key){return mMemoryCache.get(key);}private void addBitmapToMemoryCache(String key, Bitmap bitmap){if (getBitmapFromMemoryCache(key) == null) {mMemoryCache.put(key, bitmap);}}public void bindBitmap(final String uri, final ImageView imageView){bindBitmap(uri,imageView,0,0);}public void bindBitmap(final String uri, final ImageView imageView,final int reqWidth, final int reqHeight){imageView.setTag(TAG_KEY_URI, uri);final Bitmap bitmap = loadBitmapFromMemoryCache(uri);if (bitmap != null) {imageView.setImageBitmap(bitmap);return;}final Runnable loadBitmapTask = new Runnable() {@Overridepublic void run() {Bitmap bitmap1 = loadBitmap(uri,reqWidth,reqHeight);if (bitmap1 != null) {LoaderResult result = new LoaderResult(imageView, uri, bitmap);mMainHandler.obtainMessage(MESSAGE_POST_RESULT, result).sendToTarget();}}};THREAD_POOL_EXECUTOR.execute(loadBitmapTask);}public Bitmap loadBitmap(String url,int reqWidth, int rewHeight){Bitmap bitmap = loadBitmapFromMemoryCache(url);if (bitmap != null) {return bitmap;}try {bitmap = loadBitmapFromDiskCache(url,reqWidth,rewHeight);if (bitmap != null) {return bitmap;}bitmap = loadBitmapFromHttp(url,reqWidth,rewHeight);} catch (IOException e) {e.printStackTrace();}if (bitmap == null && !mIsDiskLruCacheCreated) {bitmap = downloadFromUrl(url);}return bitmap;}private Bitmap loadBitmapFromMemoryCache(String url){final String key = hashKeyFromUrl(url);return getBitmapFromMemoryCache(key);}private Bitmap loadBitmapFromHttp(String url,int reqWidth, int rewHeight)throws IOException{if (Looper.myLooper() == Looper.getMainLooper()){throw new RuntimeException("can not visit network from UI thread.");}if (mDiskLruCache == null){return null;}String key = hashKeyFromUrl(url);DiskLruCache.Editor editor = mDiskLruCache.edit(key);if (editor != null) {OutputStream outputStream = editor.newOutputStream(DISK_CACHE_INDEX);if (downloadUrlToStream(url, outputStream)){editor.commit();} else {editor.abort();}mDiskLruCache.flush();}return loadBitmapFromDiskCache(url, reqWidth, rewHeight);}private Bitmap loadBitmapFromDiskCache(String url,int reqWidth, int rewHeight) throws IOException{if (Looper.myLooper() == Looper.getMainLooper()){throw new RuntimeException("can not visit network from UI thread.");}if (mDiskLruCache == null){return null;}Bitmap bitmap = null;String key = hashKeyFromUrl(url);DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);if (snapshot != null) {FileInputStream fileInputStream = (FileInputStream)snapshot.getInputStream(DISK_CACHE_INDEX);FileDescriptor descriptor = fileInputStream.getFD();bitmap = mImageResizer.decodeSampledBitmapFromFileDescriptor(descriptor,reqWidth,rewHeight);if (bitmap != null){addBitmapToMemoryCache(key,bitmap);}}return bitmap;}private boolean downloadUrlToStream(String urlString, OutputStream outputStream){HttpURLConnection urlConnection = null;BufferedInputStream in = null;BufferedOutputStream out = null;try {final URL url = new URL(urlString);urlConnection = (HttpURLConnection)url.openConnection();in = new BufferedInputStream(urlConnection.getInputStream());out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);int b;while ((b = in.read())!=-1){out.write(b);}return true;} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (urlConnection != null){urlConnection.disconnect();}MyUtils.close(out);MyUtils.close(in);}return false;}private Bitmap downloadFromUrl(String urlString){Bitmap bitmap = null;HttpURLConnection urlConnection = null;BufferedInputStream in = null;try {final URL url = new URL(urlString);urlConnection = (HttpURLConnection)url.openConnection();in = new BufferedInputStream(urlConnection.getInputStream());bitmap = BitmapFactory.decodeStream(in);} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (urlConnection != null) {urlConnection.disconnect();}MyUtils.close(in);}return bitmap;}private String hashKeyFromUrl(String url){String cacheKey;try {final MessageDigest digest = MessageDigest.getInstance("MD5");digest.update(url.getBytes());cacheKey = bytesToHexString(digest.digest());} catch (NoSuchAlgorithmException e) {cacheKey = String.valueOf(url.hashCode());}return cacheKey;}private String bytesToHexString(byte[] bytes){StringBuilder sb = new StringBuilder();for (int i=0; i< bytes.length; i++) {String hex = Integer.toHexString(0xFF & bytes[i]);if (hex.length() == 1){sb.append("0");}sb.append(hex);}return sb.toString();}private File getDiskCacheDir(Context context, String name) {boolean externalStorageAvailable = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);final String cachePath;if (externalStorageAvailable){cachePath = context.getExternalCacheDir().getPath();} else {cachePath = context.getCacheDir().getPath();}return new File(cachePath + File.separator + name);}@TargetApi(Build.VERSION_CODES.GINGERBREAD)private long getUsableSpace(File path){if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD){return path.getUsableSpace();}final StatFs stats = new StatFs(path.getPath());return (long)stats.getBlockSize() * (long)stats.getAvailableBlocks();}private static class LoaderResult {public ImageView imageView;public String uri;public Bitmap bitmap;public LoaderResult(ImageView imageView, String uri, Bitmap bitmap) {this.imageView = imageView;this.uri = uri;this.bitmap = bitmap;}}
}
3.ImageLoader的使用
3.1照片强效果
#GridView的的布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="study.chenj.chapter_9.TestActivity"><GridViewandroid:id="@+id/gridView1"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:horizontalSpacing="5dp"android:verticalSpacing="5dp"android:listSelector="@android:color/transparent"android:numColumns="3"android:stretchMode="columnWidth"/>
</LinearLayout>#GridView的item的布局文件
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:orientation="vertical"><study.chenj.chapter_9.SquareImageViewandroid:id="@+id/image"android:scaleType="centerCrop"android:src="@mipmap/ic_launcher"android:layout_width="match_parent"android:layout_height="wrap_content" />
</LinearLayout>
public class SquareImageView extends android.support.v7.widget.AppCompatImageView {public SquareImageView(Context context) {super(context);}public SquareImageView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public SquareImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, widthMeasureSpec);}
}
public class ImageAdapter extends BaseAdapter {...@Overridepublic int getCount() {return mUrList.size();}@Overridepublic Object getItem(int position) {return mUrList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null){convertView = LayoutInflater.from(mContext).inflate(R.layout.grid_item,parent,false);holder = new ViewHolder();holder.imageView = (ImageView)convertView.findViewById(R.id.image);convertView.setTag(holder);} else {holder = (ViewHolder)convertView.getTag();}ImageView imageView = holder.imageView;final String tag = (String)imageView.getTag();final String url = (String)getItem(position);if (!url.equals(tag)){imageView.setImageDrawable(mDefaultBitmapDrawable);}if (mIsGridViewIdle && mCanGetBitmapFromNetWork){imageView.setTag(url);mImageLoader.bindBitmap(url,imageView,mImageWidth, mImageWidth);}return convertView;}}
GridView gridView = (GridView)findViewById(R.id.gridView1);gridView.setAdapter(new ImageAdapter(this,getUrls()));
3.2 优化列表的卡顿现象
public void onScrollStateChanged(AbsListView view, int scrollState) {if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE){mIsGridViewIdle = true;ImageAdapter.this.notifyDataSetChanged();} else {mIsGridViewIdle = false;}}
if (mIsGridViewIdle){imageView.setTag(url);mImageLoader.bindBitmap(url,imageView,mImageWidth, mImageWidth);}
一般来说经过上面两个步骤,列表都不会有卡顿现象,但是在某些特殊情况下,列表还是会有偶尔卡顿线程,这个时候还可以开启硬件加速。绝大多说情况下,硬件加速可以解决莫名的卡顿问题,通过设置android:hardwareAccelerated="true"即可为Activity开启硬件加速。
Bitmap的加载和Cache相关推荐
- 《Android开发艺术探索》第12章- Bitmap 的加载和 Cache 读书笔记
目录 1. 前言 2. 正文 2.1 Bitmap 的高效加载 2.1.1 说一下对于Android 中的 Bitmap 的理解 2.1.2 内存中存储的 Bitmap 对象和本地图片有什么区别? 2 ...
- 《android开发艺术探索》笔记之Bitmap的加载和Cache
<Android开发艺术探索>笔记之Bitmap的加载和Cache<一> 我放暑假前,就在图书馆借了一本<Android开发艺术探索>,这也是我看到很多人推荐的.之 ...
- Connor学Android - Bitmap的加载和缓存策略
Learn && Live 虚度年华浮萍于世,勤学善思至死不渝 前言 Hey,欢迎阅读Connor学Android系列,这个系列记录了我的Android原理知识学习.复盘过程,欢迎各位 ...
- Android开发-自己动手写Bitmap高效加载 跟OOM说再见
Bitmap 前言 BitmapFactory.Options BitmapFactory 高效加载Bitmap inDensity,inTargetDensity,inScaled inSample ...
- 高效使用Bitmaps(一) 大Bitmap的加载
转自:http://my.oschina.net/rengwuxian/blog/182885 高效使用Bitmaps有什么好处? 我 们常常提到的"Android程序优化",通常 ...
- Bitmap高效加载
1.Bitmap的基础概念 Bitmap是Android系统中的图像处理的最重要类之,Bitmap可以获取图片的信息,可以将信息进行缩放,裁剪等操作,提供了图片文件的操作支持. 2.Bitmap加载方 ...
- 安卓 Bitmap 高效加载
博客: 安卓之家 微博: 追风917 CSDN: 蒋朋的家 简书: 追风917 理论 Bitmap 的高效加载会利用 BitmapFactory.Options 来加载所需尺寸的图片,也就是可以按一定 ...
- Bitmap如何高效加载图片
如何高效加载Bitmap? 核心思想:利用BitmapFactory.Obtions来加载所需尺寸的图片. BitmapFactory.Obtions主要用到它的inSampleSize参数(采样率) ...
- Universal-imageLoader缓存图片加载
一,先要配置ImageLoaderConfiguration这个类实现全局ImageLoader的实现情况 ImageLoaderConfiguration config = new ImageLoa ...
最新文章
- 【STM32】【STM32CubeMX】STM32CubeMX的使用之五:定时器时基配置及其中断
- wcf高并发 mysql_WCF 高并发时客户端发送和服务端接收存在等待或延迟
- 译林 五年级上 单词_译林版小学英语五上Unit 4 HobbiesStory time公开课优质课件教案视频教案...
- securecrt破解版64位
- 凸包, 圆角矩阵凸包, 点的旋转,任意多边形外角和为360度, 绕着某点进行旋转
- 对一段Oracle GoldenGate (OGG) 传输进程日志(.rpt文件)的解释
- 第十三届蓝桥杯大赛软件赛省赛 Python 大学 B 组
- hadoop+Spark实战基于大数据技术之电视收视率企业项目实战
- 中兴B863AV3.2-M、B863AV3.1-M2、E900V22C免拆机通刷救砖包【安卓9.0】
- SQL server 语句删除部分数据
- vue 基础域名-单独配置
- 怎样用ps做出3D分割效果海报图
- LabVIEW程序框图保存为图像
- 微信小程序 - (广告、优惠券)弹出与关闭
- java saas_una-saas-toturial-master
- 邯郸网络服务器机柜型号,42U网络机柜规格服务器机柜型号介绍
- 算法:五笔编码,如何根据输入的词条自动生成输入编码
- 做一个好管家 Linux系统管理技巧大荟萃
- 后门狂奔者reper.exe专杀
- 央视推荐的护眼灯是哪款?盘点央视推荐的护眼灯排名
热门文章
- Carboxyrhodamine 110-PEG4-DBCO,羧罗丹明110-PEG4-DBCO是一种荧光标记染料
- M1 芯片开发环境搭建全记录 ——虚拟机、 Java、Go、Python、Web
- “东华春秋杯”上海大学生网络安全技能大赛决赛收官 聚焦高校人才培养
- C++中换行endl和\n的区别
- 写给女朋友的java_Java会说情话的女朋友
- Android动态更改TextView的字体大小
- 友邦人寿发布非一线差异化发展策略,稳步加速中国市场拓展布局
- Paper Reading||Differentiable Dynamic Quantization with Mixed Precision and Adaptive Resolution
- ubuntu下的3D桌面.compiz
- 基于聚类算法的图像分割技术