小小千想和您聊一聊

当前位置: 首页> 技术分享> 移动APP测试-ListView优化之内存缓存

移动APP测试-ListView优化之内存缓存

  内存缓存:

  内存优化是将获取到的数据存入到Map集合中,如果再次引用此数据,就直接从Map集合中获取,这样会导致一个问题,如果Map集合中的数据特别多,比如存 取了100万条数据,这样有可能就会导致内存溢出。这是因为Map集合是强引用的集合,如何不把Map集合置为空的话,这个集合Java虚拟机就不会把它 回收掉,当Map中的数据大小超过了内存大小就会导致内存溢出。为了避免这种异常我们要使用软引用softreference,软引用和强引用的区别如 下:

  1、softreference 他是java虚拟机给我们提供的一个包装类型。

  在包装类型里面的对象,一般情况下,java虚拟机会尽量长时间的保留这个对象。

  当java虚拟机内存不足的时候,java虚拟机就会回收softreference里面的对象。

  2、hardreference 默认new出来的对象都是这种强应用的类型。

  只要一个对象还保留的有引用,他就不会被垃圾回收。

  Map map;

  sd卡缓存:

public class MyReadAdapter extends BaseAdapter {
    private List<CollectionEntry> entrys;
 
    public MyReadAdapter(CollectionFeed feeds) {
        entrys = feeds.getEntries();
    }
 public int getCount() {
        return entrys.size();
    }
 
    public Object getItem(int position) {
        return entrys.get(position);
    }
 
    public long getItemId(int position) {
        return position;
    }
public View getView(int position, View convertView, ViewGroup parent) {
        View view = infalter.inflate(R.layout.myread_item, null);
        final ImageView iv = (ImageView) view.findViewById(R.id.book_img);
 
        // 获取数据实体
        CollectionEntry ce = entrys.get(position);
        // 获取图片地址
        String iconurl = ce.getSubjectEntry().getLink("image", null).getHref();
        int start = iconurl.lastIndexOf("/");
        int end = iconurl.length();
        final String iconname = iconurl.substring(start, end);
        // Environment.getExternalStorageDirectory()这个是sd卡目录
        File file = new File(Environment.getExternalStorageDirectory(),
                iconname);
 
        // 获取sd卡缓存
        if (file.exists()) {
            iv.setImageURI(Uri.fromFile(file));
            Log.i(TAG, "使用sd卡图片");
        } else {
            new LoadImageAsynTask(new ImageTaskCallback() {
                // 图片获取之后
                public void onImageLoaded(Bitmap bitmap) {
                    if (bitmap != null) {
                        iv.setImageBitmap(bitmap);
 
                        // 把图片存到sd卡上
                        if (Environment.getExternalStorageState().equals(
                                Environment.MEDIA_MOUNTED)) {
                            try {
                                File file = new File(Environment
                                        .getExternalStorageDirectory(),
                                        iconname);
                                FileOutputStream fos = new FileOutputStream(
                                        file);
                                bitmap.compress(CompressFormat.JPEG, 100, fos);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    } else {
                        iv.setImageResource(R.drawable.book);
                    }
                }
 
                // 图片获取之前
                public void beforeImageLoaded() {
                    iv.setImageResource(R.drawable.book);
                }
            }).execute(iconurl);
        }
        return view;
    }
}
内存缓存:

Map<String,SoftReference<Bitmap>> map;
public class MyReadAdapter extends BaseAdapter {
    private List<CollectionEntry> entrys;
 
    public MyReadAdapter(CollectionFeed feeds) {
        entrys = feeds.getEntries();
    }
 
    public int getCount() {
        return entrys.size();
    }
 
    public Object getItem(int position) {
        return entrys.get(position);
    }
 
    public long getItemId(int position) {
        return position;
    }
 
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = infalter.inflate(R.layout.myread_item, null);
        final ImageView iv = (ImageView) view.findViewById(R.id.book_img);
        // 获取到数据的实体
        CollectionEntry ce = entrys.get(position);
        // 获取到图片的Url
        String iconurl = ce.getSubjectEntry().getLink("image", null).getHref();
        int start = iconurl.lastIndexOf("/");
        int end = iconurl.length();
        final String iconname = iconurl.substring(start, end);
 
        // 使用内存缓存
        if (map != null && map.get(iconname) != null) {
            iv.setImageBitmap(map.get(iconname).get());
            Log.i(TAG, "使用内存缓存");
        } else {
            new LoadImageAsynTask(new ImageTaskCallback() {
                // 图片获取之后
                public void onImageLoaded(Bitmap bitmap) {
                    if (bitmap != null) {
                        iv.setImageBitmap(bitmap);
 
                        // 存放到内存中,
                        // 软引用类型的bitmap
                        map.put(iconname, new SoftReference<Bitmap>(bitmap));
                    } else {
                        iv.setImageResource(R.drawable.book);
                    }
                }
 
                // 图片获取之前
                public void beforeImageLoaded() {
                    iv.setImageResource(R.drawable.book);
                }
            }).execute(iconurl);
        }
        return view;
    }
}
listview的延时加载: 

public class ListViewForLoading extends Activity implements OnScrollListener {

