前言

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

数据准备

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

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

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

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

 package com.example.handlerimageortext;

 public class CommonUri {
// 访问服务器数据的链接
public static final String PRODUCT_URL = "http://192.168.1.102:1231/json/returnCommondityJson.ashx";
// 图片的连接
public static final String PRODUCT_IMG="http://192.168.1.102:1231/json/img/";
}

  

使用AsyncTask获取Json数据

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

     public class MyTask extends AsyncTask<String, Void, List<Map<String,Object>>>{
@Override
protected void onPreExecute() {
super.onPreExecute();
// 显示对话框
dialog.show();
} @Override
protected List<Map<String, Object>> doInBackground(String... params) {
List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
try {
// 获取网络JSON格式数据
HttpClient httpClient=new DefaultHttpClient();
HttpPost httpPost=new HttpPost(params[0]);
HttpResponse httpResponse=httpClient.execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode()==200){
String jsonString=EntityUtils.toString(httpResponse.getEntity(),"utf-8");
// 解析Json格式数据,并使用一个List<Map>存放
JSONArray jsonArray=new JSONArray(jsonString);
for(int i=0;i<jsonArray.length();i++){
JSONObject jsonObject=jsonArray.getJSONObject(i);
Map<String,Object> map=new HashMap<String, Object>();
map.put("name",jsonObject.get("name"));
map.put("price",jsonObject.get("price"));
map.put("imageName",jsonObject.get("imageName"));
list.add(map);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
@Override
protected void onPostExecute(List<Map<String, Object>> result) {
super.onPostExecute(result);
// 把查询到的数据传递给适配器
adapter.setData(result);
// 为ListView设定适配器
listview.setAdapter(adapter);
adapter.notifyDataSetChanged();
// 隐藏对话框
dialog.dismiss();
}
}

下载图片信息

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

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

 package com.example.handlerimageortext;

 import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message; public class DownLoadImage {
private String image_path; public DownLoadImage(String image_path) {
// 保存图片的下载地址
this.image_path = image_path;
} public void loadImage(final ImageCallback callback) {
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// 接受到消息后,调用接口回调的方法
callback.getDrawable((Drawable) msg.obj);
}
};
// 开启一个新线程用于访问图片数据
new Thread(new Runnable() { @Override
public void run() {
try {
// 下载图片为Drawable对象
Drawable drawable = Drawable.createFromStream(new URL(
image_path).openStream(), "");
// 把图片对象包装成一个消息发送给Handler
Message message = Message.obtain();
message.what = 1;
message.obj = drawable;
handler.sendMessage(message);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} // 定义一个公开的接口,用于执行回调操作
public interface ImageCallback {
public void getDrawable(Drawable draw);
}
}

数据的适配器

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

     public class MyAdapter extends BaseAdapter{
private Context context;
private LayoutInflater layoutInflater;
private List<Map<String,Object>> list=null;
public MyAdapter(Context context){
this.context=context;
layoutInflater=LayoutInflater.from(context);
} public void setData(List<Map<String,Object>> list){
this.list=list;
} @Override
public int getCount() {
return list.size();
} @Override
public Object getItem(int position) {
return list.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
View view=null;
if(convertView==null){
// 如果View为空,则以布局XML资源文件填充View
view=layoutInflater.inflate(R.layout.item,null);
}else{
view=convertView;
}
TextView name=(TextView)view.findViewById(R.id.textView1);
TextView price=(TextView)view.findViewById(R.id.textView2);
// 因为需要在回调接口中访问这个ImageView控件,所以需要声明为final
final ImageView imageview=(ImageView)view.findViewById(R.id.imageView1);
name.setText(list.get(position).get("name").toString());
price.setText(list.get(position).get("price").toString()); // 使用DownLoadImage,下载地址代表的图片
DownLoadImage downLoadImage=new DownLoadImage(CommonUri.PRODUCT_IMG+list.get(position).get("imageName").toString());
// 使用回调接口,设置ImageView的图片
downLoadImage.loadImage(new ImageCallback() {
@Override
public void getDrawable(Drawable draw) {
imageview.setImageDrawable(draw);
}
});
return view;
}
}

  效果展示:

  源码下载

Android--多线程之图文混排的更多相关文章

  1. 使用android SpannableStringBuilder实现图文混排

    项目开发中需要实现这种效果 多余两行,两行最后是省略号,省略号后面是下拉更多 之前用过的是Html.fromHtml去处理图文混排的,仅仅是文字后图片或者文字颜色字体什么的, 但是这里需要在最后文字的 ...

  2. 使用android SpannableStringBuilder实现图文混排,看到许多其他

    项目开发需要达到这种效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmFuY3lsb3ZlamF2YQ==/font/5a6L5L2T/fontsiz ...

  3. Android TextView中图文混排设置行间距导致高度不一致问题解决

    最近项目中需要实现一个评论带表情的功能,刚开始一切顺利,非常easy,突然有一天发现文字跟表情混排的时候,TextView中图文高度不一致,excuse...什么鬼,之前明明测试过图文混排,不存在这个 ...

  4. android开发 自定义图文混排控件

    功能:图文混排,可自动缩放字体,如图: 单点触控使用的代码来自:http://blog.csdn.net/xiaanming/article/details/42833893  谢谢博主! 在该dem ...

  5. 【转】Android TextView SpannableStringBuilder 图文混排颜色斜体粗体下划线删除线

    spannableStringBuilder 用法详解: SpannableString ss = new SpannableString("红色打电话斜体删除线绿色下划线图片:." ...

  6. Android 自绘TextView解决提前换行问题,支持图文混排

    先看下效果图: 上面是MTextView,下面是默认的TextView. 一.原因 用最简单的全英文句子为例,如果有一个很长的单词,这一行剩余的空间显示不下了,那么规则就是不打断单词,而是把整个单词丢 ...

  7. Android自动解析html带图片,实现图文混排

    在android中,如何将html代码转换为text,然后显示在textview中呢,有一个简单直接的方法: textView.setText(Html.fromHtml(content)); 然而用 ...

  8. Android中Textview显示Html,图文混排,支持图片点击放大

    本文首发于网易云社区 对于呈现Html文本来说,Android提供的Webview控件可以得到很好的效果,但使用Webview控件的弊端是效率相对比较低,对于呈现简单的html文本的话,杀鸡不必使用牛 ...

  9. Android 图文混排 通过webview实现并实现点击图片

    在一个开源项目看到是用的webview 实现的 1. 这是在asset中的一个模板html <html> <head> <title>News Detail< ...

  10. android:怎样在TextView实现图文混排

    我们通常在TextView文本中设置文字.但是怎样设置图文混排呢? 我就在这里写一个样例 .我们须要用到一点简单的HTML知识 在TextView中预订了一些类似HTML的标签,通过标签能够使Text ...

随机推荐

  1. Mybatis批量更新比较

    https://blog.csdn.net/lu1024188315/article/details/78758943

  2. out与ref以及可空类型用法的用法

    1.ref的用法:传递结构 public class A { public int X{get;set;} } public static void changeA(ref A a) { a.X=2 ...

  3. C#将结构体和指针互转的方法

    . 功能及位置 将数据从托管对象封送到非托管内存块,属于.NET Framework 类库 命名空间:System.Runtime.InteropServices 程序集:mscorlib(在 msc ...

  4. etcd 增减节点

    一.查看集群节点 etcdctl --endpoint=https://10.2.0.6:2379 --ca-file=/etc/etcd/ca.pem --cert-file=/etc/etcd/c ...

  5. Codeforces 1120 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意简述:给你一个mmm个数的数列,现在规定把一个数列的1,2,...,k1,2,...,k1,2,...,k分成第一组,把k+1, ...

  6. Unity3D中默认函数的执行顺序

    直接用一张图来说明各个默认函数的执行顺序: FixedUpdate以固定的物理时间间隔被调用,不受游戏帧率影响.一个游戏帧可能会调用多次FixedUpdate.比如处理Rigidbody的时候最好用F ...

  7. JSP 前端的一些应用

    Ext标签库 一.Ext.VeiwPort 代表整个浏览器显示区域,该对象渲染到页面的body 区域,并会随着浏览器显示区域的大小自动改变,一个页面中只能有一个ViewPort 实例. <scr ...

  8. Java实现zip压缩文件的解压

    需求描述: 前段时间写了一篇博客<Java实现对文本文件MD5加密并ftp传送到远程主机目录>,实现了一部分的业务需求.然而有些业务可能不止传送一个文件,有时候客户需要传多个文件,原有系统 ...

  9. python计时器类

    import time as t class MyTimer(): def __init__(self): self.unit = ['年', '月', '日', '时', '分', '秒'] sel ...

  10. poj3660 cow contest

    这题主要是传递闭包 题意: n头牛,m次测试,假设a牛赢过b牛,那么说明a牛的能力比b牛强,问你根据输入的m次测试结果,最多能确定多少条牛的排名 大题的思路: 对于 k 牛,比他强的有x头牛,比他弱的 ...