android網絡編程 -- HTTP通信(02) Android HTTP 通信 [附源碼分析]

之前我們探討了Tomcat 搭建 HTTP 服務器,這節我們探討一下Android 與 服務器的通信。

Android HTTP請求可以通過以下兩種方式實現:

1. 使用JDK中HttpURLConnection訪問網絡資源(POST, GET)

2.使用Apache的HttpClient訪問網絡資源(POST, GET)

今天主要探討第一種:


S0 安卓環境搭建

這是準備工作,不再累述。

S1 新建一個安卓工程


用 MyEclipse (或 Eclipse) 新建一個安卓程序並命名爲 AndroidHTTPDemo。

創建好空工程,點擊運行,結果如截圖所示:( HelloWorld 程序 )


S2 簡單設計安卓界面,在原來基礎上增加一個Button即可。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/Infotv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/ShowBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="82dp"
        android:text="Show" />

</RelativeLayout>

SS1 GET 方法

S3 新建一個WebService類,在com.rxz.web包下,編寫安卓的通信程序:

package com.rxz.web;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class WebService {
	// IP地址
	private static String IP = "10.0.2.2:8080";

	/**
	 * 通過Get方式獲取HTTP服務器數據
	 * @return
	 */
	public static String executeHttpGet() {
		
		HttpURLConnection conn = null;
		InputStream is = null;
		
        try {
        	// URL 地址
        	String path = "http://" + IP + "/HelloWeb/servlet/MyServlet";
        	
        	conn = (HttpURLConnection) new URL(path).openConnection();
    		conn.setConnectTimeout(5000); // 設置超時時間
    		conn.setRequestMethod("GET"); // 設置獲取信息方式
    		conn.setRequestProperty("Charset", "UTF-8"); // 設置接收數據編碼格式

    		if(conn.getResponseCode() == 200){
    			is = conn.getInputStream();
    			return parseInfo(is);
    		}

    		return null;
    		
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        	// 意外退出時進行連接關閉保護
            if (conn != null) {
                conn.disconnect();
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
        }
        return null;
    }
	
	/**
	 * 將輸入流轉化爲 String 型
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	private static String parseInfo(InputStream inStream) throws Exception{
		byte[] data = read(inStream);
		//轉化爲字符串
		return new String(data, "UTF-8");
	}
	
	/**
	 * 將輸入流轉化爲byte型
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	public static byte[] read(InputStream inStream) throws Exception{
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while((len = inStream.read(buffer)) != -1){
			outputStream.write(buffer,0,len);
		}
		inStream.close();
		return outputStream.toByteArray();
	}
}

S4 修改MainActivity界面類,獲取Button,並響應按鈕點擊事件:

package com.rxz.androidhttpdemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

import com.rxz.web.WebService;

public class MainActivity extends Activity implements OnClickListener {
	
	// 顯示按鈕
	private Button showbtn = null;
	// 顯示文本區域
	private TextView infotv = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		// 獲取控件
		showbtn = (Button) findViewById(R.id.ShowBtn);
		infotv = (TextView) findViewById(R.id.Infotv);
		
		// 設置按鈕監聽器
		showbtn.setOnClickListener(this);	
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId())
		{
		// 顯示按鈕點擊事件
		case R.id.ShowBtn:
			String info = WebService.executeHttpGet();
			infotv.setText(info);
			break;
		}
	}
}

S5 切記:增加安卓聯網權限!!!在AndroidManifest.xml文件裏面:

    <!-- 聯網權限 -->
    <uses-permission android:name="android.permission.INTERNET" />

S6 先運行01節博客所講的HTTP 服務器,然後運行安卓程序,按下按鈕,效果如下,表明成功。


SS2 POST方法

S7 新建一個WebServicePost類,在com.rxz.web包下,編寫安卓的通信程序:

package com.rxz.web;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

public class WebServicePost {
	
	// IP地址
	private static String IP = "10.0.2.2:8080";
	
	/**
	 * 通過 POST 方式獲取HTTP服務器數據
	 * @param infor
	 * @param credit
	 * @return
	 * @throws Exception
	 */
	public static String executeHttpPost(String infor,String credit){
		
		try {
			String path = "http://" + IP + "/HelloWeb/servlet/MyServlet";
			
			// 發送指令和信息
			Map<String,String> params = new HashMap<String,String>();
			params.put("infor", infor);
			params.put("state", credit);
			
			return sendPOSTRequest(path, params, "UTF-8");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
		return null;
	}
	
	/**
	 * 處理髮送數據請求
	 * @param path
	 * @param params
	 * @param encoding
	 * @return
	 * @throws Exception
	 */
	private static String sendPOSTRequest(String path,
			Map<String, String> params, String encoding) throws Exception {
		// TODO Auto-generated method stub
		List<NameValuePair> pairs = new ArrayList<NameValuePair>();
		if(params != null && !params.isEmpty()){
			for(Map.Entry<String, String> entry : params.entrySet()){
				pairs.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
			}
		}
		
		UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs,encoding);
		
		HttpPost post = new HttpPost(path);
		post.setEntity(entity);
		DefaultHttpClient client = new DefaultHttpClient();
		HttpResponse response = client.execute(post);
		
		// 判斷是否成功收取信息
		if(response.getStatusLine().getStatusCode() == 200){
			return getInfo(response);
		}
		
		// 未成功收取信息,返回空指針
		return null;
	}
	
	/**
	 * 收取數據
	 * @param response
	 * @return
	 * @throws Exception
	 */
	private static String getInfo(HttpResponse response) throws Exception{
		
	    HttpEntity entity =	response.getEntity();
	    InputStream is = entity.getContent();
		//將輸入流轉化爲byte型
		byte[] data = WebService.read(is);
		//轉化爲字符串
		return new String(data, "UTF-8");
	}
	
}

S8 修改MainActivity界面類,獲取Button,並響應按鈕點擊事件:

@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId())
		{
		// 顯示按鈕點擊事件
		case R.id.ShowBtn:
			//String info = WebService.executeHttpGet();
			//infotv.setText(info);
			String info = WebServicePost.executeHttpPost("MyCommand", "This is My Info");
			infotv.setText(info);
			break;
		}
	}

S9 修改服務器MyServlet類的doPost方法,實現獲取用戶傳遞信息並反饋信息的功能:

/**
	 * The doPost method of the servlet. <br>
	 *
	 * This method is called when a form has its tag value method equals to post.
	 * 
	 * @param request the request send by the client to the server
	 * @param response the response send by the server to the client
	 * @throws ServletException if an error occurred
	 * @throws IOException if an error occurred
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		System.out.println("************   POST正在接收請求      *************");
		
		// 設置編碼方式
		request.setCharacterEncoding("UTF-8");
		// 獲取到 命令信息
		String infor = request.getParameter("infor");
		// 獲取到 參數信息
		String credit = request.getParameter("state");
		
		System.out.println("收到的客戶端的信息爲:" + infor);
		System.out.println("    收到客戶端的命令:" + credit);
		
		
		System.out.println("************   正在發送信息      *************");
		
		// 發送信息
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("回饋信息" + infor + ":" + credit);
		
		out.flush();
		out.close();
		
	}

S10 重新運行HTTP 服務器,然後運行安卓程序,按下按鈕,效果如下,表明成功。


PS: 關鍵點:
注意:因爲是通過android模擬器訪問本地pc服務端,所以不能使用localhost和127.0.0.1,使用127.0.0.1會訪問模擬器自身。
Android系統爲實現通信將PC的IP設置爲10.0.2.2

附上源碼:
沒有積分的請留言郵箱~

發佈了26 篇原創文章 · 獲贊 24 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章