Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android應用開發入門(四十四)多線程之圖文混排

Android應用開發入門(四十四)多線程之圖文混排

編輯:Android開發實例

前言

  本篇聊一聊Android開發中一個比較經典的案例,網絡數據圖文混排,本文的案例只涉及關於開啟多線程訪問網絡數據,不涉及緩存的內容。眾所周知,從網絡上獲取一段文本肯定要比獲取一張張的圖片要省時,所以一般如果是獲取圖片+文本的數據,會先開啟一條線程獲取文本數據,再從開啟另外的線程來單獨獲取圖片信息。本案例填充一個自定義的XML布局文件作為數據項,並使用ListView承載數據。

 

數據准備

  本案例中的服務端數據以Json的形式傳遞,在服務端使用.Net開發一個一般處理程序,序列化一個產品對象,裡面包含名稱、價格、圖片名稱,最後序列化成JSON格式的數據返回給客戶端。關於.Net下如何序列化一個對象成JSON格式,可以參見:http://www.fengfly.com/plus/view-213375-1.html,這裡不再累述,大家可以使用自己熟悉的服務端技術模擬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/";  

使用AsyncTask獲取Json數據

  在UI線程中,使用AsyncTask的方式訪問網絡獲取JSON數據,並對其進行解析,關於Android下JSON解析的內容可以參見:http://www.fengfly.com/plus/view-213376-1.html。 

 

  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.     }  

數據的適配器

  上面已經獲取到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.     } 

 效果展示:

   源碼下載

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved