網絡編程之URL與Http

轉發請註明出處:http://blog.csdn.net/qq_28055429/article/details/52047347

ONE  ------       URL:

一,基本知識:

(1)全稱:Uniform Resource Locator  

(2)中文名: 統一資源定位器

3)組成:協議名,主機,端口和資源(protocol://host:port/resourceName

如:http://www.crazyit.org/index.php

二,基本方法:

String  getFile()------獲取此URL的資源名
String  getHost() :獲取此URL的主機名
String  getPath() :獲取此URL的路徑部分
  Int   getPort() :獲取此URL的端口號
String  getProtocol() :獲取此URL的協議名稱
String  getQuery()   :獲取此URL的查詢字符串部分

下面的兩個方法經常使用:
URLConnection  openConnection():返回一個URLConnection對象,表示到URL所引用的遠程對象的連接。
InputStream  openStream():打開與此URL的連接,並返回一個用於讀取該URL資源的InputStream

三,使用openStream(): 例子:讀取圖片:
(1) 創建URL對象

URL   url  =  new URL(Str);//Str爲你要圖片的網絡地址
(2)用openStream()方法打開輸入流,返回一個InputStream對象
InputStream  is  =  url.openStream();
(3)去執行你想要的結果的相關操作,如讀取圖片:
Bitmap  bitmap  =  BitmapFactory.decodeStream(is);
Msg.obj  =  bitmap ;//這裏把圖片作爲參數,傳給handler,然後去顯示,
 			//發送完後記得關閉流,is.close();

如,將圖片下載到本地:
//創建輸出流,參數:名字,參數2:模式
	OutputStream  os = openFileOutput(“crazyit.pne” , MODE_WORLD_READABLE);
	Byte[]  buff  =  new byte[1024];		//一個字節的度
	Int  hasRead  = 0 ;
	While( ( hasRead  = is.read(buff) )  > 0)	
	{
		Os.write(buff , 0 , hasRead);		//寫入
	}
	Is.close();		//關閉輸入輸出流
	os.close();

四 ,使用URL的openConnection方法來提交請求

步驟一:通過使用URL對象的openConnection()方法來創建URLConnection對象

步驟二:設置URLConnection的參數和普通請求屬性
步驟三:
GET請求 :使用connect方法來建立和遠程資源之間的實際連接
POST請求:需要獲取URLConnection實例對應的輸出流來發送請求參數
步驟四:
  遠程資源變爲可用,程序可訪問遠程資源的頭字段,或通過輸入流讀取遠程資源的數據
 在建立和遠程資源的實際連接之前,可設置請求頭字段:

setAllowUserInteraction :設置該URLConnection的allowUserInteraction請求頭字段的值
  setDoInput  :…….doInput請求頭字段的值
  setDoOutput :…….doOutput請求頭字段的值
  setIfModifiedSince  :  ……..ifModifiedSince請求頭字段的值
  setUseCaches : …..useCaches請求頭字段的值
另外方法: 
 setRequestProperty(String key , String value):設置該URLConnection的key請求頭字段的值爲value(此方法經常用):如,conn.setRequestProperty(“accept” , “*/*”);
  addRequestProperty(String key , String value):爲該URLConnection的key請求頭字段增加value值,該方法不會覆蓋原請求頭字段的值,而是將新增的值追加到原請求頭字段中
當程序資源可用後,出現可用下面方法訪問頭字段和內容:
<pre name="code" class="java">Object getContent(): 獲取該URLConnection的內容
String getHeaderField(String name):獲取指定響應頭字段的值
getInputStream():返回該URLConnection對應的輸入流,用於獲取URLConnection響應的內容
  getOutputStream() :返回該URLConnection對應的輸出流,用於向URLConnection發送請求參數


   附註:     與getHeaderField類型,java提供以下方法訪問特定響應頭字段的值: 

     getContentEncoding -------  獲取content-encoding響應頭字段的值     

     getContentLength   -------  獲取content-length 響應頭字段的值     

     getContentType     -------  獲取content-type 響應頭字段的值 

     getDate()          -------   獲取date響應頭字段的值        

     getExpiration()     ---------   獲取expires響應頭字段的值

     getLastModified()  --------    獲取last-modified響應頭字段的值

<span style="color:#cc0000;">(1)	GET請求</span>
創建URL對象:
		URL  readUrl  = new URL(url);
使用URLConnection打開鏈接
		URLConnection conn  =  readUrl.openConnection();
建立前設置相關屬性,然後用connect()建立實際連接
Conn.setRequestProperty(“accept” , “*/*’);
…..
conn.connect();
實際建立後,可獲取相關響應頭字段值:最後記得關閉流

…….
<span style="color:#cc0000;">(2)	POST請求</span>
創建URL對象:
		URL  readUrl  = new URL(url);
使用URLConnection打開鏈接
		URLConnection conn  =  readUrl.openConnection();
建立前設置相關屬性,獲取輸出流來發送請求參數 
Conn.setRequestProperty(“accept” , “*/*’);
……
conn.setDoOutput(true);
conn.setDoInput(true);   //這兩行是必須的
out  = new PrintWriter(conn.getOutputStream());	//也可通過別的方法來獲取,
out.print(params)
out.flush():
然後,記得關閉兩個流
因爲與下面的HTTP中的HttpURLConnection有密切關係,例子就在HttpURLConnection裏面了(詳見例子2)

TWO   ----   HTTP:

一,基本知識:

(1)全稱:Hypertext transfer protocol

(2)中文意思:超文本傳送協議

(3)解釋:面向應用層的可靠傳輸協議

二,常用有兩種:HttpURLConnection和HttpClient

<1>HttpURLConnection的使用:

基本方法:

int  getResponseCode() :獲取服務器的響應代碼

String getResponseMessage() :獲取服務器的響應消息

String  getRequestMethod():獲取發送請求的方法

void setRequestMethod(String  method) :設置發送請求的方法

具體使用如下:

GET訪問:

一,HttpURLConnection鏈接網絡:

假如得到某個網址:String path = " http:XXXX";

假如是一張圖片網址:String path = "http://p4.so.qhimg.com/t01b4d668163834560e.jpg";

那麼開始鏈接:

(1)用URL把網址封裝

URL   url = new    URL(path) ;

(2)用URL.openConnection()方法打開連接,返回一個URLConnection對象

HttpURLConnection    conn    =  (HttpURLConnection) url.openConnection();

(3)設置請求方法,可以查看ie瀏覽器等,請求爲--GET

<pre name="code" class="java">conn.setRequestMethod("GET");    //設置方法GET


(4)設置時間:

conn.setConnectTimeout(5000);    //客戶端連接服務端的時間
          // conn.setReadTimeout(5000); 設置從服務端下載來本地顯示的時間,
           //如顯示時突然斷網了,圖片剛好顯示一半,那麼這個時候要怎麼處理呢?就是這個時間

(5)設置哪個瀏覽器範圍:

 // conn.setRequestProperty(參數1,參數2);設置連接的瀏覽器,可以通過ie等查看

(6)獲取返回碼:200代表正常, 400----錯誤請求 , 404----找不到

int result =  conn.getResponseCode();     //得到返回碼,200正常,

(7)然後開始處理

if(result    ==  200){
               //獲取輸入流對象
               InputStream is =  conn.getInputStream();
               //利用BitmapFactory.decodeStream()方法得到Bitmap對象,該方法接受一個InputStream對象
               Bitmap   bitmap  =   BitmapFactory.decodeStream(is);
               imageView.setImageBitmap(bitmap);
           }
           else {
               Toast.makeText(this , "顯示圖片失敗" , Toast.LENGTH_SHORT).show();
           }

這段代碼是有問題的,因爲在android4.0之後就不允許在主線程訪問網絡,,

具體例子:訪問圖片

佈局文件activity_layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/ig_view"
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <EditText
        android:text=""
        android:singleLine="true"
        android:hint="請輸入網址"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_view"/>
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="瀏覽"
        android:id="@+id/button"
        android:onClick="find_photo"/>
</LinearLayout>


主類:MainActivity

public class MainActivity extends AppCompatActivity {
    private EditText editText ;
    private ImageView imageView ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        

        editText    =   (EditText)findViewById(R.id.et_view);
        imageView   =   (ImageView)findViewById(R.id.ig_view);

    }
   public void  find_photo(View view){
        String str_txt  =   editText.getText().toString().trim() ;
       try {
           //包裝成URL對象
           URL url = new URL(str_txt);
           //用url.openConnection()打開連接,返回一個URLConnection對象,
           //因爲前面用URL包裝,故而用HttpURL,還有別的種類,如https等
           HttpURLConnection    conn    =  (HttpURLConnection) url.openConnection();
           conn.setRequestMethod("GET");    //設置方法GET
           conn.setConnectTimeout(5000);    //客戶端連接服務端的時間
          // conn.setReadTimeout(5000); 設置從服務端下載來本地顯示的時間,
           //如顯示時突然斷網了,圖片剛好顯示一半,那麼這個時候要怎麼處理呢?就是這個時間
          // conn.setRequestProperty(參數1,參數2);設置連接的瀏覽器,可以通過ie等查看
          int result =  conn.getResponseCode();     //得到返回碼,200正常,
           if(result    ==  200){
               //獲取輸入流對象
               InputStream is =  conn.getInputStream();
               //利用BitmapFactory.decodeStream()方法得到Bitmap對象,該方法接受一個InputStream對象
               Bitmap   bitmap  =   BitmapFactory.decodeStream(is);
               imageView.setImageBitmap(bitmap);
           }
           else {
               Toast.makeText(this , "顯示圖片失敗" , Toast.LENGTH_SHORT).show();
           }
       }catch (Exception e){
           e.printStackTrace();
           Toast.makeText(this , "獲取圖片失敗" , Toast.LENGTH_SHORT).show();
       }
    }
}


記得添加網絡權限:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

結果:如果你是在android4.0之後的,會出現,訪問失敗

如果不是則沒問題:

這個時候,你可能說,那就在子線程訪問網絡啊,new一個線程

代碼:

public void  find_photo(View view){
        final  String str_txt  =   editText.getText().toString().trim() ;
        new   Thread(){
            @Override
            public void run() {
                try {
                    //包裝成URL對象
                    URL url = new URL(str_txt);
                    //用url.openConnection()打開連接,返回一個URLConnection對象,
                    //因爲前面用URL包裝,故而用HttpURL,還有別的種類,如https等
                    HttpURLConnection    conn    =  (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");    //設置方法GET
                    conn.setConnectTimeout(5000);    //客戶端連接服務端的時間
                    // conn.setReadTimeout(5000); 設置從服務端下載來本地顯示的時間,
                    //如顯示時突然斷網了,圖片剛好顯示一半,那麼這個時候要怎麼處理呢?就是這個時間
                    // conn.setRequestProperty(參數1,參數2);設置連接的瀏覽器,可以通過ie等查看
                    int result =  conn.getResponseCode();     //得到返回碼,200正常,
                    if(result    ==  200){
                        //獲取輸入流對象
                        InputStream is =  conn.getInputStream();
                        //利用BitmapFactory.decodeStream()方法得到Bitmap對象,該方法接受一個InputStream對象
                        Bitmap   bitmap  =   BitmapFactory.decodeStream(is);
                        imageView.setImageBitmap(bitmap);
                    }
                    else {
                        Toast.makeText(MainActivity.this , "顯示圖片失敗" , Toast.LENGTH_SHORT).show();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    Toast.makeText(MainActivity.this , "獲取圖片失敗" , Toast.LENGTH_SHORT).show();
                }
            }
        }.start();

    }
結果:沒反應,過一會兒,提示:XX應用已經停止應用
因爲,安卓4.0後不允許在子線程中更新UI,只能在主線程更新UI)

那麼怎麼辦呢,請看下面:

二,解決主線程不能範圍網絡的方法:兩種
第一種:(不推薦)  

 //注意在Android 4.0之後系統強制性的不允許在主線程訪問網絡,否則會出現android.os.NetworkOnMainThreadException異常,
        //常用解決辦法是:在onCreat()方法的setContentView()語句之後添加以下句子,此處就加在這裏吧
        if(android.os.Build.VERSION.SDK_INT > 9){
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
       }

第二種:利用Handler機制:(子線程訪問網絡,主線程更新UI)

1,基本知識:理解Handler的機制,如圖



理解:

(1)先在主線程中創建一個Handler對象,如下:

private Handler handler =  new Handler(){ };

(2)在子線程中處理數據,並利用handler.sendMessage(message);發送消息,如下:

if(result    ==  200){
                        //獲取輸入流對象
                        InputStream is    =  conn.getInputStream();
                        //利用BitmapFactory.decodeStream()方法得到Bitmap對象,該方法接受一個InputStream對象
                        Bitmap   bitmap   =   BitmapFactory.decodeStream(is);
                        Message  message  =   new Message();
                        message.what      =     CHANGE_UI ;     //設置訪問類型,int類型值,自定義CHANGE_UI = 1;
                        message.obj       =     bitmap ;     //設置message的數據
                        handler.sendMessage(message);
                    }

(3)主線程中的Handler會把消息放入message queue,一旦message queue有消息,looper便會循環取出消息,調用

handleMessage()方法來處理消息:代碼如下:

private Handler handler =  new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1){ //判斷消息的類型
                Bitmap  bt  =  (Bitmap) msg.obj; //取出數據
                imageView.setImageBitmap(bt);
            }
        }
    };

完整代碼:

package phototest.maiyu.cai;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

public class MainActivity extends AppCompatActivity {
    private EditText editText ;
    private ImageView imageView ;
    private static int CHANGE_UI = 1;
    private static int ERROR_UI  = 2;
    private Handler handler =  new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1){ //判斷消息的類型
                Bitmap  bt  =  (Bitmap) msg.obj; //取出數據
                imageView.setImageBitmap(bt);
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText    =   (EditText)findViewById(R.id.et_view);
        imageView   =   (ImageView)findViewById(R.id.ig_view);

    }
   public void  find_photo(View view){
        final  String str_txt  =   editText.getText().toString().trim() ;
        new   Thread(){
            @Override
            public void run() {
                try {
                    //包裝成URL對象
                    URL url = new URL(str_txt);
                    //用url.openConnection()打開連接,返回一個URLConnection對象,
                    //因爲前面用URL包裝,故而用HttpURL,還有別的種類,如https等
                    HttpURLConnection    conn    =  (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");    //設置方法GET
                    conn.setConnectTimeout(5000);    //客戶端連接服務端的時間
                    // conn.setReadTimeout(5000); 設置從服務端下載來本地顯示的時間,
                    //如顯示時突然斷網了,圖片剛好顯示一半,那麼這個時候要怎麼處理呢?就是這個時間
                    // conn.setRequestProperty(參數1,參數2);設置連接的瀏覽器,可以通過ie等查看
                    int result =  conn.getResponseCode();     //得到返回碼,200正常,
                    if(result    ==  200){
                        //獲取輸入流對象
                        InputStream is    =  conn.getInputStream();
                        //利用BitmapFactory.decodeStream()方法得到Bitmap對象,該方法接受一個InputStream對象
                        Bitmap   bitmap   =   BitmapFactory.decodeStream(is);
                        Message  message  =   new Message();
                        message.what      =     CHANGE_UI ;     //設置訪問類型,int類型值,自定義CHANGE_UI = 1;
                        message.obj       =     bitmap ;     //設置message的數據
                        handler.sendMessage(message);
                    }
                    else {
                        Toast.makeText(MainActivity.this , "顯示圖片失敗" , Toast.LENGTH_SHORT).show();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    Toast.makeText(MainActivity.this , "獲取圖片失敗" , Toast.LENGTH_SHORT).show();
                }
            }
        }.start();

    }
}
輸入正確圖片地址:就會出現一張圖片了

但是如果地址錯誤,又會出現:該應用已經停止運行,,,

原因:還是在子線程處理了UI

else {
                        Toast.makeText(MainActivity.this , "顯示圖片失敗" , Toast.LENGTH_SHORT).show();
                    }

更改如下:

 else {
                        Message  message  =   new Message();
                        message.what      =     ERROR_UI ;     //設置訪問類型,int類型值,自定義ERROR_UI=2;
                        handler.sendMessage(message);
                    }
在Handler的handleMessage()方法中添加:

else if(msg.what    ==  ERROR_UI){
                Toast.makeText(MainActivity.this , "顯示圖片失敗" ,Toast.LENGTH_SHORT).show();
            }
完整代碼:

<pre name="code" class="java">package phototest.maiyu.cai;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

public class MainActivity extends AppCompatActivity {
    private EditText editText ;
    private ImageView imageView ;
    private static int CHANGE_UI = 1;
    private static int ERROR_UI  = 2;
    private Handler handler =  new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == CHANGE_UI){ //判斷消息的類型
                Bitmap  bt  =  (Bitmap) msg.obj; //取出數據
                imageView.setImageBitmap(bt);
            }
            else if(msg.what    ==  ERROR_UI){
                Toast.makeText(MainActivity.this , "顯示圖片失敗" ,Toast.LENGTH_SHORT).show();
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText    =   (EditText)findViewById(R.id.et_view);
        imageView   =   (ImageView)findViewById(R.id.ig_view);

    }
   public void  find_photo(View view) {
       final String str_txt = editText.getText().toString().trim();
       if (!TextUtils.isEmpty(str_txt)) {
           new Thread() {
               @Override
               public void run() {
                   try {
                       //包裝成URL對象
                       URL url = new URL(str_txt);
                       //用url.openConnection()打開連接,返回一個URLConnection對象,
                       //因爲前面用URL包裝,故而用HttpURL,還有別的種類,如https等
                       HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                       conn.setRequestMethod("GET");    //設置方法GET
                       conn.setConnectTimeout(5000);    //客戶端連接服務端的時間
                       // conn.setReadTimeout(5000); 設置從服務端下載來本地顯示的時間,
                       //如顯示時突然斷網了,圖片剛好顯示一半,那麼這個時候要怎麼處理呢?就是這個時間
                       // conn.setRequestProperty(參數1,參數2);設置連接的瀏覽器,可以通過ie等查看
                       int result = conn.getResponseCode();     //得到返回碼,200正常,
                       if (result == 200) {
                           //獲取輸入流對象
                           InputStream is = conn.getInputStream();
                           //利用BitmapFactory.decodeStream()方法得到Bitmap對象,該方法接受一個InputStream對象
                           Bitmap bitmap = BitmapFactory.decodeStream(is);
                           Message message = new Message();
                           message.what = CHANGE_UI;     //設置訪問類型,int類型值,自定義CHANGE_UI = 1;
                           message.obj = bitmap;     //設置message的數據
                           handler.sendMessage(message);
                       } else {
                           Message message = new Message();
                           message.what = ERROR_UI;     //設置訪問類型,int類型值,自定義ERROR_UI=2;
                           handler.sendMessage(message);
                       }
                   } catch (Exception e) {
                       e.printStackTrace();
                       Toast.makeText(MainActivity.this, "獲取圖片失敗", Toast.LENGTH_SHORT).show();
                   }
               }
           }.start();
       }
       else{
           Toast.makeText(MainActivity.this, "路徑不能爲空" , Toast.LENGTH_SHORT).show();
       }
   }
}


結果:

當地址不正確時,Toast提示,

當正確時,出現圖片

附加一張效果圖:

如果要訪問顯示網址源代碼,可以這樣解析:

public class StreamTools {
    public static String readInputStream(InputStream is){
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int len = 0;
            byte[] buffer = new byte[1024] ;
            while((len = is.read(buffer)) != -1){
                baos.write(buffer , 0 , len);

            }
            is.close();
            baos.close();
            byte[] result = baos.toByteArray();
            return new String(result);

        }catch (Exception e){
            e.printStackTrace();
            return "錯誤";
        }
    }
}

POST訪問:見例子代碼:

例子2:

佈局:activity_httpurlconn:採用線性佈局,放置一個TextView用於提示,兩個按鈕(get和post),

一個ScrollView(裏面放置一個TextView)用於顯示內容

代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- 定義基本佈局:LinearLayout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <!-- 提示的TextView -->
    <TextView
        android:id="@+id/TextView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/tv_httpurlconn" >
    </TextView>

    <!-- get請求 -->
    <Button
        android:id="@+id/Button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn01_httpurlconn" >
    </Button>

    <!-- post請求 -->
    <Button
        android:id="@+id/Button02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn02_httpurlconn" >
    </Button>
    <!-- ScrollView:裏面放置一個TextView用於顯示響應的結果 -->
    <ScrollView
        android:id="@+id/ScrollView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
        <TextView
            android:id="@+id/TextView02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </TextView>
    </ScrollView>

</LinearLayout>
字符串資源:

    <string name="tv_httpurlconn">HttpURLConnection網絡測速</string>
    <string name="btn01_httpurlconn">get請求手機網站</string>
    <string name="btn02_httpurlconn">post請求CSDN博客</string>
主類:代碼如下:

package com.example.s08_01.activity;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.s08_01.R;

public class HttpURLConnectionActivity extends Activity {

	private TextView tv = null; // 定義TextView
	private Button httpget, httppost;// 定義get按鈕和post按鈕
	private String googleWeatherUrl =  "http://3g.renren.com/login.do";
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == 1) {
				Toast.makeText(getApplicationContext(), "連接手機網站成功!",
						Toast.LENGTH_SHORT).show();
				String str = (String) msg.obj;
				tv.setText(str);
			} else if (msg.what == 2) {
				Toast.makeText(getApplicationContext(), "連接手機網站失敗",
						Toast.LENGTH_SHORT).show();
			} else if (msg.what == 3) {
				Toast.makeText(getApplicationContext(), "連接CSDN博客成功!",
						Toast.LENGTH_SHORT).show();
				String str = (String) msg.obj;
				tv.setText(str);
			} else if (msg.what == 4) {
				Toast.makeText(getApplicationContext(), "連接CSDN博客失敗",
						Toast.LENGTH_SHORT).show();
			}
		};
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_httpurlconn);
		findView(); // 爲控件綁定ID
		setListener(); // 爲控件設置監聽
	}

	// 爲控件設置監聽
	private void setListener() {
		// get請求
		httpget.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new Thread() {
					public void run() {
						urlGetConn(); // 新開線程去請求
					};
				}.start();
			}
		});

		// post請求
		httppost.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new Thread() {
					public void run() {
						urlPostConn(); // 主線程請求
					};
				}.start();
			}
		});

	}

	// 爲控件綁定ID
	private void findView() {
		tv = (TextView) findViewById(R.id.TextView02);
		httpget = (Button) findViewById(R.id.Button01);
		httppost = (Button) findViewById(R.id.Button02);
	}

	// 使用URLConnection get連接GoogleWeatherAPI
	protected void urlGetConn() {
		Message msg = new Message(); // 創建Message對象
		try {
			// 創建URL對象,並傳入地址
			URL url = new URL(googleWeatherUrl);
			// 用URL的openConnection()方法打開連接,並獲取HttpURLConnection
			HttpURLConnection httpconn = (HttpURLConnection) url
					.openConnection();
			// 若請求結果成功
			if (httpconn.getResponseCode() == HttpURLConnection.HTTP_OK) {

				// InputStreamReader
				InputStreamReader isr = new InputStreamReader(
						httpconn.getInputStream(), "utf-8");
				int i;
				String content = "";
				// read
				while ((i = isr.read()) != -1) {
					content = content + (char) i;
				}
				msg.obj = content;
				msg.what = 1;
				handler.sendMessage(msg);
				isr.close();
				// 設置TextView
			}
			// disconnect
			httpconn.disconnect();
		} catch (Exception e) {
			msg.what = 2;
			handler.sendMessage(msg);
		}
	}

	public void urlPostConn() {
		String httpUrl = "http://www.csdn.net/";
		String resultData = "";
		URL url = null;
		Message msg = new Message();
		try {
			// 創建URL對象
			url = new URL(httpUrl);
		} catch (MalformedURLException e) {
			msg.what = 2;
			handler.sendMessage(msg);
		}
		if (url != null) {
			try {
				// 使用HttpURLConnection打開連接
				HttpURLConnection urlConn = (HttpURLConnection) url
						.openConnection();
				
				// 因爲要求使用Post方式提交數據,需要設置爲true
				urlConn.setDoOutput(true);
				urlConn.setDoInput(true);
				
				// 設置以Post方式,注意此處的“POST”必須大寫
				urlConn.setRequestMethod("POST");
				
				// Post 請求不能使用緩存
				urlConn.setUseCaches(false);
				urlConn.setInstanceFollowRedirects(true);
				
				// 配置本次連接的Content-Type,配置爲application/x-www-form-urlencoded
				urlConn.setRequestProperty("Content-Type",
						"application/x-www-form-urlencoded");
				// 連接,從postUrl.openConnection()至此的配置必須在connect之前完成
				// 要注意的事connection.getOutputStream會隱含地進行connect。
				urlConn.connect();

				// DataOutputStream流上傳數據
				DataOutputStream out = new DataOutputStream(
						urlConn.getOutputStream());
				// 要上傳的參數
				String content = "par="
						+ URLEncoder.encode("POSTTransferData", "gb2312");
				// 將要上傳的內容寫入流中
				out.writeBytes(content);
				// 刷新,關閉
				out.flush();
				out.close();
				// 得到讀取的數據
				InputStreamReader in = new InputStreamReader(
						urlConn.getInputStream());
				BufferedReader buffer = new BufferedReader(in);
				String str = null;
				while ((str = buffer.readLine()) != null) {
					resultData += str + "\n";
				}
				in.close();
				urlConn.disconnect();

				msg.obj = resultData;
				msg.what = 3;
				handler.sendMessage(msg);

			} catch (IOException e) {
				msg.what = 4;
				handler.sendMessage(msg);
			}
		}// if(url!=null)
		else {
			msg.what = 4;
			handler.sendMessage(msg);
		}
	}

}
記得添加網絡權限:

 <uses-permission android:name="android.permission.INTERNET" />
結果:略,,,

增強版的HttpURLConnection      --------- >>     HttpClient的使用:

(1)創建HttpClient對象

(2)設置GET請求(創建HttpGet對象)或者設置POST請求(創建HttpPost對象)

(3)設置請求參數:

GET  ---  setParams(HttpParams  params)

POST ----setParams(HttpParams params)或者setEntity(HttpEntity  entity)方法

(4)調用HttpClient對象的execute(HttpUriRequest  request)發送請求,返回一個HttpResponse對象

(5)調用HttpResponse的

                      ------getAllHeaders(),getHeaders(String name)獲取服務器的請求頭

   -----getEntity()獲取HttpEntity對象(裏面包含了服務器的響應內容),可通過該對象獲取服務器的響應內容,如:String result = EntityUtils.toString(httpResponse.getEntity())

可以得到結果,


下面例子用get和post方法來訪問百度首頁:

佈局文件:activity_httpclient:常用LinearLayout,裏面放置一個TextView用於提示,兩個按鈕(get請求和post請求),

和一個ScrollView(裏面放置一個TextView)用於顯示響應的內容:

<?xml version="1.0" encoding="utf-8"?>
<!-- 定義基本佈局:LinearLayout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
	<!-- 文本提示 -->
    <TextView
        android:id="@+id/TextView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/httpclient_tv01" >
    </TextView>

    <!-- GET訪問按鈕 -->
    <Button
        android:id="@+id/Button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/httpclient_btn01" >
    </Button>
   <!-- POST訪問按鈕 -->
    <Button
        android:id="@+id/Button02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/httpclient_btn02" >     
    </Button>
   <!-- 定義ScrollView(裏面放置TextView)用來顯示結果 -->
    <ScrollView
        android:id="@+id/ScrollView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/TextView02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </TextView>
    </ScrollView>

</LinearLayout>

字符串資源:

    <string name="httpclient_tv01">HttpClient網絡測速</string>
    <string name="httpclient_btn01">Get訪問百度</string>
    <string name="httpclient_btn02">POST訪問百度</string>

主類:採用handler+message去處理訪問網絡,具體代碼如下:

package com.example.s08_01.activity;

import org.apache.http.HttpResponse;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.s08_01.R;

public class HttpClientActivity extends Activity {
	private TextView tv = null; // 定義文本顯示內容
	private String testUrl = "http://www.baidu.com"; // 定義百度地址
	private Button httpget, httppost; // 定義按鈕

	// 創建線程,重寫handleMessage方法
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == 1) { // msg.what爲1時,表示請求成功
				Toast.makeText(getApplicationContext(), "連接成功!",
						Toast.LENGTH_SHORT).show(); // Toast提示
				// 設置TextView
				String str = (String) msg.obj; // 把傳回來的參數轉化爲字符串類型,然後顯示出來
				tv.setText(str);
			} else if (msg.what == 2) { // 連接失敗
				Toast.makeText(getApplicationContext(), "連接失敗",
						Toast.LENGTH_SHORT).show();
				tv.setText("鏈接失敗 ");
			}
		};
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_httpclient);
		findView(); // 爲控件綁定ID
		setListener(); // 爲控件設置監聽
	}

	//爲控件設置監聽
	private void setListener() {
		//get請求監聽
		httpget.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new Thread() {			//創建子線程,
					public void run() {
						httpClientGet();	//get請求
					};
				}.start();

			}
		});

		//post請求監聽
		httppost.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new Thread() {		//創建子線程
					public void run() {
						httpClientPost();	//post請求
					};
				}.start();

			}
		});

	}

	//爲控件綁定id
	private void findView() {
		tv = (TextView) findViewById(R.id.TextView02);
		httpget = (Button) findViewById(R.id.Button01);
		httppost = (Button) findViewById(R.id.Button02);
	}

	//get請求
	protected void httpClientGet() {
		// 創建DefaultHttpClient對象
		DefaultHttpClient httpclient = new DefaultHttpClient();
		// 設置爲GET請求:即創建HttpGet對象
		HttpGet httpget = new HttpGet(testUrl);
		// 創建ResponseHandler
		//ResponseHandler<String> responseHandler = new BasicResponseHandler();
		Message message = new Message();	//創建Message對象

		try {
			
			//調用HttpClient的execute方法發送請求,返回一個HttpResponse對象		
			HttpResponse httpResponse = httpclient.execute(httpget);	
			// 發送請求並獲取反饋
			// 解析返回的內容
			//調用HttpResponse的getEntity()方法獲取HttpEntity對象(裏面包裝了服務內容)
			String content = EntityUtils.toString(httpResponse.getEntity());  
			//獲取內容
			//String content = httpclient.execute(httpget, responseHandler);
			message.obj = content;	//設置參數obj,what,
			message.what = 1;
			handler.sendMessage(message);	//發送給主線程

		} catch (Exception e) {
			//錯誤
			message.what = 2;
			handler.sendMessage(message);

		}
		httpclient.getConnectionManager().shutdown();
	}

	//post請求
	protected void httpClientPost() {
		Message message = new Message();
		try {
			DefaultHttpClient httpclient = new DefaultHttpClient();  //創建DefaultHttpClient對象
			HttpPost httppost = new HttpPost(testUrl);				//設置爲POST請求:即創建HttpPost對象
			HttpResponse httpResponse = httpclient.execute(httppost);	//調用HttpClient的execute方法發送請求,返回一個HttpResponse對象		
			// 發送請求並獲取反饋
			// 解析返回的內容
			String result = EntityUtils.toString(httpResponse.getEntity());  //調用HttpResponse的getEntity()方法獲取HttpEntity對象(裏面包裝了服務內容)
			message.what = 1;
			message.obj = result;
			handler.sendMessage(message);

		} catch (Exception e) {
			message.what = 2;
			handler.sendMessage(message);
		}
	}
}

記得添加網絡權限:

       <!-- 授予訪問互聯網權限 -->
    <uses-permission android:name="android.permission.INTERNET" />

然後,結果就出來了...略






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章