从服务端加载图片(ImageLoader+AsyncTask)
2015-03-03 22:51
134 查看
以上是效果图
------------------------------------------------
先看服务端代码
ShopInfo.java(只列出属性)
private int id; private String name; private String imagepath; private double price;ShopListServlet.java
package com.atguigu.web.servlet; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Random; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.atguigu.web.bean.ShopInfo; import com.google.gson.Gson; /** * 返回json格式的ShopList的Servlet */ public class ShopListServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<ShopInfo> list = getAllShops(request); String json = new Gson().toJson(list); System.out.println(json); response.setContentType("text/json;charset=utf-8"); response.getWriter().write(json); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } /** * 得到商家的集合 {"id":1,"name":"f1的商品名称","imagepath": * "http://127.0.0.1:8090/Web_server/images/f1.jpg","price":25.0} */ private List<ShopInfo> getAllShops(HttpServletRequest request) { List<ShopInfo> list = new ArrayList<ShopInfo>(); // 得到图片根目录的地址路径 String imagesPath = getServletContext().getRealPath("/images"); // 得到所有图片的file对象数组 File file = new File(imagesPath); File[] files = file.listFiles(); for (int i = 0; i < files.length; i++) { ShopInfo info = new ShopInfo(); // 为对象设置id info.setId(i + 1); String imageName = files[i].getName(); // 为对象设置图片路径 http://192.168.30.41:8090/Web_server/images/+imageName info.setImagepath("http://" + request.getLocalAddr() + ":" + request.getLocalPort() + request.getContextPath() + "/images/" + imageName); // 为对象设置名字 info.setName(imageName.substring(0, imageName.lastIndexOf(".")) + "的商品名称"); // 为对象设置价格 info.setPrice(new Random().nextInt(20) + 20); // 循环将对象加入到list集合中 list.add(info); } return list; } }
-------------------------------------------------我是分割线、下面是安卓端代码---------------------------------------
先上布局文件
activity_main.xml
<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" > </ListView>main_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:orientation="horizontal" > <ImageView android:id="@+id/iv_item_main_icon" android:layout_width="80dp" android:layout_height="80dp" android:src="@drawable/ic_launcher" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/tv_item_main_name" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:text="TextView" android:gravity="center_vertical"/> <TextView android:id="@+id/tv_item_main_price" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:text="TextView" android:gravity="center_vertical"/> </LinearLayout> </LinearLayout>
ShopInfo.java(只列出属性)
private int id; private String name; private String imagepath; private double price;
MainActivity.java
package com.example.msgproject; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import android.app.ListActivity; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.widget.Toast; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; public class MainActivity extends ListActivity { // 加载视图 private ProgressDialog pd; // 适配器 private MyAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取数据 loadData(); } /** * 获取图片集合的方法 */ private void loadData() { // 准备提交服务器的请求参数 final String path = "http://192.168.30.41:8090/Web_server/ShopListServlet"; // 异步加载 new AsyncTask<Void, Void, String>() { // 1、请求服务器资源之前先显示加载视图 protected void onPreExecute() { //显示加载的进度条 pd = ProgressDialog.show(MainActivity.this, null, "加载数据...."); } // 2、从服务器获取图片集合 @Override protected String doInBackground(Void... params) { String result = null; try { result = requestToString(path); } catch (Exception e) { e.printStackTrace(); } return result; } // 3、获取图片集合后,将图片设置到listView中 protected void onPostExecute(String result) { // 在设置之前先要取消掉 正在加载...视图 pd.dismiss(); if (result == null) { Toast.makeText(MainActivity.this, "获取数据出错!", 0).show(); } else { //创建对象list集合 List<ShopInfo> data = null;//[{id:1,name},{}] Gson gson = new Gson(); //将json对象数组转为对象list集合 data = gson.fromJson(result, new TypeToken<List<ShopInfo>>(){}.getType()); //测试信息 Log.e("TAG", data.size()+"__"+data.get(0)); //创建适配器 adapter = new MyAdapter(MainActivity.this, data); //设置适配器 setListAdapter(adapter); } } // 执行异步任务 }.execute(); } /** * 请求服务器端, 得到返回的结果字符串 */ public String requestToString(String path) throws Exception { URL url = new URL(path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); connection.setDoInput(true); connection.connect(); InputStream is = connection.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while ((len = is.read(buffer)) != -1) { baos.write(buffer, 0, len); } baos.close(); is.close(); String result = baos.toString(); connection.disconnect(); return result; } }
MyAdapter.java
package com.example.msgproject; import java.util.List; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class MyAdapter extends BaseAdapter { //图片加载器 private ImageLoader imageLoader; //需要传递过来的环境、从服务器请求的数据 private Context context; private List<ShopInfo> data; //通过构造方法的形式进行初始化 public MyAdapter(Context context, List<ShopInfo> data) { super(); this.context = context; this.data = data; //参数图片是一张默认的图片 imageLoader = new ImageLoader(context,R.drawable.shop_photo_frame); } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { //如果没有视图就动态加载视图对象 if (convertView == null) { convertView =View.inflate(context, R.layout.main_item, null); } //找出视图,设置数据 TextView nameTextView = (TextView) convertView.findViewById(R.id.tv_item_main_name); TextView priceTextView = (TextView) convertView.findViewById(R.id.tv_item_main_price); ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_item_main_icon); //得到当前数据 ShopInfo shopInfo = data.get(position); //将数据设置到对应的视图对象 nameTextView.setText(shopInfo.getName()); priceTextView.setText(shopInfo.getPrice()+"元"); //获取图片url地址信息 String imagePath = shopInfo.getImagepath(); //利用图片加载器进行图片的加载显示,每次得到一个view就会加载图片 imageLoader.loadImage(imagePath,imageView); return convertView; } }
ImageLoader.java
package com.example.msgproject; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.lang.ref.SoftReference; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.util.Log; import android.widget.ImageView; /** * 异步加载图片并显示 图片(Bitmap)缓存: 1. 在内存中缓存图片对应的bitmap对象 (一级缓存) 2. 将图片保存在手机内部或sd卡(二级缓存) * 3. 服务器端 */ public class ImageLoader { // 加载之间显示的默认图片 private int defaultBitmapId; private Context context; public ImageLoader(Context context, int defaultBitmapId) { this.defaultBitmapId = defaultBitmapId; this.context = context; } /** * 根据图片路径加载图片并显示 */ public void loadImage(String imagepath, ImageView imageView) { // 保存标记--用来判断是否是复用的图片 imageView.setTag(imagepath); // 从一级缓存中取bitmap对象 Bitmap bitmap = getFromFirstCache(imagepath); if (bitmap != null) { // 如果有, 直接显示 imageView.setImageBitmap(bitmap); return; } // 从二级缓存中取bitmap对象 bitmap = getFromSecondCache(imagepath); if (bitmap != null) { // 如果有, 直接显示 imageView.setImageBitmap(bitmap); return; } // 从服务器获取 // 显示默认图片 imageView.setImageResource(R.drawable.shop_photo_frame); loadImageFromNet(imagepath, imageView); } // 内存中缓存图片对象的集合-string是图片url地址信息 private Map<String, SoftReference<Bitmap>> cache = new HashMap<String, SoftReference<Bitmap>>(); /** * 从一级缓存中取bitmap对象-通过imagepath来取 */ private Bitmap getFromFirstCache(String imagepath) { Bitmap bitmap = null; SoftReference<Bitmap> softReference = cache.get(imagepath); //判断图片url地址信息,有没有对应的缓存图片 if (softReference != null) { bitmap = softReference.get(); //如果为null,说明被gc回收了 if (bitmap == null) { Log.e("TAG", "有图片被回收了..."); cache.remove(imagepath); } } return bitmap; } /** * 从二级缓存中取bitmap对象 图片缓存在: /data/data/packagename/cache/ * http://192.168.30.41:8090/Web_server/images/f1.jpg */ private Bitmap getFromSecondCache(String imagepath) { // 得到图片的本地路径 String filename = imagepath.substring(imagepath.lastIndexOf("/") + 1); File cacheFile = context.getCacheDir(); String filePath = cacheFile.getAbsolutePath() + "/" + filename; // /data/data/packagename/cache/f1.jpg // 加载图片文件, 得到bitmap对象 Bitmap bitmap = BitmapFactory.decodeFile(filePath); return bitmap; } /** * 从服务器端获取图片, 并显示 */ private void loadImageFromNet(final String imagepath, final ImageView imageView) { new AsyncTask<Void, Void, Bitmap>() { @Override protected Bitmap doInBackground(Void... params) { String newPath = (String) imageView.getTag(); if (newPath != imagepath)// 如果不相同, 说明imageView已经被复用, 不用加载服务器端的图片 return null; Bitmap bitmap = null; try { URL url = new URL(imagepath); HttpURLConnection connection = (HttpURLConnection) url .openConnection(); connection.setDoInput(true); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); connection.connect(); if (connection.getResponseCode() == 200) { InputStream is = connection.getInputStream(); // 图片流 //获取图片对象 bitmap = BitmapFactory.decodeStream(is); if (bitmap != null) { // 缓存到一级缓存中 cache.put(imagepath, new SoftReference<Bitmap>( bitmap)); // 缓存到二级缓存, 将bitmap保存为一张图片 String filename = imagepath.substring(imagepath .lastIndexOf("/") + 1); //获取存放的目录信息 File cacheFile = context.getCacheDir(); bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(new File(cacheFile, filename))); } } } catch (Exception e) { e.printStackTrace(); } return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) { String newPath = (String) imageView.getTag(); if (bitmap != null && newPath == imagepath) {// 只有ImageView没有被复用才能显示 imageView.setImageBitmap(bitmap); } } }.execute(); } }
相关文章推荐
- Android图片异步加载之Android-Universal-Image-Loader
- Android利用universal-image-loader异步加载大量图片完整示例
- android异步加载图片类(续)-universal-image-loader详解
- 图片异步加载框架 Android-Universal-Image-Loader
- [置顶] Android图片异步加载之Android-Universal-Image-Loader
- Android-Universal-Image-Loader 图片异步加载框架
- Android图片异步加载之Android-Universal-Image-Loader使用
- 使用ImageLoader+gallery加载图片导致图片哆嗦的问题解决办法
- Android-Universal-Image-Loader图片异步加载并缓存
- Android_开源框架_AndroidUniversalImageLoader网络图片加载
- 【移动开发】Android图片异步加载之Android-Universal-Image-Loader使用 推荐
- Android利用universal-image-loader异步加载大量图片完整示例
- IOS开发中图片加载类库的使用 EGOImageLoader,SDWebImage
- 图片加载框架---UniversalImageLoader使用(一)
- 图片加载框架---UniversalImageLoader使用(一)
- 图片异步加载框架 Android-Universal-Image-Loader
- Android-Universal-Image-Loader 异步加载图片
- Android-Universal-Image-Loader异步加载图片框架学习研究
- 图片异步加载框架 Android-Universal-Image-Loader
- 图片异步加载框架 Android-Universal-Image-Loader