前言

  本周一直在说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. Chapter5_初始化与清理_用构造器初始化

    接下来进入第五章,java中初始化和清理的问题,这是两个涉及安全的重要命题.初始化的功能主要是为库中的构件(或者说类中的域)初始化一些值,清理的功能主要是清除程序中不再被需要的元素,防止资源过分被垃圾 ...

  2. android 开发案列汇总

    Android 开发案列汇总 1.一款轻量级的便签软件,界面简单干净,绿色无广告.支持部分Markdown语法,可以方便地输入和预览Markdown文本,并且生成长微博图片保存到本地. 文章来源:ht ...

  3. 大前端学习笔记【七】关于CSS再次整理

    如果你在日常工作中使用 CSS,你的主要目标可能会重点围绕着使事情“看起来正确”.如何实现这一点经常是远不如最终结果那么重要.这意味着比起正确的语法和视觉结果来说,我们更少关心 CSS 的工作原理. ...

  4. Django模板标签

    一.模板标签 1.模板标签是在模板中运用python语言的实现,如for循环,if语句 2.模板标签的运用 2.1在teacher模板下创建students_list模板, 在teacher视图中国创 ...

  5. _ZNote_Qt_重启软件

    原文: http://wiki.qt.io/How_to_make_an_Application_restartable int main(int argc, char** argv) { QAppl ...

  6. flask-文件上传

    flask文件上传 流程 1. 上传的文件request.files拿取 2. 可以通过WTForms表单验证 3. 通过secure_filename (from werkzeug.utils im ...

  7. 在Windows平台下Qt的exe报错问题排查步骤

    在Windows平台下Qt的exe报错问题排查步骤 工具介绍: 1. Dependency Worker Dependency Worker是一个免费的用具用来扫描任何的32bit 或者64bit 的 ...

  8. wordcounter

    这周是一个wc的程序,通过C语言在WINDOWS上实现的. 我在通过参考的代码后,发现WC程序的代码其实相当简洁,主要的代码不过十数行.主要通过设置一个字符型变量,这个变量可以得到一个从键盘输入的字符 ...

  9. Chrome部分站点无法启用Flash问题

    ## 69.0之前 ## 1. 打开 chrome://settings/content/flash 2. 禁止网站运行Flash -> 改为“先询问(推荐)” 3. 允许->添加 4. ...

  10. MXNet的新接口Gluon

    为什么要开发Gluon的接口 在MXNet中我们可以通过Sybmol模块来定义神经网络,并组通过Module模块提供的一些上层API来简化整个训练过程.那MXNet为什么还要重新开发一套Python的 ...