編輯:關於Android編程
本章主要會講述如何在手機端使用HTTP協議和服務器端進行網絡交互,並對服務器返回的數據進行解析,這也是Android中最常使用到的網絡技術了,下面就讓我們一起來學習一下吧。
借助它我們就可以在自己的應用程序裡嵌入一個浏覽器,從而非常輕松地展示各種各樣的網頁
WebView的用法也是相當簡單,下面我們就通過一個例子來學習一下吧。新建一個WebViewTest項目,然後修改activity_main.xml中的代碼,如下所示
可以看到,我們在布局文件中使用到了一個新的控件,WebView。這個控件當然也就是用來顯示網頁的了,這裡的寫法很簡單,給它設置了一個id,並讓它充滿整個屏幕。
然後修改MainActivity中的代碼,如下所示:
package com.example.webview; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.webkit.WebView; import android.webkit.WebViewClient; public class MainActivity extends Activity { private WebView webview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webview=(WebView) findViewById(R.id.web_view); webview.getSettings().setJavaScriptEnabled(true); webview.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); // 根據傳入的參數再去加載新的網頁 return true; // 表示當前WebView可以處理打開新網頁的請求,不用借助系統浏覽器 } }); webview.loadUrl("http://www.baidu.com"); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
MainActivity中的代碼也很短,首先使用findViewById()方法獲取到了WebView的實例,然後調用WebView的getSettings()方法可以去設置一些浏覽器的屬性,這裡我們並不去設置過多的屬性,只是調用了setJavaScriptEnabled()方法來讓WebView支持JavaScript腳本。
接下來是非常重要的一個部分,我們調用了WebView的setWebViewClient()方法,並傳入了WebViewClient的匿名類作為參數,然後重寫了shouldOverrideUrlLoading()方法。這就表明當需要從一個網頁跳轉到另一個網頁時,我們希望目標網頁仍然在當前WebView中顯示,而不是打開系統浏覽器。
最後一步就非常簡單了,調用WebView的loadUrl()方法,並將網址傳入
另外還需要注意,由於本程序使用到了網絡功能,而訪問網絡是需要聲明權限的,因此我們還得修改AndroidManifest.xml文件,並加入權限聲明,如下所示:
…… ……
它的工作原理特別的簡單,就是客戶端向服務器發出一條HTTP請求,服務器收到請求之後會返回一些數據給客戶端,然後客戶端再對這些數據進行解析和處理就可以了。
在Android上發送HTTP請求的方式一般有兩種,HttpURLConnection和HttpClient,本小節我們先來學習一下HttpURLConnection的用法。
首先需要獲取到HttpURLConnection的實例,一般只需new出一個URL對象,並傳入目標的網絡地址,然後調用一下openConnection()方法即可,如下所示:
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
得到了HttpURLConnection的實例之後,我們可以設置一下HTTP請求所使用的方法。常用的方法主要有兩個,GET和POST。GET表示希望從服務器那裡獲取數據,而POST則表示希望提交數據給服務器。寫法如下:
connection.setRequestMethod("GET");
接下來就可以進行一些自由的定制了,比如設置連接超時、讀取超時的毫秒數,以及服務器希望得到的一些消息頭等。這部分內容根據自己的實際情況進行編寫,示例寫法如下:
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
之後再調用getInputStream()方法就可以獲取到服務器返回的輸入流了,剩下的任務就是對輸入流進行讀取,如下所示:
InputStream in = connection.getInputStream();
最後可以調用disconnect()方法將這個HTTP連接關閉掉,如下所示:
connection.disconnect();
下面就讓我們通過一個具體的例子來真正體驗一下HttpURLConnection的用法。新建一個NetworkTest項目,首先修改activity_main.xml中的代碼,如下所示:
注意這裡我們使用了一個新的控件,ScrollView,它是用來做什麼的呢?由於手機屏幕的空間一般都比較小,有些時候過多的內容一屏是顯示不下的,借助ScrollView控件的話就可以允許我們以滾動的形式查看屏幕外的那部分內容。另外,布局中還放置了一個Button和一個TextView,Button用於發送HTTP請求,TextView用於將服務器返回的數據顯示出來。
接著修改MainActivity中的代碼,如下所示:
public class MainActivity extends Activity implements OnClickListener { public static final int SHOW_RESPONSE = 0; private Button sendRequest; private TextView responseText; private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case SHOW_RESPONSE: String response = (String) msg.obj; // 在這裡進行UI操作,將結果顯示到界面上 responseText.setText(response); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sendRequest = (Button) findViewById(R.id.send_request); responseText = (TextView) findViewById(R.id.response_text); sendRequest.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.send_request) { sendRequestWithHttpURLConnection(); } } private void sendRequestWithHttpURLConnection() { // 開啟線程來發起網絡請求 new Thread(new Runnable() { @Override public void run() { HttpURLConnection connection = null; try { URL url = new URL("http://www.baidu.com"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in = connection.getInputStream(); // 下面對獲取到的輸入流進行讀取 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } Message message = new Message(); message.what = SHOW_RESPONSE; // 將服務器返回的結果存放到Message中 message.obj = response.toString(); handler.sendMessage(message); } catch (Exception e) { e.printStackTrace(); } finally { if (connection != null) { connection.disconnect(); } } } }).start(); } }
以看到,我們在Send Request按鈕的點擊事件裡調用了sendRequestWithHttpURL- Connection()方法,在這個方法中先是開啟了一個子線程,然後在子線程裡使用HttpURLConnection發出一條HTTP請求,請求的目標地址就是百度的首頁。接著利用BufferedReader對服務器返回的流進行讀取,並將結果存放到了一個Message對象中。這裡為什麼要使用Message對象呢?當然是因為子線程中無法對UI進行操作了。我們希望可以將服務器返回的內容顯示到界面上,所以就創建了一個Message對象,並使用Handler將它發送出去。之後又在Handler的handleMessage()方法中對這條Message進行處理,最終取出結果並設置到TextView上。
過在開始運行之前,仍然別忘了要聲明一下網絡權限。修改AndroidManifest.xml中的代碼
…… ……
好了,現在運行一下程序,並點擊Send Request按鈕,結果如圖2所示。
那麼如果是想要提交數據給服務器應該怎麼辦呢?其實也不復雜,只需要將HTTP請求的方法改成POST,並在獲取輸入流之前把要提交的數據寫出即可。注意每條數據都要以鍵值對的形式存在,數據與數據之間用&符號隔開,比如說我們想要向服務器提交用戶名和密碼,就可以這樣寫:
connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=admin&password=123456");
HttpClient是Apache提供的HTTP網絡訪問接口,從一開始的時候就被引入到了Android API中。它可以完成和HttpURLConnection幾乎一模一樣的效果,但兩者之間的用法卻有較大的差別,那麼我們自然要看一下HttpClient是如何使用的了。
首先你需要知道,HttpClient是一個接口,因此無法創建它的實例,通常情況下都會創建一個DefaultHttpClient的實例,如下所示:
HttpClient httpClient = new DefaultHttpClient();
接下來如果想要發起一條GET請求,就可以創建一個HttpGet對象,並傳入目標的網絡地址,然後調用HttpClient的execute()方法即可:
HttpGet httpGet = new HttpGet("http://www.baidu.com");
httpClient.execute(httpGet);
並傳入目標的網絡地址,如下所示:
HttpPost httpPost = new HttpPost("http://www.baidu.com");
然後通過一個NameValuePair集合來存放待提交的參數,並將這個參數集合傳入到一個UrlEncodedFormEntity中,然後調用HttpPost的setEntity()方法將構建好的UrlEncodedFormEntity傳入,如下所示:
List
params.add(new BasicNameValuePair("username", "admin"));
params.add(new BasicNameValuePair("password", "123456"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8");
httpPost.setEntity(entity);
接下來的操作就和HttpGet一樣了,調用HttpClient的execute()方法,並將HttpPost對象傳入即可:
httpClient.execute(httpPost);
執行execute()方法之後會返回一個HttpResponse對象,服務器所返回的所有信息就會包含在這裡面。通常情況下我們都會先取出服務器返回的狀態碼,如果等於200就說明請求和響應都成功了,如下所示:
if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 請求和響應都成功了
}
接下來在這個if判斷的內部取出服務返回的具體內容,可以調用getEntity()方法獲取到一個HttpEntity實例,然後再用EntityUtils.toString()這個靜態方法將HttpEntity轉換成字符串即可,如下所示:
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity);
注意如果服務器返回的數據是帶有中文的,直接調用EntityUtils.toString()方法進行轉換會有亂碼的情況出現,這個時候只需要在轉換的時候將字符集指定成utf-8就可以了,如下所示:
String response = EntityUtils.toString(entity, "utf-8");
好了,基本的用法就是如此,接下來就讓我們把NetworkTest這個項目改用HttpClient的方式再實現一遍吧。
由於布局部分完全不用改動,所以現在直接修改MainActivity中的代碼,如下所示
public class MainActivity extends Activity implements OnClickListener { …… @Override public void onClick(View v) { if (v.getId() == R.id.send_request) { sendRequestWithHttpClient(); } } private void sendRequestWithHttpClient() { new Thread(new Runnable() { @Override public void run() { try { HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet("http://www.baidu.com"); HttpResponse httpResponse = httpClient.execute(httpGet); if (httpResponse.getStatusLine().getStatusCode() == 200) { // 請求和響應都成功了 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity, "utf-8"); Message message = new Message(); message.what = SHOW_RESPONSE; // 將服務器返回的結果存放到Message中 message.obj = response.toString(); handler.sendMessage(message); } } catch (Exception e) { e.printStackTrace(); } } }).start(); } …… }
Android其實沒有對話框的概念,有的只是用PopupWindow實現一個對話框的效果。下面給一個完整的例子,及用法。 新建一個PromptWindow類 packag
前言Android 開發中,我們經常需要實現圖片的圓形/圓角的效果,我們可以使用兩種方式來實現這樣的效果。一種是使用Xfermode,另一種是BitmapShader來實
本文實例講述了Android編程實現任務管理器的方法。分享給大家供大家參考,具體如下:任務管理器可以實現的功能有:1.查看當前系統下運行的所有的進程2.可以查看每個進程的
一個讓人賞心悅目的界面對軟件來說非常重要,因此圖形圖像資源也顯得非常重要。本講就要談一談Android中處理圖形圖像的最重要的一個類Drawable。Drawable就是
先占個位置,下次翻譯~ :p Properly stopping a