Android實戰開發—請求接口獲取數據 – Android移動開發技術文章_手機開發 Android移動開發教學課程

 

上文中我們看過瞭項目的整體框架,趁著寫接口的間隙,和大傢一起研究一下讀取接口的類:XMLTool.java。

 

 

 

說實話,自己的項目名字感覺起的都不怎麼好,XMLTool很容易讓人以為是與XML有關的工具,誰也不會想到是請求接口的一系列方法,這裡以後肯定要改進,這回我們還是以代碼分析為主。

 

 

 

在這個類中,我們有幾個主要的方法,分別是GetXmlValue、PostXmlValue、DeleteXmlValue、UploadImagFile、ReturnXMLValue、DownloadFile2SDCard、GetInputStreamFromUrl這七個方法。基本上常用的請求操作都用到瞭,從名字應該可以看出大概的作用,下面我們一一說明,並指出其中的一些主要代碼。

 

 

 

我們的接口是REST格式,也就是有四種狀態get獲取數據、post新增/修改數據、put修改數據(未用)、delete刪除數據。

 

 

 

1.  GetXmlValue

 

這個方法很明顯,是用來進行get提交並取得數據。使用的是比較常用的方法,大傢看看代碼也就明白瞭:

 

 

StringBuffer sbResult = new StringBuffer(); 

 

 // 創建一個http客戶端 

 

 HttpClient client = new DefaultHttpClient(); 

 

 // 創建一個GET請求 

 

 HttpGet httpGet = new HttpGet(url); 

 

 // 向服務器發送請求並獲取服務器返回的結果 

 

 HttpResponse response = null; 

 

 // 返回的結果可能放到InputStream,http Header中等。 

 

 InputStream inputStream = response.getEntity().getContent(); 

 

 // 讀取內容 

 

 BufferedReader br = new BufferedReader(new InputStreamReader( 

 

        inputStream, "utf-8")); 

 

 String data = ""; 

 

 if (sbResult.toString().equalsIgnoreCase("")) { 

 

     while ((data = br.readLine()) != null) { 

 

        sbResult.append(data); 

 

     } 

 

 } 

 

 inputStream.close(); 

這段代碼應該是網絡上比較常見的瞭,也不用我過多的解釋瞭。

 

 

 

2.       PostXmlValue

 

這個是使用post提交數據,用於新增、修改數據。其中主要是參數的添加,這裡我從外面傳入一個HashMap並轉為List<BasicNameValuePair>,代碼如下:

 

 

   …… 

 

    // 創建一個POST請求 

 

   HttpPost httpPost = new HttpPost(url); 

 

 

 

   //添加post參數 

 

   List<BasicNameValuePair> dataList = new ArrayList<BasicNameValuePair>(); 

 

   Iterator<Map.Entry<String, String>> i = param.entrySet().iterator(); 

 

   while (i.hasNext()) { 

 

       Map.Entry<String, String> o = (Map.Entry<String, String>) i.next(); 

 

       dataList.add(new BasicNameValuePair(o.getKey().toString(), o.getValue().toString())); 

 

   } 

 

   HttpEntity entity = entity = new UrlEncodedFormEntity(dataList, "UTF-8"); 

 

httpPost.setEntity(entity); 

 

…… 

 

 

3.       DeleteXmlValue

 

Delete方法就比較簡單瞭,和get方法類似,不過就是將HttpGet改成HttpDelete對象而已。

 

 

// 創建一個Delete請求 

 

HttpDelete httpDelete = new HttpDelete(); 

 

 

4.       UploadImagFile

 

這是一個上傳圖片的方法,主要是上傳一些小的圖片文件之類,用的也是比較普遍的二進制流的上傳方式。

 

 

 

將文件讀取到一個FileInputStream對象中,然後通過DataOutputStream的write方法寫入請求中,這裡要註意的是一些參數的添加,比如上傳的文件名怎麼定義之類的。

 

 

