您的位置:首页 > 其它

从服务端加载图片(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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: