Android應用與服務器的橋梁-HttpUrlConnection


1. 實例化URL對象

首先第一步實例化一個URL對象,傳入參數為請求的數據的網址。

URL url = new URL("http://www.imooc.com/api/teacher?type=3&cid=1");

2. 獲取HttpURLConnection對象

調用URL對象的openConnection方法將返回一個URLConnection對象,而URLConnection類為HttpURLConnection類的父類,可強制轉換為我們需要的HttpURLConnection對象。

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

3. 設置請求連接屬性

可通過第二步獲取的HttpURLConnection對象設置連接的屬性,例如setRequestMethod設置連接類型“GET”或“POST”、setReadTimeout設置讀取超時時限等等。

conn.setRequestMethod("GET");
conn.setReadTimeout(6000);

4. 獲取響應碼

響應碼用於確認是否連接結果,若返回值為HttpURLConnection.HTTP_OK(200)則連接成功。

conn.getResponesCode();

5. 讀取並解析輸入流

通過HttpURLConnection對象可以獲取到一個輸入流,選取適當的方式將輸入流的內容讀取到本地,再進行解析。

可以直接用JSONObject進行解析,也可以用第三方框架,推薦使用gson。

if (conn.getResponesCode() == 200) {
    InputStream in = conn.getInputStream();
    byte[] b = new byte[1024 * 512];
    int len = 0;
    
    //建立緩存流,保存所讀取的字節數組
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    while ((len = in.read(b)) > -1) {
        baos.write(b, 0, len);
    }
    String msg = baos.toString();
    
    //解析數據
    JSONObject obj = new JSONObject(msg);
    JSONObject data = obj.getJSONObject("data");
    String title = data.getString("title");
    String author = data.getString("author");
    String content = data.getString("content");
}

gson解析數據簡單介紹:

(1)gson解析普通json對象:gson的使用依賴於JSONObject,通過JSONObject對象的getString方法,以字符串形式獲取相應數據,而后將其解析為指定類。

String data = obj.getString("data");//obj為JSONObject對象
Gson gson = new Gson();
Essay e = gson.fromJson(data, Essay.class);//第一個參數為json對象形式的字符串,第二個參數為自定義的類,需要將json對象解析成什么類型,就傳入相應的類

(2)gson解析數組形式數據:

解析數組形式的數據,步驟與普通json對象基本一致,不同的是,這里fromJson方法的第一個參數為滿足json數組形式的字符串,第二個參數則為一個Type對象,而Type對象需通過TypeToken對象的getType方法獲取。

獲取Type對象:new TypeToken<ArrayList >(){}.getType(),TypeToken的泛型決定數據解析為什么類型,數組形式的數據一般解析為List,而List的泛型為每一個數組元素對應的類, 要注意類的屬性名需要與json數組中每一項里面的key值保持一致

String data = new JSONObject(result).getString("data");//result為未解析的json字符串
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<Essay>>(){}.getType();
ArrayList<Essay> e = gson.fromJson(data, listType);

6. 將數據傳遞回主線程

由於網絡操作不能在主線程中進行,而子線程又不允許對UI進行操作,因此需要將解析的數據傳遞回主線程。

通過使用Handler和Message進行線程之間的通信,代碼請看下方完整例子。

7. 完整案例

布局xml:

<?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"
    tools:context="com.studying.network.DetailActivity">

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:gravity="center"
        android:textSize="24sp" />

    <TextView
        android:id="@+id/author"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:gravity="right"
        android:paddingRight="10dp"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="8dp"
        android:layout_marginTop="15dp"
        android:layout_weight="1"
        android:lineSpacingMultiplier="1.5"
        android:textSize="20sp" />

</LinearLayout>

Activity:

public class DetailActivity extends Activity {

    private TextView titleView, authorView, contentView;
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            Essay essay = (Essay) msg.obj;
            titleView.setText(essay.getTitle());
            authorView.setText(essay.getAuthor());
            contentView.setText(essay.getContent());
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);

        initView();
        initData();
    }

    public void initView() {
        titleView = (TextView) findViewById(R.id.title);
        authorView = (TextView) findViewById(R.id.author);
        contentView = (TextView) findViewById(R.id.content);
    }

    public void initData() {
        //網絡操作不能在主線程中進行
        new Thread(){
            @Override
            public void run() {
                try {
                    URL url = new URL("http://www.imooc.com/api/teacher?type=3&cid=1");
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");
                    conn.setReadTimeout(6000);

                    //獲取響應碼的同時會連接網絡
                    if (conn.getResponseCode() == 200) {
                        InputStream in = conn.getInputStream();
                        byte[] b = new byte[512 * 1024];
                        int len = 0;

                        //將輸入流的內容轉存到字節數組流中
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        while ((len = in.read(b)) > -1){
                            baos.write(b, 0, len);
                        }
                        String result = baos.toString();

                        //解析數據
                        JSONObject obj = new JSONObject(result);
                        JSONObject data = obj.getJSONObject("data");
                        String title = data.getString("title");
                        String author = data.getString("author");
                        String content = data.getString("content");

                        //通過Message將數據傳遞回主線程
                        Message message = handler.obtainMessage();
                        Essay essay = new Essay(title, author, content);//Essay為自定義類,用於傳遞多個值
                        message.obj = essay;
                        handler.sendMessage(message);//調用這個方法,會觸發主線程中Handler對象里的handleMessage方法

                        conn.disconnect();
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
}

Essay:

public class Essay {

    private String title, author, content;

    public Essay(String title, String author, String content) {
        this.title = title;
        this.author = author;
        this.content = content;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM