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

  • 关于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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值