sb1.append("Content-Disposition: form-data; name=\"do_img\"; filename=\""+ file.getName() + "\"" + LINEND); 

outStream.write(sb1.toString().getBytes()); 

其實這段代碼自己也是似懂非懂,我們就留作最後的提高部分供大傢探討,也希望有高手能將這段代碼全標上註釋供大傢理解。

 

 

 

5.       ReturnXMLValue

 

這個方法就是在上面的GetXmlValue中的// 返回的結果可能放到InputStream,http Header中等。後面那一段,因為每個請求都會用到,所以提瞭出來。

 

 

 

6.       DownloadFile2SDCard

 

這個方法應該看名字能看出來,下載文件到手機卡上。

 

其中FileTool是另外一個工具類,用於一些文件的創建、查找方面的工作,我們以後再介紹,這裡隻是取得inputstream後調用FileTool中的方法來進行操作,所以就不多介紹,留待以後介紹FileTool類時再說。

 

 

 

7.       GetInputStreamFromUrl

 

獲取連接inputstream方法,返回的是conn.getInputStream()。

 

 

 

這就是我用來請求接口的類,其實還是比較粗糙的,但基本功能都沒問題,而且在上一版本的使用中也並沒有出現過什麼問題,因此還算是比較好用的一個工具類。下面附上全部的代碼供參考。

 

 

 

 

package hb.hbwb.tools; 

 

/**

 * @name XML數據處理類

 * @author zhang.yue

 * @create_date 20110512

 * @last_edit_author zhang.yue

 * @last_edit_date 20111115

 * @remark

 * @edit_remark 優化代碼

 */ 

 

import hb.hbwb.R; 

import hb.hbwb.finals.SystemFinals; 

 

import java.io.BufferedReader; 

import java.io.DataOutputStream; 

import java.io.File; 

import java.io.FileInputStream; 

import java.io.IOException; 

  

import java.io.InputStream; 

import java.io.InputStreamReader; 

import java.net.HttpURLConnection; 

import java.net.URI; 

import java.net.URL; 

 

import java.util.ArrayList; 

import java.util.HashMap; 

import java.util.Iterator; 

import java.util.List; 

import java.util.Map; 

 

import org.apache.http.HttpEntity; 

import org.apache.http.HttpResponse; 

import org.apache.http.client.HttpClient; 

import org.apache.http.client.entity.UrlEncodedFormEntity; 

import org.apache.http.client.methods.HttpDelete; 

import org.apache.http.client.methods.HttpGet; 

import org.apache.http.client.methods.HttpPost; 

import org.apache.http.impl.client.DefaultHttpClient; 

import org.apache.http.message.BasicNameValuePair; 

 

import android.content.Context; 

 

public class XMLTool { 

 

    /**

     * 根據請求url獲取信息–GET方法

     * 

     * @param url 鏈接地址

     * @param activity 頁面context

     * @return XML String

     */ 

    public static StringBuffer GetXmlValue(String url, Context activity) { 

        StringBuffer sbResult = new StringBuffer(); 

        // 創建一個http客戶端 

        HttpClient client = new DefaultHttpClient(); 

        // 創建一個GET請求 

        HttpGet httpGet = new HttpGet(url); 

        // 向服務器發送請求並獲取服務器返回的結果 

        HttpResponse response = null; 

        try { 

            response = client.execute(httpGet); 

            //獲取Stream到字符 

            sbResult = ReturnXMLValue(sbResult, response); 

        } catch (Exception e) { 

            System.out.println(e.getMessage()); 

            // 無法訪問服務器,加載錯誤信息 

            sbResult.append(activity.getText(R.string.server_noservice_xml) 

                    .toString());  

 

        } 

        return sbResult; 

    } 

 

    /**

     * POST請求

     * 

     * @param url 鏈接地址

     * @param activity 頁面context

     * @param param 參數

     * @return XML String

     */ 

