對於HTTP協議,大家肯定不陌生,我們平時訪問網站的網址一般都是使用http協議的,它的工作原理十分簡單,就是客戶端向服務器發送一條HTTP請求,服務器收到請求之後會返回一些數據給客戶端,然後客戶端再對這些數據進行解析處理就可以了。可以總結爲一下幾步:
1、客戶端發送HTTP請求
2、服務器接受服務響應
3、服務器返回數據
4、客戶端解析處理返回數據
接下來通過手動發送HTTP請求的方式,來更加深入地理解一下這個過程。
HttpURLConnection的使用
由於在Android 5.0後HttpClient被廢棄了,所以這裏只介紹如何使用HttpURLConnection來訪問網絡,首先要獲取HttpURLConnection的實例,代碼如下:
try {
URL url = new URL("http://www.baidu.com");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
得到HttpURLConnection的實例之後,我們可以設置一下HTTP請求所使用的方法。常用的方法主要有兩個,GET和POST。GET表示希望從服務器裏獲取數據,而POST則表示希望提交數據給服務器。我們這裏就設置爲GET,代碼如下:
connection.setRequestMethod("GET");
接下來就可以進行一些自由的定製了,比如設置連接超時、讀取超時的毫秒數,以及服務器希望得到一些消息頭,代碼如下:
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
然後再調用getInputStream()方法就可以獲取到服務器返回的數據輸入流,然後就可以對數據流進行讀取,代碼如下:
InputStream in = connection.getInputStream();
最後可以調用disconnect()方法將這個HTTP連接關閉掉,代碼如下:
connection.disconnect();
下面就以訪問百度網站爲例,代碼如下:
public class MainActivity extends Activity {
private final static int SHOW_RESPONSE = 1;
// private HttpsURLConnection connection;
private TextView tv_Response;
final Handler myHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_RESPONSE:
tv_Response.setText(msg.obj.toString());
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnSendRequest = (Button) findViewById(R.id.send_request);
tv_Response = (TextView)findViewById(R.id.response_text);
btnSendRequest.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
sendHttpRequest("http://www.baidu.com");
}
});
}
public void sendHttpRequest(final String url){
new Thread(new Runnable() {
final String urlString = url;
@Override
public void run() {
// TODO Auto-generated method stub
HttpURLConnection connection = null;
try {
URL url = new URL(urlString);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
InputStream in = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
while((line = bufferedReader.readLine()) != null){
response.append(line);
}
Message message = new Message();
message.what = SHOW_RESPONSE;
message.obj = response.toString();
myHandler.sendMessage(message);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(connection != null){
connection.disconnect();
}
}
}
}).start();
}
}
最後還要在AndroidManifest.xml中聲明一下網絡權限:
<uses-permission android:name="android.permission.INTERNET"/>
如果想要向服務器提交數據,則只需將HTTP請求的方法改成POST,並在輸入流前把數據提交,注意,數據每條數據都要以鍵值對的形式存在,數據與數據之間用&符號隔開,比如提交用戶名和密碼,就可以這樣寫:
connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=admin&password=123456");