从服务端加载图片(ImageLoader+AsyncTask)

以上是效果图

————————————————

先看服务端代码

ShopInfo.java(只列出属性)

private int id;private String name;private String imagepath;private double price;ShopListServlet.javapackage 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": * ":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();// 为对象设置idinfo.setId(i + 1);String imageName = files[i].getName();// 为对象设置图片路径 :8090/Web_server/images/+imageNameinfo.setImagepath("" + 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=""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=""android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><ImageViewandroid:id="@+id/iv_item_main_icon"android:layout_width="80dp"android:layout_height="80dp"android:src="@drawable/ic_launcher" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid: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"/><TextViewandroid: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.javapackage 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;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获取数据loadData();}/** * 获取图片集合的方法 */private void loadData() {// 准备提交服务器的请求参数final String path = ":8090/Web_server/ShopListServlet";// 异步加载new AsyncTask<Void, Void, String>() {// 1、请求服务器资源之前先显示加载视图protected void onPreExecute() {//显示加载的进度条pd = ProgressDialog.show(MainActivity.this, null, "加载数据….");}// 2、从服务器获取图片集合@Overrideprotected 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.javapackage 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);}@Overridepublic int getCount() {return data.size();}@Overridepublic Object getItem(int position) {return data.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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.javapackage 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/ * :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>() {@Overrideprotected 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;}@Overrideprotected void onPostExecute(Bitmap bitmap) {String newPath = (String) imageView.getTag();if (bitmap != null && newPath == imagepath) {// 只有ImageView没有被复用才能显示imageView.setImageBitmap(bitmap);}}}.execute();}}

在乎的是沿途的风景以及看风景的心情,让心灵去旅行!

从服务端加载图片(ImageLoader+AsyncTask)

相关文章:

你感兴趣的文章:

标签云: