博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 学习 豆瓣学习 sd卡缓存 内存缓存 下拉刷新 日志编辑等
阅读量:5161 次
发布时间:2019-06-13

本文共 10073 字,大约阅读时间需要 33 分钟。

这次老师讲解了两张调用你缓存的方法 我以前是实现现在图片再从本地读取图片

这样需要

数据流 - bitmap - 图片 - bitmap 

而老师的方式

数据流 -bitmap(已经显示在ui上) - 图片  显然 老师的方式更好

但是老师讲的内存缓存的方式 感觉一般,全写在activity感觉不是个好的方式 

另外,似乎本地缓存+内存缓存是更好一点的解决方案

在爱家项目中遇到的图片由于缓存不能更新的问题现在想到了解决方案:

图片更新后图片的网址会更新,我可能要md5(URL) 命名图片 如果图片更新那url变了 那我就重新下载图片

两种缓存代码

package cn.itcast.douban;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.lang.ref.SoftReference;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import com.google.gdata.data.Link;import com.google.gdata.data.douban.Attribute;import com.google.gdata.data.douban.CollectionEntry;import com.google.gdata.data.douban.CollectionFeed;import com.google.gdata.data.douban.Subject;import com.google.gdata.data.douban.SubjectEntry;import com.google.gdata.data.douban.UserEntry;import com.google.gdata.data.extensions.Rating;import com.google.gdata.util.ServiceException;import cn.itcast.douban.domain.Book;import cn.itcast.douban.util.LoadImageAsynTask;import cn.itcast.douban.util.LoadImageAsynTask.LoadImageAsynTaskCallback;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.net.Uri;import android.os.AsyncTask;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.AbsListView.OnScrollListener;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.AbsListView;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.ListView;import android.widget.RatingBar;import android.widget.RelativeLayout;import android.widget.TextView;public class MyReadActivity extends BaseActivity implements OnItemClickListener {	private ListView subjectlist;	MyReadAdapter adapter;	// Map
iconCache; Map
> iconCache; int startindex; // 开始获取内容的id int count; int max = 20; boolean isloading = false; IntentFilter filter; KillReceiver receiver ; @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.subject); super.onCreate(savedInstanceState); startindex = 1; count = 5; // 初始化内存缓存 iconCache = new HashMap
>(); } @Override public void setupView() { mRelativeLoading = (RelativeLayout) this.findViewById(R.id.loading); subjectlist = (ListView) this.findViewById(R.id.subjectlist); filter = new IntentFilter(); filter.addAction("kill_activity_action"); receiver = new KillReceiver(); this.registerReceiver(receiver, filter); } @Override public void setListener() { subjectlist.setOnItemClickListener(this); subjectlist.setOnScrollListener(new OnScrollListener() { public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { case OnScrollListener.SCROLL_STATE_IDLE: // 如果当前滚动状态为静止状态 // 并且listview里面最后一个用户可见的条目 内容 等于listview数据适配器里面的最后一个条目 // 获取listview中最后一个用户可见条目的位置 int positon = view.getLastVisiblePosition(); System.out.println("最后一个可见条目的位置 " + positon); int totalcount = adapter.getCount(); System.out.println("listview 条目的数目 " + totalcount); if (positon == (totalcount - 1)) {// 代表当前界面拖动到了最下方 // 获取更多的数据 startindex = startindex + count; if (startindex > max) { showToast("数据已经加载到最大条目"); return; } if (isloading) { return; } fillData(); } break; } } public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } @Override public void fillData() { // 通过异步任务 获取数据 然后显示到界面上 new AsyncTask
>() { @Override protected void onPreExecute() { showLoading(); isloading = true; super.onPreExecute(); } @Override protected void onPostExecute(List
result) { hideLoading(); super.onPostExecute(result); if (result != null) { if (adapter == null) { adapter = new MyReadAdapter(result); subjectlist.setAdapter(adapter); } else { // 把新获取到的数据 加到listview的数据适配器里面 // 通知界面更新内容 adapter.addMoreBook(result); // 通知数据适配器更新数据 adapter.notifyDataSetChanged(); } } else { showToast("获取数据失败"); } isloading = false; } @Override protected List
doInBackground(Void... params) { try { UserEntry ue = myService.getAuthorizedUser(); String uid = ue.getUid(); // 首先获取用户的 所有收集的信息 CollectionFeed feeds = myService.getUserCollections(uid, "book", null, null, startindex, count); List
books = new ArrayList
(); for (CollectionEntry ce : feeds.getEntries()) { Subject se = ce.getSubjectEntry(); if (se != null) { Book book = new Book(); String title = se.getTitle().getPlainText(); book.setName(title); StringBuilder sb = new StringBuilder(); for (Attribute attr : se.getAttributes()) { if ("author".equals(attr.getName())) { sb.append(attr.getContent()); sb.append("/"); } else if ("publisher".equals(attr.getName())) { sb.append(attr.getContent()); sb.append("/"); } else if ("pubdate".equals(attr.getName())) { sb.append(attr.getContent()); sb.append("/"); } else if ("isbn10".equals(attr.getName())) { sb.append(attr.getContent()); sb.append("/"); } } book.setDescription(sb.toString()); Rating rating = se.getRating(); if (rating != null) { book.setRating(rating.getAverage()); } for (Link link : se.getLinks()) { if ("image".equals(link.getRel())) { book.setBookurl(link.getHref()); } } books.add(book); } } return books; } catch (Exception e) { e.printStackTrace(); return null; } } }.execute(); } //点击某个条目对应的点击事件 public void onItemClick(AdapterView
parent, View view, int position, long id) { Book book =(Book) subjectlist.getItemAtPosition(position); String description = book.getDescription(); int end = description.indexOf("/"); String isbn = description.substring(0, end); Intent intent = new Intent(this,BookDetailActivity.class); intent.putExtra("isbn", isbn); startActivity(intent); } private class MyReadAdapter extends BaseAdapter { private List
books; public MyReadAdapter(List
books) { this.books = books; } public void addMoreBook(List
books) { for (Book book : books) { this.books.add(book); } } public int getCount() { return books.size(); } public Object getItem(int position) { // TODO Auto-generated method stub return books.get(position); } public long getItemId(int position) { // TODO Auto-generated method stub return position; } public View getView(int position, View convertView, ViewGroup parent) { View view = View.inflate(MyReadActivity.this, R.layout.book_item, null); final ImageView iv_book = (ImageView) view .findViewById(R.id.book_img); RatingBar rb = (RatingBar) view.findViewById(R.id.ratingbar); TextView tv_title = (TextView) view.findViewById(R.id.book_title); TextView tv_description = (TextView) view .findViewById(R.id.book_description); Book book = books.get(position); if (book.getRating() != 0) { rb.setRating(book.getRating()); } else { rb.setVisibility(View.INVISIBLE); } tv_description.setText(book.getDescription()); tv_title.setText(book.getName()); // 判断 图片是否在sd卡上存在 String iconpath = book.getBookurl(); final String iconname = iconpath.substring( iconpath.lastIndexOf("/") + 1, iconpath.length()); /* * File file = new File("/sdcard/" + iconname); if (file.exists()) { * iv_book.setImageURI(Uri.fromFile(file)); * System.out.println("使用sd卡缓存"); } else { */ if (iconCache.containsKey(iconname)) { SoftReference
softref = iconCache.get(iconname); if (softref != null) { Bitmap bitmap = softref.get(); if (bitmap != null) { System.out.println("使用内存缓存 "); iv_book.setImageBitmap(bitmap); } else { loadimage(iv_book, book, iconname); } } } else { loadimage(iv_book, book, iconname); } return view; } private void loadimage(final ImageView iv_book, Book book, final String iconname) { LoadImageAsynTask task = new LoadImageAsynTask( new LoadImageAsynTaskCallback() { public void beforeLoadImage() { iv_book.setImageResource(R.drawable.book); } public void afterLoadImage(Bitmap bitmap) { if (bitmap != null) { System.out.println("下载服务器图片"); iv_book.setImageBitmap(bitmap); /* * // 把bitmap存放到sd卡上 try { File file = new * File("/sdcard/" + iconname); FileOutputStream * stream = new FileOutputStream( file); * bitmap.compress(CompressFormat.JPEG, 100, * stream); } catch (Exception e) { * e.printStackTrace(); } */ // 把图片存放到内存缓存里面 iconCache.put(iconname, new SoftReference
(bitmap)); } else { iv_book.setImageResource(R.drawable.book); } } }); task.execute(book.getBookurl()); } } private class KillReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { iconCache = null; showToast("内存不足activity退出"); finish(); } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); unregisterReceiver(receiver); } }
app中有个方法是关于oom错误的

