Http网络连接处理
这里我们将学习Android程序如何进行网络连接,获取网络返回数据,如果对HTTP网络协议还不了解的可以参考深入理解HTTP协议,在进行网络连接操作前需要先在程序的manifest文件中添加下面的permissions:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
同时要检查当前网络环境是否可用
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (isGpsConnection() || isWiFiConnection()) { //网络连接可用 } else { //网络连接不可用! }
/** * 检查网络连接是否可用 */ public boolean isGpsConnection(){ ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { //网络连接可用 return true; } else { //网络连接不可用! return false; } } public boolean isWiFiConnection(Context inContext) { Context context = inContext.getApplicationContext(); ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (connectivity != null) { NetworkInfo[] info = connectivity.getAllNetworkInfo(); if (info != null) { for (int i = 0; i < info.length; i++) { if (info[i].getTypeName().equals("WIFI") && info[i].isConnected()) { return true; } } } } return false; }
网络操作会遇到不可预期的延迟。显然为了避免一个不好的用户体验,总是在UI Thread之外去执行网络操作。AsyncTask 类提供了一种简单的方式来处理这个问题
doInBackground()) 执行 downloadUrl()方法。Web URL作为参数,方法downloadUrl() 获取并处理网页返回的数据,执行完毕后,传递结果到onPostExecute()。参数类型为String.
onPostExecute()) 获取到返回数据并显示到UI上。
private class DownloadWebpageText extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... urls) { // 参数从execute()方法传入, params[0]表示url. //获取url资源数据并返回 } // onPostExecute方法中处理AsyncTask返回的结果 @Override protected void onPostExecute(String result) { } }
我们来看下完整的实例代码
布局文件activity_httpconnection_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/http_url_edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入URL地址" /> <TextView android:id="@+id/http_content_txt" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/http_get_content_btn" android:layout_width="match_parent" android:onClick="onConnectionClickHandler" android:layout_height="wrap_content" /> </LinearLayout>
原代码 HttpExampleActivity.java
public class HttpExampleActivity extends Activity { private static final String DEBUG_TAG = "HttpExample"; private EditText mUrlText; private TextView mShowMessageTxt; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_httpconnection_layout); mUrlText = (EditText) findViewById(R.id.http_url_edit); mShowMessageTxt = (TextView) findViewById(R.id.http_content_txt); } /** * 用户点击此按钮时执行异步任务,在执行前需检查网络是否可用. * */ public void onConnectionClickHandler(View view) { String stringUrl = mUrlText.getText().toString();// 获取请求的URL从EditText控件中. ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { new DownloadWebpageText().execute(stringUrl); } else { mShowMessageTxt.setText("网络连接不可用!"); } } private class DownloadWebpageText extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... urls) { // 参数从execute()方法传入, params[0]表示url. try { return downloadUrl(urls[0]); } catch (IOException e) { return "Unable to retrieve web page. URL may be invalid."; } } // onPostExecute方法中处理AsyncTask返回的结果 @Override protected void onPostExecute(String result) { mShowMessageTxt.setText(result); } } /** * 根据给定的url地址,建立一个HttpUrlConnection连接它将以流的形式返回页面内容,将流转换成字符串返回 * @param myurl * @return * @throws IOException */ private String downloadUrl(String myurl) throws IOException { InputStream is = null; try { URL url = new URL(myurl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(10000); /*读数据超时*/ conn.setConnectTimeout(15000);/*连接超时*/ conn.setRequestMethod("GET"); /*请求方式*/ conn.setDoInput(true);/* 设置允许输入流*/ conn.connect(); int response = conn.getResponseCode(); Log.d(DEBUG_TAG, "The response is: " + response); is = conn.getInputStream(); String contentAsString = readIt(is); return contentAsString; //关闭InputStream } finally { if (is != null) { is.close(); } } } /** * 将InputStream转换成String返回 * @param stream * @return * @throws IOException * @throws UnsupportedEncodingException */ public String readIt(InputStream stream) throws IOException,UnsupportedEncodingException { Reader reader = new InputStreamReader(stream, "UTF-8"); // 创建包装流 BufferedReader br = new BufferedReader(reader); // 定义String类型用于储存单行数据 String line = null; // 创建StringBuffer对象用于存储所有数据 StringBuffer sb = new StringBuffer(); while ((line = br.readLine()) != null) { sb.append(line); } return sb.toString(); } }
请注意,getResponseCode() 会返回连接状态码( status code). 这是一种获知额外网络连接信息的有效方式。status code 是 200 则意味着连接成功.
Convert the InputStream to a String(把InputStream的数据转换为String)
InputStream 是一种可读的byte数据源。如果你获得了一个 InputStream, 通常会进行decode或者转换为制定的数据类型。例如,如果你是在下载一张image数据,你可能需要像下面一下进行decode:
InputStream is = null; ... Bitmap bitmap = BitmapFactory.decodeStream(is); ImageView imageView = (ImageView) findViewById(R.id.image_view); imageView.setImageBitmap(bitmap);
大多数连接网络的Android app会使用HttpURLConnection作为客户端来发送与接受数据。除此之外还可用Apache HttpClient。
HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(httpUrl); HttpResponse response = httpClient.execute(httpGet); int statusCode = response.getStatusLine().getStatusCode(); Logs.v("statusCode >>> :" + statusCode); if (statusCode == HttpURLConnection.HTTP_OK) { InputStream ins = response.getEntity().getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(ins,"utf-8")); StringBuilder sb = new StringBuilder(); String line = null; while ((line = br.readLine()) != null) { sb.append(line); } }
转载请注明来源:Http网络连接处理