數據准備
本案例中的服務端數據以Json的形式傳遞,在服務端使用.Net開發一個一般處理程序,序列化一個產品對象,裡面包含名稱、價格、圖片名稱,最後序列化成JSON格式的數據返回給客戶端。
數據如下
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數據,並對其進行解析
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);