您的位置:首页 > 理论基础 > 计算机网络

listview+BaseAdapter + AsyncTask异步请求网络 + LruCache缓存图片

2015-06-14 22:49 549 查看
1,通过异步加载,避免阻塞UI线程

2,通过LruCache,将已经下载的图片放到内存中

3,通过判断Listview滑动状态,决定何时加载图片

4,不仅仅是listview ,任何控件都可以使用异步加载

代码结构:

布局1,

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity" >

<ListView

android:id="@+id/lv_main"

android:layout_width="match_parent"

android:layout_height="match_parent"/>

</RelativeLayout>

布局2

<?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:padding="40dp"

android:orientation="horizontal" >

<ImageView

android:id="@+id/iv_icon"

android:layout_width="64dp"

android:layout_height="64dp"

android:src="@drawable/ic_launcher"/>

<LinearLayout

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingLeft="4dp"

android:orientation="vertical">

<TextView

android:id="@+id/tv_title"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:textSize="15sp"

android:maxLines="1"

android:text="title"/>

<TextView

android:id="@+id/tv_content"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:textSize="10sp"

android:maxLines="3"

android:text="content"/>

</LinearLayout>

</LinearLayout>

java代码:

package com.my.listviewbaseadapter;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.UnsupportedEncodingException;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.ArrayList;

import java.util.List;

import org.json.JSONArray;

import org.json.JSONException;

import org.json.JSONObject;

import android.os.AsyncTask;

import android.os.Bundle;

import android.app.Activity;

import android.util.Log;

import android.view.Menu;

import android.widget.ListView;

public class MainActivity extends Activity {

private ListView mListView;

private static String url = "http://www.**************************"; //一个含有图片,title,content三个内容的接口就行

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mListView = (ListView) findViewById(R.id.lv_main);

new NewsAsyncTask().execute(url);

}

/*

* 讲url对应的json格式数据转化为我们所封装的NewsBean对象

*/

