2015年6月8日 星期一

[Android] Use Post To Call API


開發Android時,如何用Post的方式 Call API來取得值

  • 首先
                String UrlLocation = 你的API位置; //API位置
                String PostData = 要傳遞的資料(字串); //EX: ID=Toyo&Name=Steven
    
                HttpURLConnection conn = null;
                StringBuilder sb = new StringBuilder();
                try
                {
                    URL Url = new URL(UrlLocation);
                    conn = (HttpURLConnection)Url.openConnection();
                    conn.setRequestMethod("POST"); //要呼意的方式 Get Or Post
                    conn.setDoInput(true);
                    conn.setDoOutput(true);
                    conn.connect();
                    //開始傳輸資料過去給API
                    OutputStream Output = conn.getOutputStream();
                    BufferedWriter writer = new BufferedWriter(
                            new OutputStreamWriter(Output, "UTF-8"));
                    writer.write(PostData);
                    writer.flush();
                    writer.close();
                    Output.close();
                    
                    //讀取API回傳的值
                    BufferedReader br = new BufferedReader(new InputStreamReader(
                            conn.getInputStream(),"utf-8"));
    
                    String line;
                    while ((line=br.readLine())!=null)
                    {
                        sb.append(line);
                    }
                }
                catch(Exception ex)
                {
                    Log.e("API_Post",ex.getMessage());
                }
                finally
                {
                    if (conn != null)
                        conn.disconnect();
                }
    
                return sb.toString();
    
  • 目前測試的結果是,如果不把呼叫API用執行緒AsyncTask的方式處理,在conn.connect()這邊會跳出Http...InMainThread的Exception,原因是Andorid預設呼叫外部處理5秒沒有回應就會跳Exception,所以預設不管這支API反應速度快不快,他都要你把上面那段做成切執行緒的方式處理,當然網路上還是有舊的方式可以用,但既然這是官方目前推薦的做法就照做吧
    //這邊有三個參數
    //第一個參數String : 呼叫這個方法時要帶入的參數型態,這邊就是可以帶入String,
    //第二個參數Void : 處理時會回報狀態跟進度,這邊寫Void表示不回傳目前處理狀態
    //第三個參數String : 處理完成時回傳的值
    private class Post extends AsyncTask
        {
    
            //事件處理順序onPreExecute , doInBackground ,onPostExecute
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }
    
            @Override
            protected String doInBackground(String ... params) {
                //改寫這邊,呼叫方法時可以傳進多個String,所以這邊改抓params
                String UrlLocation = params[0]; //API位置
                String PostData = params[1]; //要傳資料
    
                HttpURLConnection conn = null;
                StringBuilder sb = new StringBuilder();
                try
                {
                    URL Url = new URL(UrlLocation);
                    conn = (HttpURLConnection)Url.openConnection();
                    conn.setRequestMethod("POST"); //要呼意的方式 Get Or Post
                    conn.setDoInput(true);
                    conn.setDoOutput(true);
                    conn.connect();
                    //開始傳輸資料過去給API
                    OutputStream Output = conn.getOutputStream();
                    BufferedWriter writer = new BufferedWriter(
                            new OutputStreamWriter(Output, "UTF-8"));
                    writer.write(PostData);
                    writer.flush();
                    writer.close();
                    Output.close();
    
                    //讀取API回傳的值
                    BufferedReader br = new BufferedReader(new InputStreamReader(
                            conn.getInputStream(),"utf-8"));
    
                    String line;
                    while ((line=br.readLine())!=null)
                    {
                        sb.append(line);
                    }
                }
                catch(Exception ex)
                {
                    Log.e("API_Post",ex.getMessage());
                }
                finally
                {
                    if (conn != null)
                        conn.disconnect();
                }
    
                return sb.toString();
            }
    
           @Override
            protected void onPostExecute(String Result) {
                super.onPostExecute(Result);
            }
        }
    
  • 最後,因為在Debug模式AsyncTask並不會進入,所以要在doInBackground的事件裡面加上這行,但因為非Debug模式下這行會造成Android沒有回應, 所以記得在部署時把這行拿掉!!
    android.os.Debug.waitForDebugger();
    
  • 全部完成後,呼叫方式如下
    String Url = "http://www.api.com.tw";
    String PostData = "id=toyo&name=steven";
    String Response = new Post().execute(Url,PostData).get();