首页 > 代码库 > 这段代码哪里内存溢出了呢?

这段代码哪里内存溢出了呢?

原文出自:方杰|http://fangjie.sinaapp.com/?p=184 转载请注明出处

最终效果演示:http://fangjie.sinaapp.com/?page_id=54
该项目代码已经放到github:https://github.com/JayFang1993/SinaWeibo

一.首先是ListView的adapter。

因为微博列表的Item不是规则的,比如说有些微博有转发子微博,有些没有,有些有图片,有些没有图片,所以说很不固定。这里就采用BaseAdapter,要自己为微博Item设计一个WeiboAdapter.java

package com.fangjie.weibo.ui;

import java.util.Date;
import java.util.List;
import com.fangjie.weibo.R;
import com.fangjie.weibo.bean.Weibo;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.text.Html;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class WeiboAdapter extends BaseAdapter {

	private Context context;
	private List<Weibo> weibos;	

	public WeiboAdapter(Context context,List<Weibo> weibos) {
        System.out.println(weibos.get(1).content);
		this.context=context;
		this.weibos=weibos;
	}

	public int getCount() {
		return weibos.size();
	}

	public Object getItem(int position) {
		return null;
	}

	public long getItemId(int position) {
		return 0;
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		 //position代表位置  

        //通过View关联自定义Item布局,进行填充  

		 if(convertView == null)
         {
			 convertView = View.inflate(context, R.layout.wb_item, null);  
         }

        System.out.println(position);
        final Weibo weibo =weibos.get(position);

        //获取要显示的组件,注意findViewById的调用对象是上面填充了Item的布局的对象View  
        TextView tv_name = (TextView)convertView.findViewById(R.id.txt_wb_item_uname);  
        TextView tv_content = (TextView)convertView.findViewById(R.id.txt_wb_item_content);  
        TextView tv_time =(TextView)convertView.findViewById(R.id.txt_wb_item_time);  
        TextView tv_from =(TextView)convertView.findViewById(R.id.txt_wb_item_from);  
        TextView tv_comment =(TextView)convertView.findViewById(R.id.txt_wb_item_comment);  
        TextView tv_repost =(TextView)convertView.findViewById(R.id.txt_wb_item_redirect);  

        LinearLayout zlayout=(LinearLayout)convertView.findViewById(R.id.lyt_wb_item_sublayout);
        TextView tv_zcontent=(TextView)convertView.findViewById(R.id.txt_wb_item_subcontent); 

        final ImageView iv_userhead=(ImageView)convertView.findViewById(R.id.img_wb_item_head);
        ImageView iv_isv=(ImageView)convertView.findViewById(R.id.img_wb_item_V);
        ImageView iv_content_pic=(ImageView)convertView.findViewById(R.id.img_wb_item_content_pic);
        ImageView iv_zcontent_pic=(ImageView)convertView.findViewById(R.id.img_wb_item_content_subpic);

        //组件添加内容
        tv_content.setText(weibo.getContent());
        tv_name.setText(weibo.getUser().getName());
        tv_from.setText("来自:"+Html.fromHtml(weibo.getFrom()));
        tv_repost.setText(weibo.getReposts_count()+"");
        tv_comment.setText(weibo.getComments_count()+"");
        tv_time.setText(dealTime(weibo.getTime()));

        loadBitmap(weibo.getUser().getProfile_image_url(), iv_userhead,80,80);  

        if(!weibo.getBmiddle_pic().equals(""))
        {
            loadBitmap(weibo.getBmiddle_pic(), iv_content_pic,0,0);    
            iv_content_pic.setVisibility(View.VISIBLE);
        }
        else
        {
            iv_content_pic.setVisibility(View.GONE);        	
        }

        if(weibo.getUser().isIsv())
        	iv_isv.setVisibility(View.VISIBLE);
        else
        	iv_isv.setVisibility(View.GONE);

        if(weibo.getWeibo()!=null)
        {
        	zlayout.setVisibility(View.VISIBLE);
        	tv_zcontent.setText("@"+weibo.getWeibo().getUser().getName()+":"+weibo.getWeibo().getContent());
            if(!weibo.getWeibo().getBmiddle_pic().equals(""))
            {
                loadBitmap(weibo.getWeibo().getBmiddle_pic(), iv_zcontent_pic,0,0);    
                iv_zcontent_pic.setVisibility(View.VISIBLE);
            }
        }
        else
        	zlayout.setVisibility(View.GONE);

        return convertView;  
	}

	public void addItem(Weibo weibo)
	{
		weibos.add(weibo);
	}
}

微博Item的布局文件 wb_item.xml

<?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="wrap_content"
  android:background="@drawable/list_item">
	  <ImageView
	      android:id="@+id/img_wb_item_head"
		  android:layout_width="48dp"
		  android:layout_height="48dp"
		  android:src=http://www.mamicode.com/"@drawable/user_head">

WeiboAdapter的作用就是将List<Weibo> weibos的数据绑定到每一个View的控件上去。注:关于图片ImagView控件的加载loadBitmap采用的是异步加载,在下一篇中会讲到。

二.ListView的细节——底部加载更多

首先需要为这个东西写一个布局文件 load_more.xml,布局很简单,就是一个button。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">
  <Button
   		android:id="@+id/loadMoreButton"
   		android:layout_width="fill_parent"
   		android:layout_height="wrap_content"
   		android:text="加载更多"
   		android:onClick="loadMore"/>
</LinearLayout>


