异步任务下载图片,通过自定义适配器显示在列表

1.设计

2.java代码

下载网络资源工具类

public class HttpUtils {

    // 获取网络上的json字符串
    // 输入String(url)
    // 返回String(jsonStr)
    public static String getHttpStr(String url) {
        HttpClient httpClient = new DefaultHttpClient(); // Http客户端
        HttpGet httpGet = new HttpGet(url); // GET请求
        try {
            HttpResponse response = httpClient.execute(httpGet); // 发起请求
            if(response.getStatusLine().getStatusCode() == 200) {
                // 200表示连接成功
                HttpEntity entity = response.getEntity(); // Http实体(有效信息)
                InputStream is = entity.getContent(); // 通过实体获取网络资源的内容(InputStream)
                //  开始下载数据
                ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 输出缓冲流(把全部的网络资源保存起来)
                byte[] buffer = new byte[1024]; // 缓冲区
                int ret;
                while(true) {
                    ret = is.read(buffer);
                    if(ret < 0) {
                        break;
                    }
                    baos.write(buffer, 0, buffer.length); // 每次把缓冲区的内容写入换冲流(缓冲区的内容每次都会不同)
                }
                return baos.toString(); // boas中的内容就是我们需要的数据了
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    // 获取网络上的图片
    // 输入String(url)
    // 返回Bitmap(图片)
    public static Bitmap getHttpBitmap(String url) {
        HttpClient httpClient = new DefaultHttpClient(); // Http客户端
        HttpGet httpGet = new HttpGet(url); // GET请求
        try {
            HttpResponse response = httpClient.execute(httpGet); // 发起请求
            if(response.getStatusLine().getStatusCode() == 200) {
                // 200表示连接成功
                HttpEntity entity = response.getEntity(); // Http实体(有效信息)
                InputStream is = entity.getContent(); // 通过实体获取网络资源的内容(InputStream)
                //  开始下载数据
                ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 输出缓冲流(把全部的网络资源保存起来)
                byte[] buffer = new byte[1024]; // 缓冲区
                int ret;
                while(true) { // 屌丝的代码 大神请忽略
                    ret = is.read(buffer);
                    if(ret < 0) {
                        break;
                    }
                    baos.write(buffer, 0, buffer.length); // 每次把缓冲区的内容写入换冲流(缓冲区的内容每次都会不同)
                }
                byte[] byteArr = baos.toByteArray(); // boas中的内容就是我们需要的数据了 先转换成字节数组
                // 把字节数组的内容转换成图片
                return BitmapFactory.decodeByteArray(byteArr, 0, byteArr.length);
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

解析JSON工具类

public class JSONUtils {
    
    // 格式为 
    // {"person":[{"address":"ServerForJSON/frjj.jpg","id":1001,"name":"Rose"},
    // {"address":"ServerForJSON/frjj2.jpg","id":1002,"name":"Jack"}]} 
    public static List<Person> parsePersonJSONStr(String jsonStr) {
        
        try {
            List<Person> list = new ArrayList<Person>();
            // 最外层的{}(JSONObject) 表示"所有人"
            JSONObject jsonObject = new JSONObject(jsonStr);
            // 根据key="person"获取value(JSONArray)
            JSONArray jsonArray = (JSONArray) jsonObject.get("person");
            // 遍历jsonArray中每一个人 (JSONObject)
            for(int i = 0; i < jsonArray.length(); i++) {
                // 获取每个人的json对象
                JSONObject jsonObject2 = (JSONObject) jsonArray.get(i);
                // 对于每一个人 分别获取address、id、name
                String address = (String) jsonObject2.get("address");
                int id = (Integer) jsonObject2.get("id");
                String name = (String) jsonObject2.get("name");
                // 通过地址下载并生成图片
                Bitmap bitmap = HttpUtils.getHttpBitmap(MainActivity.URL+address);
                // 生成Person的对象
                Person person = new Person(id, name, address, bitmap);
                list.add(person); // 添加到list列表中
            }
            return list; // 返回人的列表
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

自定义适配器

public class MyAdapter extends BaseAdapter {
    private List<Person> list;
    private Context context;
    // 通过构造器传递参数 List<Person>、Context
    public MyAdapter(List<Person> list, Context context) {
        this.list = list;
        this.context = context;
    }
    // 获取数据的大小数量(List<Person>)
    @Override
    public int getCount() {
        return list.size();
    }
    // 根据下标获取列表中具体的数据
    @Override
    public Object getItem(int position) {
        return list.get(position);
    }
    // 根据下标获取ID(下标)
    @Override
    public long getItemId(int position) {
        return position;
    }
    // 根据下标获取对应的视图
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = null;
        ViewHolder holder = null;
        if(convertView == null) {
            // 1. 首次加载时 没有缓冲的view 只能创建View
            LayoutInflater inflater = LayoutInflater.from(context);
            view = inflater.inflate(R.layout.item, null);
            // 2. 创建holder 并在view中查找holder中的视图(查找是很耗时间的)
            holder = new ViewHolder();
            holder.image = (ImageView) view.findViewById(R.id.image); // 图片
            holder.textview1 = (TextView) view.findViewById(R.id.textview1); // id
            holder.textview2 = (TextView) view.findViewById(R.id.textview2); // 姓名
            // 3. 绑定view和holder
            view.setTag(holder);
        } else {
            // 1. 后面加载时 已经有缓存的view 可复用
            view = convertView;
            // 2. 直接拿来使用
            holder = (ViewHolder) view.getTag();
        }
        // 4. 给image、textview1、textview2赋值
        Person person = list.get(position); // 具体的人
        Bitmap bitmap = person.getBitmap(); // 得到TA的图片
        holder.image.setImageBitmap(bitmap);
        int id = person.getId(); // 得到TA的id
        holder.textview1.setText(id+"");
        String name = person.getName(); // 得到TA的name
        holder.textview2.setText(name);
        // 5. 返回view
        return view;
    }
    // ViewHolder内部类 把视图包装在一起
    public class ViewHolder {
        public ImageView image;// 图片
        public TextView textview1; // id
        public TextView textview2; // 姓名
    }
}

异步任务类

public class MyTask extends AsyncTask<String, Void, List<Person>> {
    private Context context; // 上下文
    private ListView listview; // 列表视图
    // 通过构造器传递参数 context、listview
    public MyTask(Context context, ListView listview) {
        this.context = context;
        this.listview = listview;
    }

    // 执行下载、解析json字符串的功能(子线程)
    @Override
    protected List<Person> doInBackground(String... params) {
        String url = params[0]; // 获得输入的url
        // 通过url下载json字符串
        String jsonStr = HttpUtils.getHttpStr(url);
        // 通过json字符串获取人的列表
        List<Person> list = JSONUtils.parsePersonJSONStr(jsonStr);
        // 调试中……测试成功
        Log.i("MyTask", jsonStr);
        for(Person p : list) {
            Log.i("MyTask", p.toString());
        }
        return list;
    }

    // 执行后台操作前的准备步骤(主)(显示对话框)
    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
    }
    // 执行后台操作后的处理工作(主)(取消对话框、显示结果)
    @Override
    protected void onPostExecute(List<Person> result) {
        // 到这里才开始启动adapter
        // 因为到这里 才能真正得到数据
        MyAdapter adapter = new MyAdapter(result, context);
        listview.setAdapter(adapter); // 把数据设置到listview上
        super.onPostExecute(result);
    }

}

对象类

public class Person {
    private int id;
    private String name; // 姓名
    private String address; // 图片地址
    private Bitmap bitmap; // 图片
    // 构造器
    public Person() {}
    public Person(int id, String name, String address, Bitmap bitmap) {
        super();
        this.id = id;
        this.name = name;
        this.address = address;
        this.bitmap = bitmap;
    }
    // getter setter
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public Bitmap getBitmap() {
        return bitmap;
    }
    public void setBitmap(Bitmap bitmap) {
        this.bitmap = bitmap;
    }
    // toString
    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", address=" + address + ", bitmap=" + bitmap + "]";
    }
}

MainActivity类

public class MainActivity extends Activity {
    // 地址常量
    // 下载json字符串时使用:http://10.16.154.26:8080/ServerForJSON/JsonServlet
    //   URL+PATH
    // 下载图片时使用:http://10.16.154.26:8080/ServerForJSON/frjj.jpg
    //   URL+address
    public static final String URL = "http://10.16.154.26:8080/";
    public static final String PATH = "ServerForJSON/JsonServlet";
    private ListView listview;
    private ImageView imageview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 找出activity_main中的listview
        listview = (ListView) findViewById(R.id.listview);
        // 设置当listview中没有数据的时候 显示空白的图片
        imageview = (ImageView) findViewById(R.id.imageview);
        listview.setEmptyView(imageview);
        // 创建异步任务类并启动执行子线程
        MyTask task = new MyTask(MainActivity.this, listview);
        task.execute(URL+PATH);
    }
}

3.UML流程图

4.效果图

 

原文地址:https://www.cnblogs.com/anni-qianqian/p/5319343.html