    public static StringBuffer PostXmlValue(String url, Context activity, 

            HashMap<String, String> param) { 

        StringBuffer sbResult = new StringBuffer(); 

        // 創建一個http客戶端 

        HttpClient client = new DefaultHttpClient(); 

        // 創建一個POST請求 

        HttpPost httpPost = new HttpPost(url); 

 

        //添加post參數 

        List<BasicNameValuePair> dataList = new ArrayList<BasicNameValuePair>(); 

        Iterator<Map.Entry<String, String>> i = param.entrySet().iterator(); 

        while (i.hasNext()) { 

            Map.Entry<String, String> o = (Map.Entry<String, String>) i.next(); 

            dataList.add(new BasicNameValuePair(o.getKey().toString(), o 

                    .getValue().toString())); 

        } 

        HttpEntity entity = null; 

        try { 

            entity = new UrlEncodedFormEntity(dataList, "UTF-8"); 

            httpPost.setEntity(entity); 

            // 向服務器發送請求並獲取服務器返回的結果 

            HttpResponse response = client.execute(httpPost); 

            sbResult = ReturnXMLValue(sbResult, response); 

        } catch (Exception e) { 

            System.out.println(e.getMessage()); 

            sbResult.append(activity.getText(R.string.server_noservice_xml) 

                    .toString()); // 無法訪問服務器 

        } 

        return sbResult; 

    } 

 

    /**

     * Delete請求

     * 

     * @param url 鏈接地址

     * @param activity 頁面context

     * @return XML String

     */ 

    public static StringBuffer DeleteXmlValue(String url, Context activity) { 

        StringBuffer sbResult = new StringBuffer(); 

        // 創建一個http客戶端 

        HttpClient client = new DefaultHttpClient(); 

        // 創建一個Delete請求 

        HttpDelete httpDelete = new HttpDelete(); 

 

        // 向服務器發送請求並獲取服務器返回的結果 

        HttpResponse response = null; 

        try {  

            httpDelete.setURI(new URI(url)); 

            response = client.execute(httpDelete); 

            sbResult = ReturnXMLValue(sbResult, response); 

        } catch (Exception e) { 

            System.out.println(e.getMessage()); 

            sbResult.append(activity.getText(R.string.server_noservice_xml) 

                    .toString()); // 無法訪問服務器 

        } 

        return sbResult; 

    } 

 

    /**

     * 圖片上傳

     * 

     * @param actionUrl 鏈接地址

     * @param imageFilePath 圖片路徑

     * @param activity 頁面context

     * @return XML String

     */ 

    public static String UploadImagFile(String actionUrl, 

            String imageFilePath, Context activity) { 

        String BOUNDARY = java.util.UUID.randomUUID().toString(); 

        String PREFIX = "–", LINEND = "\r\n"; 

        String MULTIPART_FROM_DATA = "multipart/form-data"; 

        try { 

            URL url = new URL(actionUrl); 

            HttpURLConnection con = (HttpURLConnection) url.openConnection(); 

 

            con.setReadTimeout(5 * 1000); // 緩存的最長時間 

            con.setDoInput(true);// 允許輸入 

            con.setDoOutput(true);// 允許輸出 

            con.setUseCaches(false); // 不允許使用緩存 

            con.setRequestMethod("POST"); 

            con.setRequestProperty("connection", "keep-alive"); 

            con.setRequestProperty("Charsert", "UTF-8"); 

            con.setRequestProperty("Content-Type", MULTIPART_FROM_DATA 

                    + ";boundary=" + BOUNDARY); 

 

            DataOutputStream outStream = new DataOutputStream( 

                    con.getOutputStream()); 

 

            File file = new File(imageFilePath); 

            FileInputStream fStream = new FileInputStream(file); 

            int bufferSize = 1024; 

            byte[] buffer = new byte[bufferSize]; 

 

            StringBuilder sb1 = new StringBuilder(); 

            sb1.append(PREFIX); 

            sb1.append(BOUNDARY); 

            sb1.append(LINEND); 

            String ext = file.getName().substring( 

                    file.getName().lastIndexOf(".") + 1); 

            String ctypeString = StringTool.Zch_GetUpImageExt(ext); 

            sb1.append("Content-Disposition: form-data; name=\"do_img\"; filename=\"" 

                    + file.getName() + "\"" + LINEND); 

            sb1.append("Content-Type: " + ctypeString + "; charset=" + SystemFinals.CHARSET 

                    + LINEND); 

 

            sb1.append(LINEND); 

            outStream.write(sb1.toString().getBytes()); 

 

            int length = -1; 

 

            while ((length = fStream.read(buffer)) != -1) { 

                outStream.write(buffer, 0, length); 

            } 

            outStream.write(LINEND.getBytes()); 

            fStream.close(); 

 

            // 請求結束標志 

            byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes(); 

            outStream.write(end_data); 

            outStream.flush(); 

 

            int res = con.getResponseCode(); 

            StringBuffer b = new StringBuffer(); 

            if (res == 200) { 

                InputStream is = con.getInputStream(); 

                int ch; 

 

                while ((ch = is.read()) != -1) { 

                    b.append((char) ch); 

                } 

            } 

            outStream.close(); 

 

            return b.toString(); 

        } catch (Exception e) { 

            return ""; 

        } 

 

    } 

 