@Override	public void onLowMemory() {		super.onLowMemory();				// 发送一些广播 关闭掉一些activity service 		Intent intent = new Intent();		intent.setAction("kill_activity_action");		sendBroadcast(intent);					}
在listview中有一个

subjectlist.setEmptyView(emptyView)//Sets the view to show if the adapter is empty

这样如果listview没有内容就会显示一个默认view 很重要

在代码中老师还讲了一下下拉刷新 他实现的很简单就是判断到底部了 直接加载

 但是很应用的整个设计却很协调,以后也可以参考这样设计

还要注意 如果数据已经没有了就不要加载了,这个需要在获取最后的数据后判断 大体上是加一个"锁"

在filldata()的时候也应该加一个锁来用户在加载数据的时候乱拖到造成listview的item错乱

// 如果当前滚动状态为静止状态					// 并且listview里面最后一个用户可见的条目 内容 等于listview数据适配器里面的最后一个条目					// 获取listview中最后一个用户可见条目的位置					int positon = view.getLastVisiblePosition();					System.out.println("最后一个可见条目的位置 " + positon);					int totalcount = adapter.getCount();					System.out.println("listview 条目的数目 " + totalcount);					if (positon == (totalcount - 1)) {// 代表当前界面拖动到了最下方						// 获取更多的数据						startindex = startindex + count;						if (startindex > max) {							showToast("数据已经加载到最大条目");							return;						}						if (isloading) {							return;						}						fillData();					}

转载于:https://www.cnblogs.com/sfshine/archive/2012/11/24/2807993.html

你可能感兴趣的文章
macOS安装mysql(顺便重置忘了的root密码)
查看>>
[LeetCode] 383. Ransom Note_Easy tag: Hash Table
查看>>
[SaSS] Using Object like style to create class dynamiclly
查看>>
[TypeStyle] Load raw CSS in TypeStyle
查看>>
[Node] Convert CommonJS Requires to ES6 Imports
查看>>
[Javascript] Task queue & Event loop.
查看>>
[RxJS] Creation operator: of()
查看>>
Python package和module
查看>>
JS 暴虐算法查找
查看>>
[学习笔记]数论(二)
查看>>
区间结构
查看>>
kendoTreeView,需要注意的地方
查看>>
nodejs文件操作模块FS(File System)常用函数简明总结(转)
查看>>
通过js实现在移动端浏览器启动微信
查看>>
网络基础 一
查看>>
Java分页需求
查看>>
输一个长方形
查看>>
(转)Emmet(Zen Coding)官方文档 之CSS语法
查看>>
PHP5.4 连接 SQL SERVER 2008
查看>>
Urozero Autumn 2016. NCPC 2016
查看>>