private List<NewsBean> getJsonData(String url) {

List<NewsBean> newsBeanList = new ArrayList<NewsBean>();

try {

String jsonString = readStream(new URL(url).openStream());

JSONObject jsonObject;

NewsBean newsBean;

try {

jsonObject = new JSONObject(jsonString);

JSONArray jsonArray = jsonObject.getJSONArray("data");

for (int i = 0; i < jsonArray.length(); i++) {

jsonObject = jsonArray.getJSONObject(i);

newsBean = new NewsBean();

newsBean.newsIconUrl = jsonObject.getString("picSmall");

newsBean.newsTitle = jsonObject.getString("name");

newsBean.newsTitle = jsonObject.getString("description");

newsBeanList.add(newsBean);

}

} catch (Exception e) {

// TODO: handle exception

}

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return newsBeanList;

}

/*

* 通过InputStream解析网页返回的数据

*/

private String readStream(InputStream is) {

InputStreamReader isr;

String result = "";

try {

String line = "";

isr = new InputStreamReader(is, "utf-8");

BufferedReader br = new BufferedReader(isr);

while ((line = br.readLine()) != null) {

result += line;

}

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return result;

}

// AsyncTask<String, Void, Result>

/*

* 实现网络的异步访问

*

* AsyncTask<String, Void, Result>方法三个参数的含义 第一个参数String 是我们需要传入的url

* 第二个参数Void是记录中间的过程

* 第三个参数是我们返回的一个result,我们创建一个bean对象用于封装我们的json数据,最终返回的是Bean对象的集合

*/

class NewsAsyncTask extends AsyncTask<String, Void, List<NewsBean>> {

@Override

protected List<NewsBean> doInBackground(String... params) {

// TODO Auto-generated method stub

return getJsonData(params[0]);

}

@Override

protected void onPostExecute(List<NewsBean> newsBeans) {

// TODO Auto-generated method stub

super.onPostExecute(newsBeans);

NewsAdapter adapter = new NewsAdapter(MainActivity.this, newsBeans,mListView);

mListView.setAdapter(adapter);

}

}

}

package com.my.listviewbaseadapter;

import java.util.List;

import android.content.Context;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AbsListView;

import android.widget.AbsListView.OnScrollListener;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.ListView;

import android.widget.TextView;

public class NeAdapter extends BaseAdapter implements OnScrollListener{

private List<NewsBean> mList;

private LayoutInflater mInflater;

private ImageLoader mImageLoader;

private int mStart,mEnd;

public static String[] URLS;

private boolean mFirstIn;

public NewsAdapter(Context context, List<NewsBean> data,ListView listview) {

super();

mList = data;

mInflater = LayoutInflater.from(context);

mImageLoader = new ImageLoader(listview);

URLS = new String[data.size()];

for (int i = 0; i < data.size(); i++) {

URLS[i] = data.get(i).newsIconUrl;

}

mFirstIn =true;

// 一定要注册对应的事件

listview.setOnScrollListener(this);

}

@Override

public int getCount() {

// TODO Auto-generated method stub

return mList.size();

}

@Override

public Object getItem(int position) {

// TODO Auto-generated method stub

return mList.get(position);

}

@Override

public long getItemId(int position) {

// TODO Auto-generated method stub

return position;

}

class ViewHolder{

public ImageView ivIcon;

public TextView tvTitle,tvContent;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

// TODO Auto-generated method stub

ViewHolder viewHolder = null;

if (convertView == null) {

viewHolder = new ViewHolder();

convertView = mInflater.inflate(R.layout.item_layout, null);

viewHolder.ivIcon = (ImageView) convertView.findViewById(R.id.iv_icon);

viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);

viewHolder.tvContent = (TextView) convertView.findViewById(R.id.tv_content);

convertView.setTag(viewHolder);

}else {

viewHolder = (ViewHolder) convertView.getTag();

}

viewHolder.ivIcon.setImageResource(R.drawable.ic_launcher);

String url = mList.get(position).newsIconUrl;

viewHolder.ivIcon.setTag(url);

// new ImageLoader().showImageByThread(viewHolder.ivIcon, mList.get(position).newsIconUrl);

mImageLoader.showImageByAsyncTask(viewHolder.ivIcon, mList.get(position).newsIconUrl);

viewHolder.tvTitle.setText(mList.get(position).newsTitle);

viewHolder.tvContent.setText(mList.get(position).newsContent);

return convertView;

}

private ImageLoader mImageLoader() {

// TODO Auto-generated method stub

return null;

}

@Override

public void onScroll(AbsListView view, int firstVisibleItem,

int visibleItemCount, int totalItemCount) {

// TODO Auto-generated method stub

mStart = firstVisibleItem;

mEnd = firstVisibleItem + visibleItemCount;

// 第一次显示的时候调用

if (mFirstIn && visibleItemCount > 0) {

mImageLoader.loadImages(mStart, mEnd);

mFirstIn = false;

}

}

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

// TODO Auto-generated method stub

if (scrollState == SCROLL_STATE_IDLE) {

// 加载可见项

mImageLoader.loadImages(mStart, mEnd);

}else {

// 停止任务

mImageLoader.cancelAllTasks();

}

}

}

package com.my.listviewbaseadapter;

public class NeBean {

/*

* 封装我们需要的三个参数

* 1.iamge图片

* 2.title

* 3.content

* */

public String newsIconUrl;

public String newsTitle;

public String newsContent;

}

package com.my.listviewbaseadapter;

import java.io.BufferedInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.HashSet;

import java.util.Set;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.AsyncTask;

import android.os.Handler;

import android.os.Message;

import android.support.v4.util.LruCache;

import android.widget.ImageView;

import android.widget.ListView;

public class ImageLoader {

private ImageView mImageView;

private String mUrl;

// 创建cache

private LruCache<String, Bitmap> mCaches;

private ListView mListView;

private Set<NewsAsyncTask> mTask;

public ImageLoader(ListView listview){

mListView = listview;

mTask = new HashSet<ImageLoader.NewsAsyncTask>();

int maxMemorty = (int) Runtime.getRuntime().maxMemory();

int cacheSize = maxMemorty / 4;

mCaches = new LruCache<String, Bitmap>(cacheSize){

@Override

protected int sizeOf(String key, Bitmap value) {

// TODO Auto-generated method stub

// 每次存入缓存的时候调用

return value.getByteCount();

}

};

}

//增加到缓存

public void addBitmapToCache(String url,Bitmap bitmap){

if (getBitmapForURL(url) == null) {

mCaches.put(url, bitmap);

}

}

// 从缓存中获取数据

public Bitmap getBitmapFromCache(String url){

return mCaches.get(url);

}

private Handler mHandler = new Handler() {

public void handleMessage(Message msg) {

super.handleMessage(msg);

if (mImageView.getTag().equals(mUrl)){

mImageView.setImageBitmap((Bitmap)msg.obj);

}

}

};

public void showImageByThread(ImageView imageview, final String url) {

mImageView = imageview;

mUrl = url;

new Thread() {

@Override

public void run() {

// TODO Auto-generated method stub

super.run();

Bitmap bitmap = getBitmapForURL(url);

Message message = Message.obtain();

message.obj = bitmap;

mHandler.sendMessage(message);

}

}.start();

}

public Bitmap getBitmapForURL(String urlString) {

Bitmap bitmap;

InputStream is = null;

try {

URL url = new URL(urlString);

HttpURLConnection connection = (HttpURLConnection) url

.openConnection();

is = new BufferedInputStream(connection.getInputStream());

bitmap = BitmapFactory.decodeStream(is);

connection.disconnect();

return bitmap;

} catch (Exception e) {

// TODO: handle exception

} finally {

try {

is.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

return null;

}

public void showImageByAsyncTask(ImageView imageview, String url) {

// 从缓存中取出对应的图片

Bitmap bitmap = getBitmapFromCache(url);

// 如果缓存中没有,就必须到网络上获取图片

if (bitmap == null) {

imageview.setImageResource(R.drawable.ic_launcher);

}else {

imageview.setImageBitmap(bitmap);

}

}

public void cancelAllTasks(){

if (mTask != null) {

for (NewsAsyncTask task : mTask) {

task.cancel(false);

}

}

}

public void loadImages(int start,int end){

for (int i = start; i < end; i++) {

String url = NewsAdapter.URLS[i];

// 从缓存中取出对应的图片

Bitmap bitmap = getBitmapFromCache(url);

// 如果缓存中没有,就必须到网络上获取图片

if (bitmap == null) {

NewsAsyncTask task = new NewsAsyncTask(url);

task.execute(url);

mTask.add(task);

}else {

ImageView imageView = (ImageView) mListView.findViewWithTag(url);

}

}

}

private class NewsAsyncTask extends AsyncTask<String, Void, Bitmap> {

// private ImageView mImageView;

private String mUrl;

@SuppressWarnings("unused")

public NewsAsyncTask(String url) {

// mImageView = imageView;

mUrl = url;

}

@Override

protected Bitmap doInBackground(String... params) {

// TODO Auto-generated method stub

String url = params[0];

// 从网络获取图片

Bitmap bitmap = getBitmapForURL(params[0]);

if (bitmap != null) {

// 将不再缓存的图片加入缓存,从而实现缓存的效果

addBitmapToCache(url, bitmap);

}

return bitmap;

}

@Override

protected void onPostExecute(Bitmap bitmap) {

// TODO Auto-generated method stub

super.onPostExecute(bitmap);

// if (mImageView.getTag().equals(mUrl)) {

// mImageView.setImageBitmap(bitmap);

// }

ImageView imageView = (ImageView) mListView.findViewWithTag(mUrl);

if (imageView != null && bitmap != null) {

imageView.setImageBitmap(bitmap);

}

}

}

}

源码下载地址:http://download.csdn.net/detail/weimo1234/8806235
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: