Android AsyncTask类的使用(二),加载ListView的Item的图片

来源:互联网 发布:甲骨文java认证 编辑:程序博客网 时间:2024/05/17 22:58
  • 关于AsyncTask,相信大家都不陌生。不过我倒是比较陌生,因为之前都没怎么用过这个类。今天看慕课视频,就写了一个Demo,用到了这个类,算是对AsyncTask的熟悉。
  • 之前一直觉得ImageLoader这种东西很高大上,都是在开源框架里面才见过这些类。
  • 不过今天看到慕课网关于AsyncTask的讲解的时候,顺便就写了一个ImageLoader,才明白ImageLoader大概是怎么一回事。
  • 慕课讲解链接: http://www.imooc.com/note/406 ;
  • 顺便放出我的Demo吧,很粗糙。但是也算是实现了功能,主要是对AsyncTask类的熟悉和加深。


  • 这是一个加载显示新闻条目的ListView的小Demo.因为是网络操作,所以需要添加网络访问权限:

<uses-permission android:name="android.permission.INTERNET" />

然后是xml,一个是Activity的xml布局,一个ListView的Item的xml布局。
1. activity的xml

<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=".MoocActivity" >    <ListView        android:id="@+id/listview"        android:layout_width="match_parent"        android:layout_height="match_parent" >    </ListView></RelativeLayout>
  1. 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:id="@+id/imageview"        android:layout_width="64dp"        android:layout_height="64dp"        android:contentDescription="@string/action_settings"        android:src="@drawable/ic_launcher" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_toRightOf="@id/imageview"        android:orientation="vertical"        android:paddingLeft="4dp" >        <TextView            android:id="@+id/tv_title"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:maxLines="1"            android:text="Title"            android:textSize="16sp" />        <TextView            android:id="@+id/tv_content"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:maxLines="3"            android:text="Content"            android:textSize="12sp" />    </LinearLayout></RelativeLayout>

然后是Activity的代码:

