zoukankan      html  css  js  c++  java
  • Android--多线程之图文混排

    前言

      本周一直在说Android多线程的那些事儿,本篇博客聊一聊Android开发中一个比较经典的案例,网络数据图文混排,本片博客的案例只涉及关于开启多线程访问网络数据,不涉及缓存的内容。众所周知,从网络上获取一段文本肯定要比获取一张张的图片要省时,所以一般如果是获取图片+文本的数据,会先开启一条线程获取文本数据,再从开启另外的线程来单独获取图片信息。本案例填充一个自定义的XML布局文件作为数据项,并使用ListView承载数据。

    数据准备

      本案例中的服务端数据以Json的形式传递,在服务端使用.Net开发一个一般处理程序,序列化一个产品对象,里面包含名称、价格、图片名称,最后序列化成JSON格式的数据返回给客户端。关于.Net下如何序列化一个对象成JSON格式,可以参见博客:C#--对象转Json序列化,这里不再累述,大家可以使用自己熟悉的服务端技术模拟JSON数据。

      获取JSON数据的一般处理程序地址:http://192.168.1.102:1231/json/returnCommondityJson.ashx,数据如下

    复制代码
    1 [{"imageName":"image1.png","name":"苹果","price":12},
    2 {"imageName":"image2.png","name":"闹钟","price":56},
    3 {"imageName":"image3.png","name":"蛋糕","price":24},
    4 {"imageName":"image4.png","name":"零钱包","price":8},
    5 {"imageName":"image5.png","name":"书本","price":42},
    6 {"imageName":"image6.png","name":"糖果","price":16},
    7 {"imageName":"image7.png","name":"西瓜","price":2}]
    复制代码

      本案例的URL地址均使用一个CommonUri类进行管理:

    复制代码
    1 package com.example.handlerimageortext;
    2 
    3 public class CommonUri {
    4     // 访问服务器数据的链接
    5     public static final String PRODUCT_URL = "http://192.168.1.102:1231/json/returnCommondityJson.ashx";
    6     // 图片的连接
    7     public static final String PRODUCT_IMG="http://192.168.1.102:1231/json/img/";
    8 }
    复制代码

      

    使用AsyncTask获取Json数据

      在UI线程中,使用AsyncTask的方式访问网络获取JSON数据,并对其进行解析,关于Android下JSON解析的内容可以参见博客:JSON解析。 

    复制代码
     1     public class MyTask extends AsyncTask<String, Void, List<Map<String,Object>>>{
     2         @Override
     3         protected void onPreExecute() {
     4             super.onPreExecute();
     5             // 显示对话框
     6             dialog.show();
     7         }
     8         
     9         @Override
    10         protected List<Map<String, Object>> doInBackground(String... params) {
    11             List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
    12             try {
    13                 // 获取网络JSON格式数据
    14                 HttpClient httpClient=new DefaultHttpClient();
    15                 HttpPost httpPost=new HttpPost(params[0]);
    16                 HttpResponse httpResponse=httpClient.execute(httpPost);
    17                 if(httpResponse.getStatusLine().getStatusCode()==200){
    18                     String jsonString=EntityUtils.toString(httpResponse.getEntity(),"utf-8");
    19                     // 解析Json格式数据,并使用一个List<Map>存放
    20                     JSONArray jsonArray=new JSONArray(jsonString);
    21                     for(int i=0;i<jsonArray.length();i++){
    22                         JSONObject jsonObject=jsonArray.getJSONObject(i);
    23                         Map<String,Object> map=new HashMap<String, Object>();
    24                         map.put("name",jsonObject.get("name"));
    25                         map.put("price",jsonObject.get("price"));
    26                         map.put("imageName",jsonObject.get("imageName"));
    27                         list.add(map);
    28                     }
    29                 }
    30             } catch (Exception e) {
    31                 e.printStackTrace();
    32             }
    33             return list;
    34         }
    35         @Override
    36         protected void onPostExecute(List<Map<String, Object>> result) {
    37             super.onPostExecute(result);
    38             // 把查询到的数据传递给适配器
    39             adapter.setData(result);
    40             // 为ListView设定适配器
    41             listview.setAdapter(adapter);
    42             adapter.notifyDataSetChanged();
    43             // 隐藏对话框
    44             dialog.dismiss();
    45         }        
    46     }
    复制代码

    下载图片信息

      上面的方法中,使用AsyncTask访问网络获取到产品的信息,其中有图片的名称,可以通过这个地址下载图片到本地。

      新创建一个类,用于下载图片,但是需要在主线程中访问图片的信息,可以使用接口回调的方式在Handler中处理子线程发送过来的消息。注释比较全,这里就不再累述了。

    复制代码
     1 package com.example.handlerimageortext;
     2 
     3 import java.io.IOException;
     4 import java.net.MalformedURLException;
     5 import java.net.URL;
     6 import android.graphics.drawable.Drawable;
     7 import android.os.Handler;
     8 import android.os.Message;
     9 
    10 public class DownLoadImage {
    11     private String image_path;
    12 
    13     public DownLoadImage(String image_path) {
    14         // 保存图片的下载地址
    15         this.image_path = image_path;
    16     }
    17 
    18     public void loadImage(final ImageCallback callback) {
    19         final Handler handler = new Handler() {
    20             @Override
    21             public void handleMessage(Message msg) {
    22                 super.handleMessage(msg);
    23                 // 接受到消息后,调用接口回调的方法
    24                 callback.getDrawable((Drawable) msg.obj);
    25             }
    26         };
    27         // 开启一个新线程用于访问图片数据
    28         new Thread(new Runnable() {
    29 
    30             @Override
    31             public void run() {
    32                 try {
    33                     // 下载图片为Drawable对象
    34                     Drawable drawable = Drawable.createFromStream(new URL(
    35                             image_path).openStream(), "");
    36                     // 把图片对象包装成一个消息发送给Handler
    37                     Message message = Message.obtain();
    38                     message.what = 1;
    39                     message.obj = drawable;
    40                     handler.sendMessage(message);
    41                 } catch (MalformedURLException e) {
    42                     e.printStackTrace();
    43                 } catch (IOException e) {
    44                     e.printStackTrace();
    45                 }
    46             }
    47         }).start();
    48     }
    49     
    50     // 定义一个公开的接口,用于执行回调操作
    51     public interface ImageCallback {
    52         public void getDrawable(Drawable draw);
    53     }
    54 }
    复制代码

    数据的适配器

      上面已经获取到Json数据中产品的数据,和产品的图片,现在声明一个Adapter类,继承自BaseAdapter,使用一个布局XML资源文件,用于填充数据。

    复制代码
     1     public class MyAdapter extends BaseAdapter{
     2         private Context context;
     3         private LayoutInflater layoutInflater;
     4         private List<Map<String,Object>> list=null;
     5         public MyAdapter(Context context){
     6             this.context=context;
     7             layoutInflater=LayoutInflater.from(context);            
     8         }
     9         
    10         public void setData(List<Map<String,Object>> list){
    11             this.list=list;
    12         }
    13         
    14         @Override
    15         public int getCount() {
    16             return list.size();
    17         }
    18 
    19         @Override
    20         public Object getItem(int position) {
    21             return list.get(position);
    22         }
    23 
    24         @Override
    25         public long getItemId(int position) {
    26             return position;
    27         }
    28 
    29         @Override
    30         public View getView(int position, View convertView, ViewGroup parent) {
    31             View view=null;
    32             if(convertView==null){
    33                 // 如果View为空,则以布局XML资源文件填充View
    34                 view=layoutInflater.inflate(R.layout.item,null);                
    35             }else{
    36                 view=convertView;
    37             }
    38             TextView name=(TextView)view.findViewById(R.id.textView1);
    39             TextView price=(TextView)view.findViewById(R.id.textView2);
    40             // 因为需要在回调接口中访问这个ImageView控件,所以需要声明为final
    41             final ImageView imageview=(ImageView)view.findViewById(R.id.imageView1);
    42             name.setText(list.get(position).get("name").toString());
    43             price.setText(list.get(position).get("price").toString());
    44             
    45             // 使用DownLoadImage,下载地址代表的图片
    46             DownLoadImage downLoadImage=new DownLoadImage(CommonUri.PRODUCT_IMG+list.get(position).get("imageName").toString());
    47             // 使用回调接口,设置ImageView的图片
    48             downLoadImage.loadImage(new ImageCallback() {                
    49                  @Override
    50                 public void getDrawable(Drawable draw) {
    51                     imageview.setImageDrawable(draw);
    52                 }
    53             });
    54             return view;
    55         }        
    56     }
    复制代码

      效果展示:

       源码下载

  • 相关阅读:
    redis常见面试题
    nginx常见的面试题
    python学习笔记(15)pymysql数据库操作
    python中的if not
    python学习笔记(24)-类与对象
    python学习笔记(23)-异常处理
    python学习笔记(22)-os文件操作模块
    Maven---pom.xml配置详解
    maven+jmeter+jenkins集成
    适配器模式
  • 原文地址:https://www.cnblogs.com/shitaotao/p/7635742.html
Copyright © 2011-2022 走看看