數據准備
本案例中的服務端數據以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);