AsyncTask异步加载

来源:互联网 发布:php yaf文档 编辑:程序博客网 时间:2024/06/06 20:22

item.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">     <ImageView         android:layout_height="60dp"        android:layout_width="60dp"        android:id="@+id/image"        android:background="@drawable/ic_launcher"/>    <TextView         android:layout_height="30dp"        android:layout_width="match_parent"        android:id="@+id/title"        android:layout_toRightOf="@+id/image"        android:gravity="center"        android:text="标题"        android:maxLines="1"        android:textSize="25sp"        />   <TextView         android:layout_height="30dp"        android:layout_width="match_parent"        android:id="@+id/content"        android:layout_below="@+id/title"        android:layout_toRightOf="@+id/image"        android:gravity="center"        android:text="内容"        android:maxLines="3"        /></RelativeLayout>

activity_main.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="match_parent"    android:orientation="vertical" >    <ListView         android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/lv">    </ListView></LinearLayout>

NewsBean.java
用于封装每一个列表项所对应的数据源信息

package com.example.newsasynctask;public class NewsBean {    public String newsIconURL;//图片网址    public String newsTitle;    public String newsContent;}

MainActivity.java
1.新建一个MyAsyncTAsk对象并给其传递一个uri
2.实现对url(网页)的异步访问

package com.example.newsasynctask;import java.io.BufferedReader;import java.net.URL;import java.io.InputStream;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.List;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.widget.ListView;public class MainActivity extends Activity {    //声明JsonString    final private String url="http://www.imooc.com/api/teacher?type=4&num=30";    private ListView lv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        lv=(ListView) findViewById(R.id.lv);        /*         * 1.新建一个MyAsyncTAsk对象并给其传递一个uri         */        new MyAsyncTask().execute(url);    }    /*     * 将 url对应的JSON格式数据转化为所封装的的NewsBean对象     */    private List<NewsBean>  getJsonData(String url){        List<NewsBean> newsBeanList=new ArrayList<>();//用于封装所有json格式的数据        try {            String JsonString=readStream(new URL(url).openStream());            JSONObject jsonObject;            NewsBean newsBean;//用于封装属性            try {                //将json格式的String转化为JSONObject                jsonObject = new JSONObject(JsonString);                //取出JSONArray:data                JSONArray jsonArray=jsonObject.getJSONArray("data");                //通过遍历JSONArray取出每一个JSONObject并取出对应的值                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.newsContent=jsonObject.getString("description");                    newsBeanList.add(newsBean);                }            } catch (JSONException e) {                e.printStackTrace();            }        } catch (Exception e) {            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);//将字符流以buffer的形式读取出来            while((line=br.readLine())!=null){                result+=line;            }        } catch (Exception e) {            e.printStackTrace();        }        return result;    }    /*     * 2.实现对url(网页)的异步访问     */    class MyAsyncTask extends AsyncTask<String,Void,List<NewsBean>>{        /*         * 3.将 url对应的JSONS格式数据转化为所封装的的NewsBean对象         */        @Override        protected List<NewsBean> doInBackground(String... params) {            return getJsonData(params[0]);        }        /*         * 4.将生成的NewsBean传递给NewsAdapter,通过NewsAdapter构造一个iew类型的数据源,并将该数据源传递给ListView          */        @Override        protected void onPostExecute(List<NewsBean> newsBeans) {//          super.onPostExecute(newsBeans);            NewsAdapter adapter=new NewsAdapter(MainActivity.this, newsBeans);            lv.setAdapter(adapter);        }    }}

NewsAdapter.java

package com.example.newsasynctask;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.webkit.WebView.FindListener;import android.widget.AbsListView;import android.widget.AbsListView.OnScrollListener;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;

1.初始化数据源:URLS,inflater

public class NewsAdapter extends BaseAdapter{   private List<NewsBean>list;   private LayoutInflater inflater;   private ImageLoader mImageLoader;   private int mStart,mEnd;   static String[] URLS;public NewsAdapter(Context context,List<NewsBean> list) {    this.list = list;    inflater=LayoutInflater.from(context);    //初始化一个ImageLoader而不是在getView方法中每次新建一个ImageLoader,来保证只有一个LruCache    mImageLoader=new ImageLoader();    //存储所有列表的图片网址    URLS=new String[list.size()];    for (int i = 0; i < list.size(); i++) {        URLS[i]=list.get(i).newsIconURL;    }}

2.将布局转化为view(利用了ListView的缓存机制,用ViewHolder将需要缓存的那些view封装好,用convertView的setTag将这些缓存起来供下次调用)

关于 ListView中convertView和ViewHolder的工作原理,见:
http://blog.csdn.net/bill_ming/article/details/8817172

@Overridepublic int getCount() {    return list.size();}@Overridepublic Object getItem(int position) {    return list.get(position);}@Overridepublic long getItemId(int position) {    return position;}@Overridepublic View getView(int position , View convertView, ViewGroup parent) {    ViewHolder viewHolder=null;    if (convertView==null) {        viewHolder=new ViewHolder();        convertView=inflater.inflate(R.layout.item, null);        //对viewHolder中的元素进行初始化        viewHolder.Icon=(ImageView) convertView.findViewById(R.id.image);        viewHolder.title=(TextView) convertView.findViewById(R.id.title);        viewHolder.content=(TextView) convertView.findViewById(R.id.content);        convertView.setTag(viewHolder);    }    else{        viewHolder=(ViewHolder) convertView.getTag();    }    String url=list.get(position).newsIconURL;    viewHolder.Icon.setTag(url);//将ImageView与对应的 url对应的图片进行了绑定    //使用AsyncTask实现异步加载    mImageLoader.showImageByAsyncTask(viewHolder.Icon, list.get(position).newsIconURL);    viewHolder.title.setText(list.get(position).newsTitle);    viewHolder.content.setText(list.get(position).newsContent);    return convertView;}   class ViewHolder{      public TextView title,content;      public ImageView Icon;   }}

ImageLoader.java

package com.example.newsasynctask;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;

1.创建Cache并初始化

/* * 非主线程不能在线程中直接更新UI,只能用UI进行线程的传递 */public class ImageLoader {    private ImageView mImageView;    private String mURL;    //创建Cache    /*     * 参数1:要保存对象的名字     * 参数2:要保存对象     */    private LruCache<String,Bitmap> mCache;    /*     * 构造方法,初始化LruCache,mList,mTask     */    public ImageLoader(){        //获取最大内存        int maxMemory=(int) Runtime.getRuntime().maxMemory();        //设定所需要的缓存的大小        int cacheSize=maxMemory/4;        mCache=new LruCache<String,Bitmap>(cacheSize){            //重写sizeOf()方法方法,用于获取正确的内存大小            @Override            protected int sizeOf(String key, Bitmap value) {                //在每次存入缓存的时候调用                return value.getByteCount();            }        };    }

addBitmapToCache:增加到缓存,在增加之前需要先校验一下当前缓存是否存在
getBitmapFromCache:从缓存中获取数据

/* *增加到缓存,在增加之前需要先校验一下当前缓存是否存在 */    public void addBitmapToCache(String url,Bitmap bitmap){        if(getBitmapFromCache(url)==null){            mCache.put(url, bitmap);        }    }    /*     * 从缓存中获取数据     */    //LruCache底层是由LinkedHashMap来实现的,所以其本质上相当于一个map,可以调用map的许多方法,如get(),put()    public Bitmap getBitmapFromCache(String url){        return  mCache.get(url);    }

showImageByAsyncTask:显示图片:从缓存中加载/下载图片

/* * 显示图片:从缓存中加载/下载图片 */public void showImageByAsyncTask(ImageView imageView,String url){    //从缓存中加载图片    Bitmap bitmap=getBitmapFromCache(url);    //如果缓存中没有,则必须下载    if(bitmap==null){        new NewsAsyncTask(imageView,url).execute(url);//      imageView.setImageResource(R.drawable.ic_launcher);    }    else{        imageView.setImageBitmap(bitmap);    }}

getBitmapfromURL:将url解析成Bitmap

/* * 将url解析成Bitmap */public Bitmap getBitmapfromURL(final String urlString) throws InterruptedException{    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();        Thread.sleep(1000);        return bitmap;    } catch (IOException e) {        e.printStackTrace();    }finally{            try {                if(is!=null)                is.close();            } catch (IOException e) {                e.printStackTrace();            }    }    return null;}

2.定义类NewsAsyncTask:从网络获取图片并加入缓存

/* * 从网络获取图片并加入缓存 */private class NewsAsyncTask extends AsyncTask<String,Void,Bitmap>{    private ImageView mImageView;    private String mURL;    public NewsAsyncTask(ImageView imageView,String url) {        mImageView=imageView;        mURL=url;    }    @Override    //异步任务    protected Bitmap doInBackground(String...params) {        try {            String url=params[0];            //从网络获取图片            Bitmap bitmap=getBitmapfromURL(url);            //将不在缓存的图片加入缓存            if (bitmap!=null) {                addBitmapToCache(url, bitmap);            }            return bitmap;        } catch (InterruptedException e) {            e.printStackTrace();        }        return null;    }/* * 为ImageView设置数据源 */   @Overrideprotected void onPostExecute(Bitmap bitmap) {    super.onPostExecute(bitmap);    if(mImageView.getTag()==null){//初始化时并未设置Tag         mImageView.setTag(mURL);    }else if(mImageView.getTag().equals(mURL)){//已经设置过Tag        mImageView.setImageBitmap(bitmap);    }}}}
0 0
原创粉丝点击