我做一个论坛。帖子最终页用listview加载数据,其中用textview加载帖子内容。现在经常浏览一段时间之后就报内存溢出。不知道该怎么释放.
看代码
帖子页 activity,销毁的时候清空了此页加载的所有图片对象
/**
* 销毁bitmap内存。否则大图容易内存耗尽
*/
protected void onDestroy()
{
//如果过大清空,避免内存不够用
Iterator it = com.china.util.Constants.imageCache.entrySet().iterator();
while (it.hasNext())
{
Map.Entry entry = (Map.Entry) it.next();
SoftReference<Drawable> softReference = (SoftReference<Drawable>)entry.getValue();
Drawable value = softReference.get();
if(value!=null)
value.setCallback(null);
}
super.onDestroy();
}
adaper的代码片段
@Override
public View getView(int position,View convertView,ViewGroup parent){
ViewHolderThread holderThread=null;
ViewHolderComment holderComment=null;
int type = getItemViewType(position);
//根据标签类型加载不通的布局模板
ThreadComment threadComment=(ThreadComment)getItem(position);
if(convertView==null)
{
switch(type)
{
case TYPE_1:
//主贴
convertView = listlater.inflate(R.layout.threadcontentview , parent, false);
holderThread=new ViewHolderThread();
holderThread.count=(TextView)convertView.findViewById(R.id.count);
holderThread.title=(TextView)convertView.findViewById(R.id.title);
holderThread.layer=(TextView)convertView.findViewById(R.id.layer);
holderThread.authorName=(TextView)convertView.findViewById(R.id.authorName);
holderThread.ctime=(TextView)convertView.findViewById(R.id.ctime);
holderThread.content=(TextView)convertView.findViewById(R.id.content);
convertView.setTag(holderThread);
break;
case TYPE_2:
//如果是标签项
convertView = listlater.inflate(R.layout.commentcontentview , parent, false);
holderComment=new ViewHolderComment();
holderComment.count=(TextView)convertView.findViewById(R.id.count);
holderComment.layer=(TextView)convertView.findViewById(R.id.layer);
holderComment.authorName=(TextView)convertView.findViewById(R.id.authorName);
holderComment.ctime=(TextView)convertView.findViewById(R.id.ctime);
holderComment.content=(TextView)convertView.findViewById(R.id.content);
convertView.setTag(holderComment);
break;
} }
else
{
//有convertView,按样式,取得不用的布局
switch(type)
{
case TYPE_1:
holderThread = (ViewHolderThread) convertView.getTag();
break;
case TYPE_2:
holderComment = (ViewHolderComment) convertView.getTag();
break;
}
}
//设置资源
URLImageParser p;
Spanned htmlSpan;
CharSequence text;
String content=threadComment.getContent();
//替换内容中的换行,让手机显示的好看点
content=Util.reHtmlStyle(content);
switch(type)
{
case TYPE_1:
holderThread.count.setText("回复量/浏览量 "+threadComment.getRewardPionts()+"/"+threadComment.getJoins());
holderThread.title.setText(threadComment.getThreadTitle().trim());
holderThread.layer.setText(threadComment.getLayer());
holderThread.authorName.setText(threadComment.getAuthorName());
holderThread.ctime.setText(threadComment.getModifiedDate());
//异步加载图片
p = new URLImageParser(holderThread.content, context);
htmlSpan = Html.fromHtml(content, p, null);
holderThread.content.setText(htmlSpan); //设置连接点击事件
holderThread.content.setMovementMethod(LinkMovementMethod.getInstance());
text = holderThread.content.getText();
if (text instanceof Spannable)
{
int end = text.length();
Spannable sp = (Spannable) text;
URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
ImageSpan[] images=sp.getSpans(0, end, ImageSpan.class);
SpannableStringBuilder style = new SpannableStringBuilder(text);
style.clearSpans();// should clear old spans
for (URLSpan url : urls) {
MyURLSpan myURLSpan = new MyURLSpan(url.getURL(),context);
style.setSpan(myURLSpan, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
for (ImageSpan image : images) {
style.setSpan(image, sp.getSpanStart(image),
sp.getSpanEnd(image), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
holderThread.content.setText(style);
}
break;
case TYPE_2:
holderComment.count.setText("顶 ");
holderComment.layer.setText(threadComment.getLayer());
holderComment.authorName.setText(threadComment.getAuthorName());
holderComment.ctime.setText(threadComment.getModifiedDate());
//异步加载图片
p = new URLImageParser(holderComment.content, context);
htmlSpan = Html.fromHtml(content, p, null);
holderComment.content.setText(htmlSpan); //设置连接点击事件
holderComment.content.setMovementMethod(LinkMovementMethod.getInstance());
text = holderComment.content.getText();
if (text instanceof Spannable)
{
int end = text.length();
Spannable sp = (Spannable) text;
URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
ImageSpan[] images=sp.getSpans(0, end, ImageSpan.class);
SpannableStringBuilder style = new SpannableStringBuilder(text);
style.clearSpans();// should clear old spans
for (URLSpan url : urls) {
MyURLSpan myURLSpan = new MyURLSpan(url.getURL(),context);
style.setSpan(myURLSpan, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
for (ImageSpan image : images) {
style.setSpan(image, sp.getSpanStart(image),
sp.getSpanEnd(image), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
holderComment.content.setText(style);
}
break;
} return convertView;
}
private static class MyURLSpan extends ClickableSpan { private String mUrl;
private Context context; MyURLSpan(String url,Context context) {
mUrl = url;
this.context=context;
} @Override
public void onClick(View widget) {
//Toast.makeText(context, mUrl, Toast.LENGTH_LONG).show();
if(mUrl.indexOf(".jpg")!=-1 || mUrl.indexOf(".png")!=-1 || mUrl.indexOf(".gif")!=-1)
{
if(mUrl.indexOf("ppb")==-1)//表情图片
{
//查看大图
Intent intent = new Intent(context,PicActivity.class);
Bundle b=new Bundle();
b.putString("picUrl", mUrl);
intent.putExtras(b);
context.startActivity(intent);
}
}
else
{
Intent it = new Intent();
Uri u = Uri.parse(mUrl);
it.setData(u);
it.setAction( Intent.ACTION_VIEW);
it.setClassName("com.android.browser","com.android.browser.BrowserActivity");
context.startActivity(it);
}
}
}
static class ViewHolderThread {
TextView count;
TextView title;
TextView layer;
TextView authorName;
TextView ctime;
TextView content;
}
static class ViewHolderComment {
TextView count;
TextView layer;
TextView authorName;
TextView ctime;
TextView content;
}异步加载图片类 @Override
public Drawable getDrawable(String source) { int w=55;
int h=55;
//单独处理表情图片
String picName=source.substring(source.lastIndexOf("/")+1,source.lastIndexOf("."));
if(picName.length()==5 && picName.indexOf("ppb")!=-1)//表情图片
{
int picid = c.getResources().getIdentifier(picName,
"drawable", "com.china");
BitmapDrawable _BitmapDrawable = (BitmapDrawable) c.getResources().getDrawable(picid);
_BitmapDrawable.setBounds(0,0,w,h);
Constants.imageCache.put(source, new SoftReference<Drawable>(_BitmapDrawable));//缓存图片对象,为了以后清除
return _BitmapDrawable;
}
//分割问号后面的图片尺寸
String[] temp=source.split("[?]");
if(temp!=null && temp.length>1)
{
temp=temp[1].split("_");
w=Integer.parseInt(temp[0]);
h=Integer.parseInt(temp[1]);
//首先根据传过来的宽高。计算新的图片宽高
String new_wh=Util.reSizeImage(w,h,Constants.SCREENWDITH-Constants.IMAGELEFT*2,Constants.IMAGEHEIGHT);
temp=new_wh.split(",");
w=Integer.parseInt(temp[0]);
h=Integer.parseInt(temp[1]);
} //检查本地缓存
File file = new File(Constants.CACHEIMAGEPATH, picName+".png");
if (file.exists()) {
BitmapDrawable _BitmapDrawable = new BitmapDrawable(BitmapFactory.decodeFile(Constants.CACHEIMAGEPATH + picName+".png"));
_BitmapDrawable.setBounds(0,0,w,h);
Constants.imageCache.put(source, new SoftReference<Drawable>(_BitmapDrawable));//缓存图片对象,为了以后清除
return _BitmapDrawable;
}
//网络加载图片
URLDrawable urlDrawable = new URLDrawable();
urlDrawable.setBounds(0,0,w,h );
ImageGetterAsyncTask asyncTask = new ImageGetterAsyncTask(urlDrawable,w,h);
asyncTask.execute(source);
//添加 加载中 图片
BitmapDrawable _BitmapDrawable = (BitmapDrawable) c.getResources().getDrawable(R.drawable.loadpic);
_BitmapDrawable.setBounds(0,0,w,h);
urlDrawable.drawable=_BitmapDrawable;
return urlDrawable;
}
当页面关闭时,是不是清空所有图片就应该可以了?还有listview item中的那些对象怎么处理,还是系统自动就处理了???
看代码
帖子页 activity,销毁的时候清空了此页加载的所有图片对象
/**
* 销毁bitmap内存。否则大图容易内存耗尽
*/
protected void onDestroy()
{
//如果过大清空,避免内存不够用
Iterator it = com.china.util.Constants.imageCache.entrySet().iterator();
while (it.hasNext())
{
Map.Entry entry = (Map.Entry) it.next();
SoftReference<Drawable> softReference = (SoftReference<Drawable>)entry.getValue();
Drawable value = softReference.get();
if(value!=null)
value.setCallback(null);
}
super.onDestroy();
}
adaper的代码片段
@Override
public View getView(int position,View convertView,ViewGroup parent){
ViewHolderThread holderThread=null;
ViewHolderComment holderComment=null;
int type = getItemViewType(position);
//根据标签类型加载不通的布局模板
ThreadComment threadComment=(ThreadComment)getItem(position);
if(convertView==null)
{
switch(type)
{
case TYPE_1:
//主贴
convertView = listlater.inflate(R.layout.threadcontentview , parent, false);
holderThread=new ViewHolderThread();
holderThread.count=(TextView)convertView.findViewById(R.id.count);
holderThread.title=(TextView)convertView.findViewById(R.id.title);
holderThread.layer=(TextView)convertView.findViewById(R.id.layer);
holderThread.authorName=(TextView)convertView.findViewById(R.id.authorName);
holderThread.ctime=(TextView)convertView.findViewById(R.id.ctime);
holderThread.content=(TextView)convertView.findViewById(R.id.content);
convertView.setTag(holderThread);
break;
case TYPE_2:
//如果是标签项
convertView = listlater.inflate(R.layout.commentcontentview , parent, false);
holderComment=new ViewHolderComment();
holderComment.count=(TextView)convertView.findViewById(R.id.count);
holderComment.layer=(TextView)convertView.findViewById(R.id.layer);
holderComment.authorName=(TextView)convertView.findViewById(R.id.authorName);
holderComment.ctime=(TextView)convertView.findViewById(R.id.ctime);
holderComment.content=(TextView)convertView.findViewById(R.id.content);
convertView.setTag(holderComment);
break;
} }
else
{
//有convertView,按样式,取得不用的布局
switch(type)
{
case TYPE_1:
holderThread = (ViewHolderThread) convertView.getTag();
break;
case TYPE_2:
holderComment = (ViewHolderComment) convertView.getTag();
break;
}
}
//设置资源
URLImageParser p;
Spanned htmlSpan;
CharSequence text;
String content=threadComment.getContent();
//替换内容中的换行,让手机显示的好看点
content=Util.reHtmlStyle(content);
switch(type)
{
case TYPE_1:
holderThread.count.setText("回复量/浏览量 "+threadComment.getRewardPionts()+"/"+threadComment.getJoins());
holderThread.title.setText(threadComment.getThreadTitle().trim());
holderThread.layer.setText(threadComment.getLayer());
holderThread.authorName.setText(threadComment.getAuthorName());
holderThread.ctime.setText(threadComment.getModifiedDate());
//异步加载图片
p = new URLImageParser(holderThread.content, context);
htmlSpan = Html.fromHtml(content, p, null);
holderThread.content.setText(htmlSpan); //设置连接点击事件
holderThread.content.setMovementMethod(LinkMovementMethod.getInstance());
text = holderThread.content.getText();
if (text instanceof Spannable)
{
int end = text.length();
Spannable sp = (Spannable) text;
URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
ImageSpan[] images=sp.getSpans(0, end, ImageSpan.class);
SpannableStringBuilder style = new SpannableStringBuilder(text);
style.clearSpans();// should clear old spans
for (URLSpan url : urls) {
MyURLSpan myURLSpan = new MyURLSpan(url.getURL(),context);
style.setSpan(myURLSpan, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
for (ImageSpan image : images) {
style.setSpan(image, sp.getSpanStart(image),
sp.getSpanEnd(image), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
holderThread.content.setText(style);
}
break;
case TYPE_2:
holderComment.count.setText("顶 ");
holderComment.layer.setText(threadComment.getLayer());
holderComment.authorName.setText(threadComment.getAuthorName());
holderComment.ctime.setText(threadComment.getModifiedDate());
//异步加载图片
p = new URLImageParser(holderComment.content, context);
htmlSpan = Html.fromHtml(content, p, null);
holderComment.content.setText(htmlSpan); //设置连接点击事件
holderComment.content.setMovementMethod(LinkMovementMethod.getInstance());
text = holderComment.content.getText();
if (text instanceof Spannable)
{
int end = text.length();
Spannable sp = (Spannable) text;
URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
ImageSpan[] images=sp.getSpans(0, end, ImageSpan.class);
SpannableStringBuilder style = new SpannableStringBuilder(text);
style.clearSpans();// should clear old spans
for (URLSpan url : urls) {
MyURLSpan myURLSpan = new MyURLSpan(url.getURL(),context);
style.setSpan(myURLSpan, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
for (ImageSpan image : images) {
style.setSpan(image, sp.getSpanStart(image),
sp.getSpanEnd(image), Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
holderComment.content.setText(style);
}
break;
} return convertView;
}
private static class MyURLSpan extends ClickableSpan { private String mUrl;
private Context context; MyURLSpan(String url,Context context) {
mUrl = url;
this.context=context;
} @Override
public void onClick(View widget) {
//Toast.makeText(context, mUrl, Toast.LENGTH_LONG).show();
if(mUrl.indexOf(".jpg")!=-1 || mUrl.indexOf(".png")!=-1 || mUrl.indexOf(".gif")!=-1)
{
if(mUrl.indexOf("ppb")==-1)//表情图片
{
//查看大图
Intent intent = new Intent(context,PicActivity.class);
Bundle b=new Bundle();
b.putString("picUrl", mUrl);
intent.putExtras(b);
context.startActivity(intent);
}
}
else
{
Intent it = new Intent();
Uri u = Uri.parse(mUrl);
it.setData(u);
it.setAction( Intent.ACTION_VIEW);
it.setClassName("com.android.browser","com.android.browser.BrowserActivity");
context.startActivity(it);
}
}
}
static class ViewHolderThread {
TextView count;
TextView title;
TextView layer;
TextView authorName;
TextView ctime;
TextView content;
}
static class ViewHolderComment {
TextView count;
TextView layer;
TextView authorName;
TextView ctime;
TextView content;
}异步加载图片类 @Override
public Drawable getDrawable(String source) { int w=55;
int h=55;
//单独处理表情图片
String picName=source.substring(source.lastIndexOf("/")+1,source.lastIndexOf("."));
if(picName.length()==5 && picName.indexOf("ppb")!=-1)//表情图片
{
int picid = c.getResources().getIdentifier(picName,
"drawable", "com.china");
BitmapDrawable _BitmapDrawable = (BitmapDrawable) c.getResources().getDrawable(picid);
_BitmapDrawable.setBounds(0,0,w,h);
Constants.imageCache.put(source, new SoftReference<Drawable>(_BitmapDrawable));//缓存图片对象,为了以后清除
return _BitmapDrawable;
}
//分割问号后面的图片尺寸
String[] temp=source.split("[?]");
if(temp!=null && temp.length>1)
{
temp=temp[1].split("_");
w=Integer.parseInt(temp[0]);
h=Integer.parseInt(temp[1]);
//首先根据传过来的宽高。计算新的图片宽高
String new_wh=Util.reSizeImage(w,h,Constants.SCREENWDITH-Constants.IMAGELEFT*2,Constants.IMAGEHEIGHT);
temp=new_wh.split(",");
w=Integer.parseInt(temp[0]);
h=Integer.parseInt(temp[1]);
} //检查本地缓存
File file = new File(Constants.CACHEIMAGEPATH, picName+".png");
if (file.exists()) {
BitmapDrawable _BitmapDrawable = new BitmapDrawable(BitmapFactory.decodeFile(Constants.CACHEIMAGEPATH + picName+".png"));
_BitmapDrawable.setBounds(0,0,w,h);
Constants.imageCache.put(source, new SoftReference<Drawable>(_BitmapDrawable));//缓存图片对象,为了以后清除
return _BitmapDrawable;
}
//网络加载图片
URLDrawable urlDrawable = new URLDrawable();
urlDrawable.setBounds(0,0,w,h );
ImageGetterAsyncTask asyncTask = new ImageGetterAsyncTask(urlDrawable,w,h);
asyncTask.execute(source);
//添加 加载中 图片
BitmapDrawable _BitmapDrawable = (BitmapDrawable) c.getResources().getDrawable(R.drawable.loadpic);
_BitmapDrawable.setBounds(0,0,w,h);
urlDrawable.drawable=_BitmapDrawable;
return urlDrawable;
}
当页面关闭时,是不是清空所有图片就应该可以了?还有listview item中的那些对象怎么处理,还是系统自动就处理了???
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货