这里我们将学习Android程序如何进行网络连接,获取网络返回数据,如果对HTTP网络协议还不了解的可以参考深入理解HTTP协议,在进行网络连接操作前需要先在程序的manifest文件中添加下面的permissions:
1 | <uses-permission android:name= "android.permission.INTERNET" /> |
2 | <uses-permission android:name= "android.permission.ACCESS_NETWORK_STATE" /> |
同时要检查当前网络环境是否可用
1 | ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); |
2 | NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); |
3 | if (networkInfo != null && networkInfo.isConnected()) { |
网络操作会遇到不可预期的延迟。显然为了避免一个不好的用户体验,总是在UI Thread之外去执行网络操作。AsyncTask 类提供了一种简单的方式来处理这个问题
doInBackground()) 执行 downloadUrl()方法。Web URL作为参数,方法downloadUrl() 获取并处理网页返回的数据,执行完毕后,传递结果到onPostExecute()。参数类型为String.
onPostExecute()) 获取到返回数据并显示到UI上。
1 | private class DownloadWebpageText extends AsyncTask<String, Void, String> { |
3 | protected String doInBackground(String... urls) { |
11 | protected void onPostExecute(String result) { |
我们来看下完整的实例代码
布局文件activity_httpconnection_layout.xml
1 | <?xml version= "1.0" encoding= "utf-8" ?> |
3 | android:layout_width= "match_parent" |
4 | android:layout_height= "match_parent" |
5 | android:orientation= "vertical" > |
8 | android:id= "@+id/http_url_edit" |
9 | android:layout_width= "match_parent" |
10 | android:layout_height= "wrap_content" |
11 | android:hint= "请输入URL地址" /> |
14 | android:id= "@+id/http_content_txt" |
15 | android:layout_width= "match_parent" |
16 | android:layout_height= "wrap_content" /> |
18 | <Button android:id= "@+id/http_get_content_btn" |
19 | android:layout_width= "match_parent" |
20 | android:onClick= "onConnectionClickHandler" |
21 | android:layout_height= "wrap_content" /> |
原代码 HttpExampleActivity.java
1 | public class HttpExampleActivity extends Activity { |
2 | private static final String DEBUG_TAG = "HttpExample" ; |
3 | private EditText mUrlText; |
4 | private TextView mShowMessageTxt; |
7 | public void onCreate(Bundle savedInstanceState) { |
8 | super .onCreate(savedInstanceState); |
9 | setContentView(R.layout.activity_httpconnection_layout); |
10 | mUrlText = (EditText) findViewById(R.id.http_url_edit); |
11 | mShowMessageTxt = (TextView) findViewById(R.id.http_content_txt); |
15 | * 用户点击此按钮时执行异步任务,在执行前需检查网络是否可用. |
18 | public void onConnectionClickHandler(View view) { |
19 | String stringUrl = mUrlText.getText().toString(); |
20 | ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); |
21 | NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); |
22 | if (networkInfo != null && networkInfo.isConnected()) { |
23 | new DownloadWebpageText().execute(stringUrl); |
25 | mShowMessageTxt.setText( "网络连接不可用!" ); |
29 | private class DownloadWebpageText extends AsyncTask<String, Void, String> { |
31 | protected String doInBackground(String... urls) { |
35 | return downloadUrl(urls[ 0 ]); |
36 | } catch (IOException e) { |
37 | return "Unable to retrieve web page. URL may be invalid." ; |
43 | protected void onPostExecute(String result) { |
44 | mShowMessageTxt.setText(result); |
50 | * 根据给定的url地址,建立一个HttpUrlConnection连接它将以流的形式返回页面内容,将流转换成字符串返回 |
55 | private String downloadUrl(String myurl) throws IOException { |
56 | InputStream is = null ; |
59 | URL url = new URL(myurl); |
60 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); |
61 | conn.setReadTimeout( 10000 ); |
89 | public String readIt(InputStream stream) throws IOException,UnsupportedEncodingException { |
90 | Reader reader = new InputStreamReader(stream, "UTF-8" ); |
92 | BufferedReader br = new BufferedReader(reader); |
96 | StringBuffer sb = new StringBuffer(); |
97 | while ((line = br.readLine()) != null ) { |
101 | return sb.toString(); |
请注意,getResponseCode() 会返回连接状态码( status code). 这是一种获知额外网络连接信息的有效方式。status code 是 200 则意味着连接成功.
Convert the InputStream to a String(把InputStream的数据转换为String)
InputStream 是一种可读的byte数据源。如果你获得了一个 InputStream, 通常会进行decode或者转换为制定的数据类型。例如,如果你是在下载一张image数据,你可能需要像下面一下进行decode:
3 | Bitmap bitmap = BitmapFactory.decodeStream(is); |
4 | ImageView imageView = (ImageView) findViewById(R.id.image_view); |
5 | imageView.setImageBitmap(bitmap); |
大多数连接网络的Android app会使用HttpURLConnection作为客户端来发送与接受数据。除此之外还可用Apache HttpClient。
1 | HttpClient httpClient = new DefaultHttpClient(); |
2 | HttpGet httpGet = new HttpGet(httpUrl); |
3 | HttpResponse response = httpClient.execute(httpGet); |
5 | int statusCode = response.getStatusLine().getStatusCode(); |
6 | Logs.v( "statusCode >>> :" + statusCode); |
8 | if (statusCode == HttpURLConnection.HTTP_OK) { |
9 | InputStream ins = response.getEntity().getContent(); |
11 | BufferedReader br = new BufferedReader( new InputStreamReader(ins, "utf-8" )); |
13 | StringBuilder sb = new StringBuilder(); |
15 | while ((line = br.readLine()) != null ) { |