package com.duck.moocAsyncTask;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.URL;import java.net.URLConnection;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.widget.ListView;public class MoocActivity extends Activity {    private static final String URL = "http://www.imooc.com/api/teacher?type=4&num=30";    private ListView mListView;    private NewsAdapter adapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_mooc);        mListView = (ListView) findViewById(R.id.listview);        new NewsAsyncTask().execute(URL);    }    class NewsAsyncTask extends AsyncTask<String, Void, List<NewsBean>> {        private static final boolean DEBUG = false;        @Override        protected void onPostExecute(List<NewsBean> result) {            super.onPostExecute(result);            adapter = new NewsAdapter(result, MoocActivity.this);            mListView.setAdapter(adapter);        }        @Override        protected List<NewsBean> doInBackground(String... params) {            String url = params[0];            return getDatasFromUrl(url);        }        private List<NewsBean> getDatasFromUrl(String url) {            try {                URLConnection connection = new URL(url).openConnection();                InputStream is = connection.getInputStream();                String jsonString = getStringFromStream(is);                return getNewsFromJson(jsonString);            } catch (Exception e) {                e.printStackTrace();            }            return null;        }        private List<NewsBean> getNewsFromJson(String jsonString) {            List<NewsBean> newsBeanList = new ArrayList<NewsBean>();            try {                JSONObject jsonObject = new JSONObject(jsonString);                JSONArray jsonArray = jsonObject.getJSONArray("data");                for (int i = 0; i < jsonArray.length(); i++) {                    JSONObject object = jsonArray.getJSONObject(i);                    String url = object.getString("picSmall");                    String title = object.getString("name");                    String content = object.getString("description");                    NewsBean bean = new NewsBean();                    bean.iconUrl = url;                    bean.title = title;                    bean.content = content;                    newsBeanList.add(bean);                }            } catch (JSONException e) {                e.printStackTrace();            }            if (DEBUG) {                // 数据获取OK!                System.out.println("newsBeanList: " + newsBeanList);                System.out.println("\n \n newsBeanList.SIZE: "                        + newsBeanList.size());                System.out.println("\n \n newsBeanList.3: "                        + newsBeanList.get(3).title);            }            return newsBeanList;        }        private String getStringFromStream(InputStream is) {            String json = "";            BufferedReader br = new BufferedReader(new InputStreamReader(is));            String line;            try {                while ((line = br.readLine()) != null) {                    json += line;                }            } catch (IOException e) {                e.printStackTrace();            } finally {                try {                    br.close();                } catch (IOException e) {                    e.printStackTrace();                }                try {                    is.close();                } catch (IOException e) {                    e.printStackTrace();                }            }            return json;        }    }}

Activity里面有一个AsyncTask类,是获取网络数据json。只有加载一次即可。

然后是Adapter的代码,但是Adapter需要准备数据源,于是需要一个ImageLoader,又涉及到数据的封装,于是又有一个Bean类。
1.Bean代码:

package com.duck.moocAsyncTask;public class NewsBean {    public String iconUrl;    public String title;    public String content;}
  1. ImageLoader代码:
package com.duck.moocAsyncTask;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.net.URLConnection;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Handler;import android.os.Message;import android.widget.ImageView;public class ImageLoader {    private ImageView mImageView;    private String mUrl;    public ImageLoader(ImageView imageView, String url) {        mImageView = imageView;        mUrl = url;    }    private Handler handler = new Handler() {        public void handleMessage(android.os.Message msg) {            if (mImageView.getTag().equals(mUrl)) {                mImageView.setImageBitmap((Bitmap) msg.obj);            }        }    };    protected Bitmap getBitmapFromUrl(String urlString) {        URLConnection connection = null;        InputStream is = null;        try {            connection = new URL(urlString).openConnection();            is = connection.getInputStream();            Bitmap bitmap = BitmapFactory.decodeStream(is);            return bitmap;        } catch (Exception e) {            e.printStackTrace();        } finally {            try {                is.close();            } catch (IOException e) {                e.printStackTrace();            }        }        return null;    }    public void disPlayByThread(final String url) {        new Thread(new Runnable() {            @Override            public void run() {                Bitmap bitmap = getBitmapFromUrl(url);                Message message = Message.obtain();                message.obj = bitmap;                handler.sendMessage(message);            }        }).start();    }    public void disPlayByAsyncTask(ImageView imageView, String url) {        new LoadImageAsyncTask(imageView,url).execute(url);    }    class LoadImageAsyncTask extends AsyncTask<String, Void, Bitmap> {        private ImageView mImageView;        private String mUrl;        public LoadImageAsyncTask(ImageView imageView,String url) {            mImageView = imageView;            mUrl = url;        }        @Override        protected Bitmap doInBackground(String... params) {            String url = params[0];            Bitmap bitmap = getBitmapFromUrl(url);            return bitmap;        }        @Override        protected void onPostExecute(Bitmap result) {            super.onPostExecute(result);            if(mImageView.getTag().equals(mUrl)){                mImageView.setImageBitmap(result);            }        }    }}

ImageLoader里面也有一个AsyncTask类。这个AsyncTask是用来加载ListView的Item需要的图片的,所以会在Adapter的getView()方法里面被多次调用。

最后就是Adapter类:

package com.duck.moocAsyncTask;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;public class NewsAdapter extends BaseAdapter {    private List<NewsBean> mList;    private LayoutInflater mInflater;    public NewsAdapter(List<NewsBean> newsBeans, Context context) {        mList = newsBeans;        mInflater = LayoutInflater.from(context);    }    @Override    public int getCount() {        return mList.size();    }    @Override    public NewsBean getItem(int position) {        return mList.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder;        if (convertView == null) {            holder = new ViewHolder();            convertView = mInflater.inflate(R.layout.item, null);            holder.ivIcon = (ImageView) convertView                    .findViewById(R.id.imageview);            holder.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);            holder.tvContent = (TextView) convertView                    .findViewById(R.id.tv_content);            convertView.setTag(holder);        } else {            holder = (ViewHolder) convertView.getTag();        }        // show data        NewsBean bean = getItem(position);        holder.ivIcon.setImageResource(R.drawable.ic_launcher);        holder.ivIcon.setTag(bean.iconUrl);// 绑定tag        // new ImageLoader(holder.ivIcon, bean.iconUrl)        // .disPlayByThread(bean.iconUrl);        new ImageLoader(holder.ivIcon, bean.iconUrl).disPlayByAsyncTask(                holder.ivIcon, bean.iconUrl);        holder.tvTitle.setText(bean.title);        holder.tvContent.setText(bean.content);        return convertView;    }    class ViewHolder {        ImageView ivIcon;        TextView tvTitle;        TextView tvContent;    }}

Adapter就是一般的Adapter。在getView方法里面去调用ImageLoader去加载网络图片,其他的没有什么。

以上代码就是这个Demo的所有代码了。

为了方便以后使用。顺便传一个资源链接吧:
项目下载

0 0