    /**

     * 讀取返回的信息

     * 

     * @param sbResult 連接用字符

     * @param response 數據response

     * @return XML String

     * @throws Exception IllegalStateException或IOException異常

     */ 

    private static StringBuffer ReturnXMLValue(StringBuffer sbResult, 

            HttpResponse response) throws Exception { 

        // 返回的結果可能放到InputStream,http Header中等。 

        InputStream inputStream = response.getEntity().getContent(); 

        // 讀取內容 

        BufferedReader br = new BufferedReader(new InputStreamReader( 

                inputStream, "utf-8")); 

        String data = ""; 

        if (sbResult.toString().equalsIgnoreCase("")) { 

            while ((data = br.readLine()) != null) { 

                sbResult.append(data); 

            } 

        } 

        inputStream.close(); 

        return sbResult; 

    } 

     

    /**

     * 下載文件並保存到內存卡方法

     * @param urlString 文件地址

     * @param path 保存路徑

     * @param fileName 文件名

     * @return 0成功,1已存在,-1發生錯誤

     */ 

    public int DownloadFile2SDCard(String urlString,String path,String fileName){ 

        InputStream inputStream = null; 

        try { 

            FileTool fileTool = new FileTool(); 

            if(fileTool.IsFileExist(fileName, path)){ 

                return 1; 

            }else{ 

                inputStream = GetInputStreamFromUrl(urlString); 

                File resultFile = fileTool.Write2SDFromInput(path, fileName, inputStream); 

                if(resultFile==null){ 

                    return -1; 

                } 

            } 

        } catch (Exception e) { 

            System.out.println(e.getMessage()); 

            return -1; 

        }finally{ 

            try { 

                inputStream.close(); 

            } catch (Exception e) { 

                System.out.println(e.getMessage()); 

            } 

        } 

         

        return 0; 

    } 

     

    /**

     * 獲取連接inputstream方法

     * @param urlStr 連接地址

     * @return inpustream流

     * @throws IOException

     */ 

    private InputStream GetInputStreamFromUrl(String urlStr) throws IOException{ 

        URL url = new URL(urlStr); 

        HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 

        return conn.getInputStream(); 

    } 

 

 

 

 

 

 

======================================================

 

提高:1. UploadImagFile註釋

 

            2.在這個類中,我將Expection全部使用Expection一個來拋出,而不是分成N個詳細的Catch來拋出,這樣會不會對性能造成影響,或者說哪種性能更優,它們的優缺點是什麼?

 

  

 

摘自 ¤壞小子¨的挨踢民工生活

發佈留言