    private listViewAdapter adapter = new listViewAdapter();
    ListView listView;
    LinearLayout loadingLayout;
    private Thread mThread;
 /**
     * 设置布局显示属性
     */
    private LayoutParams mLayoutParams = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    /**
     * 设置布局显示目标最大化属性
     */
    private LayoutParams FFlayoutParams = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.FILL_PARENT,
            LinearLayout.LayoutParams.FILL_PARENT);
	private ProgressBar progressBar;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            switch (msg.what) {
            case 1:
                if (adapter.count <= 41) {
                    adapter.count += 10;
                    int currentPage = adapter.count / 10;
                    Toast.makeText(getApplicationContext(),"第" + currentPage + "页", Toast.LENGTH_LONG).show();
                } else {
                    listView.removeFooterView(loadingLayout);
                }
                //重新刷新Listview的adapter里面数据
                adapter.notifyDataSetChanged();
                break;
            default:
                break;
            }
        }

    };
 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        init();
    }

    private void init() {
        // TODO Auto-generated method stub
        // 线性布局
        LinearLayout layout = new LinearLayout(this);
        // 设置布局 水平方向
        layout.setOrientation(LinearLayout.HORIZONTAL);
        // 进度条
        progressBar = new ProgressBar(this);
        // 进度条显示位置
        progressBar.setPadding(0, 0, 15, 0);
        // 把进度条加入到layout中
        layout.addView(progressBar, mLayoutParams);
        // 文本内容
        TextView textView = new TextView(this);
        textView.setText("加载中...");
        textView.setGravity(Gravity.CENTER_VERTICAL);
        // 把文本加入到layout中
        layout.addView(textView, FFlayoutParams);
        // 设置layout的重力方向,即对齐方式是
        layout.setGravity(Gravity.CENTER);

        // 设置ListView的页脚layout
        loadingLayout = new LinearLayout(this);
        loadingLayout.addView(layout, mLayoutParams);
        loadingLayout.setGravity(Gravity.CENTER);

        // 得到一个ListView用来显示条目
        listView = (ListView) findViewById(R.id.tv);
        // 添加到脚页显示
        listView.addFooterView(loadingLayout);
        // 给ListView添加适配器
        listView.setAdapter(adapter);
        // 给ListView注册滚动监听
        listView.setOnScrollListener(this);
    }
 /**
     * 要用用于生成显示数据
     * 
     * @author huangbq
     * 
     */
    class listViewAdapter extends BaseAdapter {
        int count = 10;

        public int getCount() {
            return count;
        }

        public Object getItem(int pos) {
            return pos;
        }

        public long getItemId(int pos) {
            return pos;
        }

        public View getView(int pos, View v, ViewGroup p) {
            TextView view;
            if (v == null) {
                view = new TextView(ListViewForLoading.this);
            } else {
                view = (TextView) v;
            }
            view.setText("ListItem " + pos);
            view.setTextSize(20f);
            view.setGravity(Gravity.CENTER);
            view.setHeight(60);
            return view;
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        // TODO Auto-generated method stub
        if(firstVisibleItem+visibleItemCount==totalItemCount)
        {
            //开线程去下载网络数据
            if (mThread == null || !mThread.isAlive()) {
                mThread = new Thread() {
                    @Override
                    public void run() {
                        try {
                            //这里放你网络数据请求的方法,这里用线程休眠5秒方法来处理
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Message message = new Message();
                        message.what = 1;
                        handler.sendMessage(message);
                    }
                };
                mThread.start();                
            }
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // TODO Auto-generated method stub        
    } 
}

上一篇:HTML5工具初识之网页编辑器

下一篇:Linux学习思路(一)

QQ技术交流群

千锋软件测试官方①群
858327674

加入群聊