Picasso的使用及内存优化的例子
一、Picasso介绍
picasso是Square公司开源的一个Android第三方图形缓存库,地址http://square.github.io/picasso/,可以实现图片下载和缓存功能。
二、Picasso基本用法
Picasso.with(mContext).load(imageUrl).into(imageView);
代码很简洁。这一行代码解决了一下问题:
1.自动将图像缓存在本地
2.通过图片压缩转换以减少内存消耗
3.自动处理了ImageView的回收,即自动取消不在视野范围内的ImageView视图资源的加载
三、Picasso其他用法
1)在Adapter中使用
@Override
public void getView(int position, View convertView, ViewGroup parent) {
SquaredImageView view = (SquaredImageView) convertView;
if (view == null) {
view = new SquaredImageView(mContext);
}
String url = getItem(position);
Picasso.with(mContext).load(url).into(view);
}
2)图片转换
1
Picasso.with(mContext).load(imageUrl).resize(200,200).centerCrop().into(imageView);
还可以自定义转换:
Transformation transformation = new Transformation() {
@Override
public Bitmap transform(Bitmap source) {
int targetWidth = getWidth();
double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
int targetHeight = (int) (targetWidth * aspectRatio);
Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
if (result != source) {
//如果大小是相同的,相同的位图就会被返回
source.recycle();
}
return result;
}
@Override
public String key() {
return "transformation" + " desiredWidth";
}
};
定义好Transformation后,在Picasso设置transform
Picasso.with(mContext).load(imageUrl).transform(transformation).into(viewHolder.mImageView);
或者通过实现Transformation接口自定义
public class CropSquareTransformation implements Transformation {
@Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap result = Bitmap.createBitmap(source, x, y, size, size);
if (result != source) {
source.recycle();
}
return result;
}
@Override
public String key() {
return "square()";
}
}
然后将CropSquareTransformation的对象传递给transform方法即可。
3)图片未正常显示时默认的图片,通过placeholder()设置;图片显示错误时显示的默认图片,通过error()设置
Picasso.with(mContext)
.load(url)
.placeholder(R.mipmap.icon_loading)
.error(R.mipmap.icon_loading)
.into(imageView);
4)加载Resources, assets, files, content providers中的资源文件
Picasso.with(mContext).load(R.mipmap.icon).into(imageView);
Picasso.wiht(mContext).load(new File(...)).into(imageView);
四、内存优化
1)查看大图放弃memory cache
Picasso默认会使用设备的15%的内存作为内存图片缓存,且现有的api无法清空内存缓存。我们可以在查看大图时放弃使用内存缓存,图片从网络下载完成后会缓存到磁盘中,加载会从磁盘中加载,这样可以加速内存的回收。
Picasso.with(mContext)
.load(imageUrl)
.memoryPolicy(NO_CACHE, NO_STORE)
.into(imageView);
其中memoryPolicy的NO_CACHE是指图片加载时放弃在内存缓存中查找,NO_STORE是指图片加载完不缓存在内存中。
2)列表页滑动优化
picasso可以对多个加载请求设置相同的tag,即
Object tag = new Object();
Picasso.with(mContext)
.load(url)
.resize(200,200)
.centerCrop()
.tag(tag)
.into(imageView);
例如在RecyclerView滑动时监听,处理不同的表现:
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState){
if (newState == RecyclerView.SCROLL_STATE_IDLE){
Picasso.with(mContext).resumeTag(tag);
}else{
Picasso.with(mContext).pauseTag(tag);
}
});
一、加载Html代码
String html="<a href=\"http://www.111cn.net \"> 百度</a>;";
textView.setMovementMethod(LinkMovementMethod.getInstance());//允许超链接点击跳转到浏览器
textView.setText(Html.fromHtml(html));
二、加载src标签
1、加载本地图片
String html="<img src=\"file:///system/media/Pre-loaded/Pictures/Picture_01_Greenery.jpg\" />";
textView.setText(Html.fromHtml(html, new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
Drawable drawable = null;
try {
drawable = Drawable.createFromStream(new URL(source).openStream(), null);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
} catch (IOException e) {
e.printStackTrace();
}
return drawable;
}
},null));
注意:file:/别忘了加
Html还有个三参数的fronHtml方法,三个参数分别是:String source(图片资源的路径),ImageGetter imageGetter(实现ImageGetter类的对象),TagHandler tagHandler(暂不知什么用,不过这里设为null就行了)
ImageGetter类是Html类的一个静态接口,有个方法getDrawable,返回值为Drawable,作用是取得图片的Drawable
drawable = Drawable.createFromStream(new URL(source).openStream(), null);
这句代码,有一点要说,不要用网上许多人用的:
drawable= Drawable.createFromPath(source);
可能会报FileNotFound错误。
2、加载网络图片
html代码和之前差不多,把路径换成网络图片的地址就行
比如:
String html="<img src=\"http://img0.bdstatic.com/img/image/shouye/xiaoxiao/%E5%AE%A0%E7%89%A9622.jpg\" />";
但是ImageGetter的getDrawable方法需要变化:
这里使用Piccsso框架加载网络图片,不会的同学可以去百度一下
private class MyImageGetter implements Html.ImageGetter {
private URLDrawable urlDrawable = null;
@Override
public Drawable getDrawable(final String source) {
urlDrawable = new URLDrawable();
Picasso.with(context).load(source).into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
urlDrawable.bitmap = bitmap;
urlDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
textView.setText(textView.getText());//不加这句显示不出来图片,原因不详
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
return urlDrawable;
}
}
URLDrawable类:
/**
* Created by Administrator on 2016/6/28 0028.
*/
public class URLDrawable extends BitmapDrawable {
public Bitmap bitmap;
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
if (bitmap != null) {
canvas.drawBitmap(bitmap, 0, 0, getPaint());
}
}
}
调用方法如下:
textView.setText(Html.fromHtml(html, new MyImageGetter(), null));
TextView间距对于各位朋友来讲是非常的重要的一个东西了,今天我们来看一篇关于Android中设置TextView的行间距的例子,具体的如下所示。一段文字,如果行间距很小的话看着就会很不舒服,我们在使用word文档的时候行间距是可以自己调整的,那么在Android开发的过程中如果一大段很长的文字如何设置行间距呢,很简单只需要一行代码:
android:lineSpacingExtra="3dp"
分享三张效果图:
第一张,没有设置行间距的,使用系统默认的效果:
第三张,设置为10dp的效果,更明显:
在使用QQ的过程中我们会发现一个很短的界面也是可以上下拖动的,这就是带有阻尼效果功能实现,要实现这样的功能呢,系统的ScrollView是没法实现的,必须要自定义继承于ScrollView的控件,先来看下效果图。
先来看看布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<frame.zmit.cn.stretchscrollview.StretchScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#E6E6E6"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:textSize="16sp"
android:background="#FFFFFF"
android:gravity="center"
android:text="5" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E6E6E6" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:textSize="16sp"
android:background="#FFFFFF"
android:gravity="center"
android:text="5" />
</LinearLayout>
</frame.zmit.cn.stretchscrollview.StretchScrollView>
</LinearLayout>
Activity啥也没有,就不贴了
下面贴上自定义的StretchScrollView
package frame.zmit.cn.stretchscrollview;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;
/**
* A ScrollView which can scroll to (0,0) when pull down or up.
*
* @author markmjw
* @date 2014-04-30
*/
public class StretchScrollView extends ScrollView {
private static final int MSG_REST_POSITION = 0x01;
/** The max scroll height. */
private static final int MAX_SCROLL_HEIGHT = 600;
/** Damping, the smaller the greater the resistance */
private static final float SCROLL_RATIO = 0.4f;
private View mChildRootView;
private float mTouchY;
private boolean mTouchStop = false;
private int mScrollY = 0;
private int mScrollDy = 0;
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (MSG_REST_POSITION == msg.what) {
if (mScrollY != 0 && mTouchStop) {
mScrollY -= mScrollDy;
if ((mScrollDy < 0 && mScrollY > 0) || (mScrollDy > 0 && mScrollY < 0)) {
mScrollY = 0;
}
mChildRootView.scrollTo(0, mScrollY);
// continue scroll after 20ms
sendEmptyMessageDelayed(MSG_REST_POSITION, 20);
}
}
}
};
public StretchScrollView(Context context) {
super(context);
init();
}
public StretchScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public StretchScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
// set scroll mode
setOverScrollMode(OVER_SCROLL_NEVER);
}
@Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
// when finished inflating from layout xml, get the first child view
mChildRootView = getChildAt(0);
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mTouchY = ev.getY();
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (null != mChildRootView) {
doTouchEvent(ev);
}
return super.onTouchEvent(ev);
}
private void doTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_UP:
mScrollY = mChildRootView.getScrollY();
if (mScrollY != 0) {
mTouchStop = true;
mScrollDy = (int) (mScrollY / 10.0f);
mHandler.sendEmptyMessage(MSG_REST_POSITION);
}
break;
case MotionEvent.ACTION_MOVE:
float nowY = ev.getY();
int deltaY = (int) (mTouchY - nowY);
mTouchY = nowY;
if (isNeedMove()) {
int offset = mChildRootView.getScrollY();
if (offset < MAX_SCROLL_HEIGHT && offset > -MAX_SCROLL_HEIGHT) {
mChildRootView.scrollBy(0, (int) (deltaY * SCROLL_RATIO));
mTouchStop = false;
}
}
break;
default:
break;
}
}
private boolean isNeedMove() {
int viewHeight = mChildRootView.getMeasuredHeight();
int scrollHeight = getHeight();
int offset = viewHeight - scrollHeight;
int scrollY = getScrollY();
return scrollY == 0 || scrollY == offset;
}
}
Acache类下载地址:http://pan.baidu.com/s/1gfI0A9X
1、创建Acache实例
Acache acache;
acache = Acache.get(this, “main”);
2、将数据保存起来(内存和文件)
acache.put(key,value,time);
前两个无需赘述,键值对,最后一个time,传入int类型,单位为秒,代表缓存存在的时间,超出这个时间,就会清除掉缓存的数据。
3、获取缓存的数据
以一个例子来描述这个问题:
代码如下 | 复制代码 |
public class MainActivity extends Activity { |
当我第一次进入的时候,控制台打印如下:
当我立即退出又进去,打印如下:
当我延迟了十秒左右再进去,又提示如下:
这样可以证明缓存可用,并且缓存的时间也有效果。
相关文章
- 安装curl扩展支持https是非常的重要现在许多的网站都使用了https了,下面我们来看一篇关于PHP安装curl扩展支持https例子吧。 问题: 线上运行的lamp服务器,默认yu...2016-11-25
- 这篇文章主要介绍了浅谈redis key值内存消耗以及性能影响,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-07
- 这篇文章主要介绍了详解分析MySQL8.0的内存消耗,帮助大家更好的理解和学习使用MySQL,感兴趣的朋友可以了解下...2021-03-23
- 关于mysql效率优化一般通过以下两种方式定位执行效率较低的sql语句。通过慢查询日志定位那些执行效率较低的 SQL 语句,用 --log-slow-queries[=file_name] 选项启动时, mysqld 会 写一个包含所有执行时间超过 long_quer...2015-11-08
- 过了这么久,discuz论坛的问题还是困扰着很多网友,其实从各论坛里看到的问题总结出来,很关键的一点都是因为没有将数据表引擎转成InnoDB导致的,discuz在并发稍微高一点的环境下就表现的非常糟糕,产生大量的锁等待,这时候如果...2015-11-24
- java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
- MySQL是一个功能强大的开源数据库。随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它的极限。这里是101条调节和优化 MySQL安装的技巧。一些技巧是针对特定的安装环境的,但这些思路是通用的。我已经把...2013-09-11
- 这篇文章主要介绍了Angular性能优化之第三方组件和懒加载技术,对性能优化感兴趣的同学,可以参考下...2021-05-11
- 这篇文章主要介绍了解决使用OpenCV中的imread()内存报错问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
- 这篇文章主要介绍了JavaScript提高网站性能优化的建议(二)的相关资料,需要的朋友可以参考下...2016-07-29
- 本文给大家介绍的是C#程序优化的小技巧,通过此方法可以有效的降低CPU的占用率,十分的简单实用,有需要的小伙伴可以参考下。...2020-06-25
利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化)
这篇文章主要介绍了利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化),本文给大家介绍的非常想详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-24网站广告怎么投放最好?首屏广告投放类型优化和广告位布局优化的案例
网站广告怎么投放最好?一个网站中广告位置最好的是哪几个地方呢,许多的朋友都不知道如何让自己的网站广告收效最好了,今天我们就一起来看看吧。 在说到联盟优化前,...2016-10-10- floor会产生小数了如果我们不希望有小数我们是可以去除小数点的了,下面一聚教程小编来为各位介绍php使用floor去掉小数点的例子,希望对各位有帮助。 float floor (...2016-11-25
- 这篇文章主要介绍了Vue开发网站seo优化方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-05-07
CocosCreator ScrollView优化系列之分帧加载
这篇文章主要介绍了CocosCreator ScrollView的优化,从分帧加载进行了讲解,对性能优化感兴趣的同学,一定要看一下...2021-04-15- 今天小编就为大家分享一篇解决tensorflow训练时内存持续增加并占满的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-22
- 这篇文章介绍了C#操作内存读写方法的主要实现代码,下面让我们来看看具体的实例实现,有需要的朋友可以参考一下...2020-06-25
- 在本篇文章里小编给大家整理了关于C#托管内存与非托管内存之间的转换的实例以及相关知识点,需要的朋友们学习下。...2020-06-25
- 这篇文章主要介绍了javascript性能优化之DOM交互操作技巧,结合实例形式总结分析了JavaScript针对DOM操作过程中的各种常见优化操作技巧,需要的朋友可以参考下...2015-12-14