然后在HomeActivity.java中为ListView增加一个底部视图,ListView.addFooterView(View view);

		//设置列表底部视图-加载更多
		View loadMoreView = getLayoutInflater().inflate(R.layout.load_more, null);  
		loadMoreButton= (Button) loadMoreView.findViewById(R.id.loadMoreButton);  
        weibolist.addFooterView(loadMoreView);


三.ListView的刷新按钮

在点击主界面的刷新按钮时,会出现progressbar,这些都不是很难。首先写好一个progress的布局,在刷新任务开始之前然progressbar显示,任务结束后就View.gone就OK啦,详细请看源代码HomeActivity.

四.注意:我在写ListView的时候,在模拟器测试完全OK,但是在真机上调试时,ListView与上面的TitleBar和TabHost交界处会有阴影。加上这句就可以了。

ListView.setFadingEdgeLength(0);

可能讲的不是很直观,最后附上HomeActivity.java的全部代码,这个就是Home界面的代码

package com.fangjie.weibo.ui;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fangjie.weibo.R;
import com.fangjie.weibo.bean.Task;
import com.fangjie.weibo.bean.Weibo;
import com.fangjie.weibo.logic.MainService;
import com.fangjie.weibo.util.SharePreferencesUtil;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class HomeActivity extends Activity implements IWeiboAcitivity {
	private ListView weibolist;
	private List<Weibo> weibos;
	private WeiboAdapter adapter;

	private TextView tv_title;
	private Button btn_refresh;
	private Button btn_update;

	private LinearLayout progress;

	private Button loadMoreButton;

	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.home);		
		init();
	}

	public void init() {
		weibolist=(ListView)findViewById(R.id.lv_weibos);
		tv_title=(TextView)findViewById(R.id.txt_wb_title);
		btn_refresh=(Button)findViewById(R.id.btn_refresh);
		btn_update=(Button)findViewById(R.id.btn_writer);
		progress=(LinearLayout)findViewById(R.id.layout_progress);

		//设置列表底部视图-加载更多
		View loadMoreView = getLayoutInflater().inflate(R.layout.load_more, null);  
		loadMoreButton= (Button) loadMoreView.findViewById(R.id.loadMoreButton);  
        weibolist.addFooterView(loadMoreView);   

        weibolist.setFadingEdgeLength(0);

		final String token=SharePreferencesUtil.getLoginUser(HomeActivity.this).getToken();
		tv_title.setText(SharePreferencesUtil.getLoginUser(HomeActivity.this).getUserName());

		Map<String,Object> params=new HashMap<String,Object>();
		params.put("token", token);
		Task task=new Task(Task.GET_WEIBOS, params);
		progress.setVisibility(View.VISIBLE);
		MainService.newTask(task);
		MainService.addActivty(HomeActivity.this);

		loadMoreButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Map<String,Object> params=new HashMap<String,Object>();
				params.put("token", token);
				params.put("max_id", weibos.get(weibos.size()-1).getWid());
				loadMoreButton.setText("正在加载,请稍候...");
				Task task=new Task(Task.LOADMORE, params);
				MainService.newTask(task);
				MainService.addActivty(HomeActivity.this);				
			}
		});

		btn_refresh.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Map<String,Object> params=new HashMap<String,Object>();
				params.put("token", token);
				progress.setVisibility(View.VISIBLE);
				Task task=new Task(Task.GET_WEIBOS, params);
				MainService.newTask(task);
				MainService.addActivty(HomeActivity.this);	
			}
		});

		btn_update.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Toast.makeText(HomeActivity.this, "亲,程序猿还没写好呢...", Toast.LENGTH_LONG).show();
			}
		});
	}

	@SuppressWarnings("unchecked")
	public void refresh(int taskID, Object... objects) {
		switch (taskID)
		{
			case Task.GET_WEIBOS:
				weibos=(List<Weibo>)objects[0];
				adapter=new WeiboAdapter(HomeActivity.this,weibos);
				weibolist.setAdapter(adapter);				
				break;
			case Task.LOADMORE:
				weibos=(List<Weibo>)objects[0];
				for(int i=1;i<weibos.size();i++)
					adapter.addItem(weibos.get(i));
				adapter.notifyDataSetChanged(); //数据集变化后,通知adapter 
				loadMoreButton.setText("加载更多");
		}
		progress.setVisibility(View.GONE);
		MainService.reMoveActivty(HomeActivity.this);
	}
}


 

可能大家在HomeActivity中只看到新开一些任务,但是这些任务具体做什么操纵不清楚,大家可以看看前面的博文,因为有一个 逻辑处理的MainService处理类。针对Task.GET_WEIBOS和Task.LOADMORE,其中的代码又增加了。这里也附上MainService.java关于这两个任务的部分代码。

			//刷新微博
			case Task.GET_WEIBOS:
			{
				String token=(String)task.getParams().get("token");
				WeiboUtil weiboutil=new WeiboUtil();
				List<Weibo> weibos=weiboutil.getWeiboList(token,0);
				msg.obj=weibos;
				break;
			}
			//加载更多
			case Task.LOADMORE:
			{
				String token=(String)task.getParams().get("token");
				long max_id=(Long) task.getParams().get("max_id");
				WeiboUtil weiboutil=new WeiboUtil();
				List<Weibo> weibos=weiboutil.getWeiboList(token,max_id);
				msg.obj=weibos;
				break;
			}


 欢迎各位关注我的个人站点:http://fangjie.sinaapp.com/