本章講解如何去下載網絡上的一些數據
開發網絡應用的時候 別忘了在AndroidManifest.xml添加網絡權限
- <uses-permission android:name="android.permission.INTERNET" >
網絡操作是一個耗時操作,需要寫在線程中~
一、通過URL來獲取網絡數據
看下代碼 很簡單 通過url對象 獲取輸入流
- //實例化url
- URL url = new URL(
- "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg");
- //通過url獲取輸入流
- InputStream is = url.openStream();
舉個例子 獲取一張網路圖片 然後在對話框中顯示
- Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // TODO Auto-generated method stub
- super.handleMessage(msg);
- ImageView imageView = new ImageView(MainActivity.this);
- imageView.setImageBitmap((Bitmap) msg.obj);
- new AlertDialog.Builder(MainActivity.this).setView(imageView)
- .setPositiveButton("OK", null).show();
- }
- };
- private void getImgWithURL() {
- // TODO Auto-generated method stub
- new Thread() {
- public void run() {
- try {
- //實例化url
- URL url = new URL(
- "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg");
- //通過url獲取輸入流
- InputStream is = url.openStream();
- Message msg = new Message();
- msg.obj = BitmapFactory.decodeStream(is);
- handler.sendMessage(msg);
- //關閉流操作
- is.close();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- };
- }.start();
- }
爲什麼要用到handler呢? 因爲不能在子線程中更新UI
二、通過HttpURLConnection獲取網絡數據
HttpURLConnection是繼承於URLConnection類,二者都是抽象類。其對象主要通過URL的openConnection方法獲得。創建方法如下代碼所示:
- // 實例化url
- URL url = new URL(
- "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg");
- // 打開URL連接
- HttpURLConnection connection = (HttpURLConnection) url
- .openConnection();
HttpURLConnection默認使用GET方式,下面來寫個demo 獲取一張網絡圖片 並顯示
- Handler handler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // TODO Auto-generated method stub
- super.handleMessage(msg);
- ImageView imageView = new ImageView(MainActivity.this);
- imageView.setImageBitmap((Bitmap) msg.obj);
- new AlertDialog.Builder(MainActivity.this).setView(imageView)
- .setPositiveButton("OK", null).show();
- }
- };
- private void getImgWithURL() {
- // TODO Auto-generated method stub
- new Thread() {
- public void run() {
- try {
- // 實例化url
- URL url = new URL(
- "http://imgsrc.baidu.com/forum/w%3D580%3B/sign=3161279c86d6277fe912323018031e30/21a4462309f790522e42f4190df3d7ca7bcbd5bc.jpg");
- // 打開URL連接
- HttpURLConnection connection = (HttpURLConnection) url
- .openConnection();
- // 設置超時
- connection.setConnectTimeout(5 * 1000);
- // 返回的響應碼200,表示成功.
- if (connection.getResponseCode() != 200)
- throw new Exception();
- // 得到網絡返回的輸入流
- InputStream is = connection.getInputStream();
- Message msg = new Message();
- msg.obj = BitmapFactory.decodeStream(is);
- handler.sendMessage(msg);
- //關閉流
- is.close();
- //斷開連接
- connection.disconnect();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- };
- }.start();
- }
下面講下HttpURLconnecttion連接url的步驟
1)創建一個URL對象
URL url = new URL(http://www.baidu.com); 2)利用HttpURLConnection對象從網絡中獲取網頁數據 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 3)設置連接超時 conn.setConnectTimeout(5*1000); 4)對響應碼進行判斷 if (conn.getResponseCode() != 200) //從Internet獲取網頁,發送請求,將網頁以流的形式讀回來 throw new RuntimeException("請求url失敗"); 5)得到網絡返回的輸入流 InputStream is = conn.getInputStream(); 7)is.close();關閉流 |
連接的時候 需要注意的地方:
總結: --記得設置連接超時,如果網絡不好,Android系統在超過默認時間會收回資源中斷操作. --返回的響應碼200,是成功. --在Android中對文件流的操作和JAVA SE上面是一樣的. --在對大文件的操作時,要將文件寫到SDCard上面,不要直接寫到手機內存上. --操作大文件是,要一遍從網絡上讀,一遍要往SDCard上面寫,減少手機內存的使用.這點很重要,面試經常會被問到. --對文件流操作完,要記得及時關閉. |
接下來 我們來講實例
1、獲取網絡上的圖片
這個就不講了 上面的例子已經寫了
2、獲取網頁的代碼
代碼基本和獲取圖片一樣 只不過是將獲取的輸入流轉換成String對象
- InputStream is = connection.getInputStream();
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(is,"gb2312"));
- StringBuffer buffer = new StringBuffer();
- String line ;
- while ((line=reader.readLine()) != null) {
- buffer.append(line);
- }
3、獲取網頁上的xml
獲取輸入流 通過XmlPullParser 解析
4、獲取網頁上的json
獲取輸入流 轉換爲String對象 然後通過JSONTokener來解析
5、單線程下載網絡上的文件,並打印進度
主要和上面的區別就是 需要將得到的輸入流 存儲到文件輸出流中
- public void download() {
- // TODO Auto-generated method stub
- new Thread() {
- public void run() {
- String path = "http://zhangmenshiting.baidu.com/data2/music/2305606/10420691361764861192.mp3?xcode=5e9a399d488f1b03081926d26e957a29";
- try {
- URL url = new URL(path);
- HttpURLConnection connection = (HttpURLConnection) url
- .openConnection();
- connection.setConnectTimeout(5 * 1000);
- if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
- throw new Exception();
- // 獲取輸入流
- InputStream is = connection.getInputStream();
- // 創建文件輸出流
- FileOutputStream fos = new FileOutputStream(
- Environment.getExternalStorageDirectory()
- + "/1.mp3");
- byte buffer[] = new byte[1024 * 4];
- // 獲取文件總長
- float filesize = connection.getContentLength();
- // 記錄已下載長度
- float temp = 0;
- int len = 0;
- while ((len = is.read(buffer)) != -1) {
- // 將字節寫入文件輸出流
- fos.write(buffer, 0, len);
- temp += len;
- System.out.println(temp / filesize * 100 + "%");
- }
- System.err.println("下載完成");
- fos.flush();
- fos.close();
- is.close();
- connection.disconnect();
- } catch (Exception e) {
- // TODO: handle exception
- e.printStackTrace();
- }
- };
- }.start();
- }
實際上很簡單 結束的時候別忘了close流和discontent連接
6、多線程下載網絡上的文件,並打印進度