什么是volley
volley是谷歌于2013推出的一款网络访问框架。具体怎样使用可以参考csdn其他博客教程,这里不重复造轮子
volley隐藏特性
1.默认自带缓存,缓存路径在-----'根目录/data/data/你的程序包名/cache/volley/'中
2.volley获取数据的途径是:检测内存,没有数据就访问硬盘缓存,再没有就访问网络重新获取数据
3.通过 queue.getCache().get(url)得到缓存对象,
4.通过queue.getCache().get(url).data得到缓存对象数据(url为你有网情况下访问数据的地址,volley会记录该值并在没网情况下通过该值得到缓存数据)
什么是universal image loader
universal image loader是一款热门的图片下载缓存框架
github下载地址:https://github.com/nostra13/Android-Universal-Image-Loader.git
你可以自定义image loader配置,也可以使用默认配置
注意点:编写一个类继承Application,需要在androidManifest.xml中配置application
<application android:name="Application" android:allowBackup="true" android:icon="@drawable/icon" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
这里我使用自定义配置,配置文件如下,根据实际情况,你可以修改
public class Application extends android.app.Application { @Override public void onCreate() { super.onCreate(); //创建默认的ImageLoader配置参数 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder( this) // 内存缓存文件最大质量 .memoryCacheExtraOptions(480, 800) // .discCacheExtraOptions(480,800,null) // 线程池内加载的数量 .threadPoolSize(3) .threadPriority(Thread.NORM_PRIORITY - 2) .denyCacheImageMultipleSizesInMemory() .memoryCache(new UsingFreqLimitedMemoryCache(3 * 1024 * 1024)) .memoryCacheSize(3 * 1024 * 1024)//内存缓存大小,这里为3M .discCacheSize(50 * 1024 * 1024)//硬盘缓存库大小,这里为50M .discCacheFileNameGenerator(new Md5FileNameGenerator()) .tasksProcessingOrder(QueueProcessingType.FIFO) .discCacheFileCount(100) .discCache( new UnlimitedDiscCache(new File(Environment .getExternalStorageDirectory() + "myApp/ImgCache")) ) .defaultDisplayImageOptions(getDisplayOptions()) .imageDownloader( new BaseImageDownloader(this, 5 * 1000, 30 * 1000) ) //下载 .writeDebugLogs() //写错误日志 .build();//开始构建 ImageLoader.getInstance().init(config);//使用自定义配置 } private DisplayImageOptions getDisplayOptions(){ DisplayImageOptions options; options=new DisplayImageOptions.Builder() .showImageOnLoading(R.mipmap.ic_launcher) .showImageForEmptyUri(R.mipmap.ic_launcher) .showImageOnFail(R.mipmap.ic_launcher) .cacheInMemory(true) .cacheOnDisc(true) .imageScaleType(ImageScaleType.EXACTLY) .bitmapConfig(Bitmap.Config.RGB_565) .resetViewBeforeLoading(true) .displayer(new RoundedBitmapDisplayer(20)) .displayer(new FadeInBitmapDisplayer(0)) .build(); return options; } }
在你的adapter或activity总实例化imageloader
ImageLoader imageLoader = ImageLoader.getInstance();//实例化使用loader.displayImage(url,view)实现显示图片//url为你的图片地址,view为你的imageview
好了,下面上volley网络请求源码,这里我把它封装在一个我项目的一个方法里面了
/** * @param url 请求数据的url */ private void requestData(final String url) { //网络请求不管怎么封装, 里面多数情况都使用子线程去执行。 final RequestQueue queue = Volley.newRequestQueue(context); StringRequest request = new StringRequest( url, new Response.Listener<String>() { //从发出请求,到成功返回数据, 需要经过3s钟,也就是3s了之后,才能执行onResponse @Override public void onResponse(String response) { try { response = new String(response.getBytes("ISO-8859-1"), "utf-8"); //关闭下拉刷洗头 swipeRefreshLayout.setRefreshing(false); Log.d("response-----", response); //1. 解析json数据 Gson gson = new Gson(); newlistBean = gson.fromJson(response, NewListBean.class); Log.d("title------", newlistBean.getData().getTopnews().get(0).getTitle()); //动态添加imageview setView(); //初始化圆点 initDot(); //进入轮播自动任务 autoLoader(); //5.表明是加载更多 if (isLoadMore) { adapter.addData(newlistBean.getData().getNews()); } else { adapter.setData(newlistBean.getData().getNews()); } //通知界面刷新 adapter.notifyDataSetChanged(); //6 关闭下拉刷新 closeRefresh(); //7. 关闭加载更多 closeLoadMore(); //swipeRefreshLayout.setRefreshing(false);//关闭刷新 } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }, //没网络是就从缓存中读取 new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) {//--------------------------这里是核心
if(queue.getCache().get(url)!=null){ String cachedResponse = new String(queue.getCache().get(url).data);
//--------------------------这里是核心
Log.d("cachejsons",cachedResponse); //1. 解析json数据 Gson gson = new Gson(); newlistBean = gson.fromJson(cachedResponse, NewListBean.class); Log.d("title------", newlistBean.getData().getTopnews().get(0).getTitle()); //动态添加imageview setView(); //初始化圆点 initDot(); //进入轮播自动任务 autoLoader(); //5.表明是加载更多 if (isLoadMore) { adapter.addData(newlistBean.getData().getNews()); } else { adapter.setData(newlistBean.getData().getNews()); } //通知界面刷新 adapter.notifyDataSetChanged(); } //6 关闭刷新 closeRefresh(); //7. 关闭加载更多 closeLoadMore(); Log.d("error----", error.toString()); } } ); queue.add(request); }下面是我adapter类中getview方法,核心代码在最后一段@Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHodler hodler=null; //可以使用viwGroup.getContext()获得上下文 if(view==null) { view = View.inflate(viewGroup.getContext(), R.layout.item_newslist, null); //使用viewhodler方式找到view hodler=new ViewHodler(); hodler.tvtitle=(TextView) view.findViewById(R.id.tv_title); hodler.tvtime=(TextView) view.findViewById(R.id.tv_time); hodler.ivicon=(ImageView) view.findViewById(R.id.iv_icon); view.setTag(hodler); }else { hodler= (ViewHodler) view.getTag(); } NewListBean.DataBean.NewsBean newsBean=mNews.get(i); hodler.tvtitle.setText(newsBean.getTitle()); hodler.tvtime.setText(newsBean.getPubdate()); // Picasso.with(viewGroup.getContext()).load(newsBean.getListimage()).into(hodler.ivicon); //使用三级缓存对图片数据进行缓存 mImageLoader.displayImage(newsBean.getListimage(),hodler.ivicon); return view; }总结:
利用框架能够轻松完成数据缓存和读取,总体实现逻辑就是从缓存中读出数据,把数据设置到适配器中,然后
显示数据,这里volley就是缓存数据的,imageloader就是根据传过来的url从硬盘或内存中读取照片并显示,附项目图