Android HTTP網絡編程(例子)

HTTP網絡編程

1、關於HTTP協議:

參考鏈接:https://www.runoob.com/w3cnote/android-tutorial-http.html

1)什麼是Http協議?
hypertext transfer protocol(超文本傳輸協議),TCP/IP協議的一個應用層協議,用於 定義WEB瀏覽器與WEB服務器之間交換數據的過程。客戶端連上web服務器後,若想獲得web服務器 中的某個web資源,需遵守一定的通訊格式,HTTP協議用於定義客戶端與web服務器通迅的格式。

2)Http 1.0 與 Http 1.1的區別
1.0協議,客戶端與web服務器建立連接後,只能獲得一個web資源! 而1.1協議,允許客戶端與web服務器建立連接後,在一個連接上獲取多個web資源!

3)Http協議的底層工作流程:
我們先要知道兩個名詞:

SYN(synchronous):TCP/IP建立連接時使用的握手信號
ACK(Acknowledgement):確認字符,確認發來的數據已經接受無誤

接着就到TCP/IP三次握手的概念:

客戶端發送syn包(syn = j)到服務器,進入SYN_SEND狀態,然後等待服務器確認
服務器收到syn包,確認客戶的syn(ack = j + 1),同時在自己也發送一個SYN包(syn=k), 即SYN + ACK包,服務器進入SYN_RECV狀態
客戶端收到SYN + ACK包,向服務器發送確認包ACK(ack = k +1),發送完畢後,客戶端與服務端 進入ESTABLISHED狀態,完成三次握手,然後兩者開始傳送數據

4)Http的幾種請求方式
實際開發中我們用得較多的方式是Get和Post,但是實際開發可能還會用到其他請求方式,比如PUT, 小豬的實際項目中就用到了,下面爲了方便大家,就把所有的請求方式列出來吧:

請求方式 解釋
Get 請求獲取Request-URI所標識的資源
POST 在Request-URI所標識的資源後附加新的數據
HEAD 請求獲取由Request-URI所標識的資源的響應信息報頭
PUT 請求服務器存儲一個資源,並用Request-URI作爲其標識
DELETE 請求服務器刪除Request-URI所標識的資源
TRACE 請求服務器回送收到的請求信息,主要用於測試或診斷
CONNECT 保留將來使用
OPTIONS 請求查詢服務器的性能,或者查詢與資源相關的選項

5)Get和Post的對比
用得最多的兩個,當然要做下對比啦!

GET:在請求的URL地址後以?的形式帶上交給服務器的數據,多個數據之間以&進行分隔, 但數據容量通常不能超過2K,比如:http://xxx?username=…&pawd=…這種就是GET

POST: 這個則可以在請求的實體內容中向服務器發送數據,傳輸沒有數量限制

另外要說一點,這兩個玩意都是發送數據的,只是發送機制不一樣,不要相信網上說的 “GET獲得服務器數據,POST向服務器發送數據”!!另外GET安全性非常低,Post安全性較高, 但是執行效率卻比Post方法好,一般查詢的時候我們用GET,數據增刪改的時候用POST!!

6)Http狀態碼合集
當然,這些狀態碼只是要給參考,實際上決定權在服務器端(後臺的)手上,一種方案是請求後, 服務器返回給我們的是狀態,或者另一種,在應用不用弄多語言版本的時候最好用,直接返回 一串結果信息的Json給我們,我們直接顯示就好,這樣可以偷懶不少!下面列下狀態碼合集,參考 下就好:

100~199 成功接受請求,客戶端需提交下一次請求才能完成整個處理過程
200 OK,客戶端請求成功
300~399 請求資源已移到新的地址(302,307,304)
401 請求未授權,改狀態代碼需與WWW-Authenticate報頭域一起使用
403 Forbidden,服務器收到請求,但是拒絕提供服務
404 Not Found,請求資源不存在,這個就不用說啦
500 Internal Server Error,服務器發生不可預期的錯誤
503 Server Unavailable,服務器當前不能處理客戶端請求,一段時間後可能恢復正常

8)Http協議的特點
概念性的東西,知道就好,別去背,百度百科的東西,直接複製粘貼:

  1. 支持客戶/服務器模式。

  2. 簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、 HEAD、POST。每種方法規定了客戶與服務器聯繫的類型不同。 由於HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。

  3. 靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。

  4. 無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求, 並收到客戶的應答後,即斷開連接。採用這種方式可以節省傳輸時間。

  5. 無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。 缺少狀態意味着如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每 次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

2、Android的例子
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/ll_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="10dp"
        android:orientation="horizontal">
        <EditText
            android:id="@+id/et_path"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginRight="3dp"
            android:layout_weight="1"
            android:background="#EBEBEB"
            android:hint="請輸入圖片路徑"
            android:inputType="textUri"
            android:textColor="#696969"
            android:textSize="20sp"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="4"
            android:background="#EBEBEB"
            android:onClick="click"
            android:text="瀏覽"
            android:textColor="#696969"
            android:textSize="20sp"/>

    </LinearLayout>
    <ImageView
        android:id="@+id/iv_pic"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/ll_text"
        android:scaleType="centerCrop"
        />

</RelativeLayout>

MainActivity.java

package com.example.imageview;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

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

public class MainActivity extends AppCompatActivity {

    private static final int CHANGE_UI = 1;
    private static final int ERROR = 2;
    private HttpURLConnection conn;
    private EditText et_path;
    private ImageView ivPic;
    //主線程創建消息處理器
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            if (msg.what == CHANGE_UI){
                Bitmap bitmap = (Bitmap) msg.obj;
                ivPic.setImageBitmap(bitmap);
            }else if (msg.what == ERROR){
                Toast.makeText(MainActivity.this,"顯示圖片出錯",Toast.LENGTH_SHORT).show();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_path = (EditText)findViewById(R.id.et_path);
        ivPic = (ImageView) findViewById(R.id.iv_pic);
        et_path.setText("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1587640176485&di=ca11aae1037813a70d1eec6ba10bab77&imgtype=0&src=http%3A%2F%2Fimage.biaobaiju.com%2Fuploads%2F20190703%2F16%2F1562142769-jXfDyGVLNg.jpeg");
    }

    public void click(View view){
        final String path = et_path.getText().toString().trim();
        if (TextUtils.isEmpty(path)){
            Toast.makeText(this,"圖片路徑不能爲空",Toast.LENGTH_SHORT).show();
        }else{
            //子線程中請求網絡,Android4.0之後訪問網絡不能放在主線程中
            new Thread(){

                @Override
                public void run() {
                    //連接服務器GET請求獲取圖片
                    try {
                        URL url = new URL(path);
                        //根據URL發送HTTP請求
                        conn = (HttpURLConnection) url.openConnection();
                        //設置請求方式
                        conn.setRequestMethod("GET");
                        //設置超時時間
                        conn.setConnectTimeout(5000);
                        //得到服務端響應碼
                        int code = conn.getResponseCode();
                        if (code == 200){
                            //獲取輸入流
                            InputStream is = conn.getInputStream();
                            //將流轉爲Bitmap對象
                            Bitmap bitmap = BitmapFactory.decodeStream(is);
                            //將更改主界面的消息發送給主線程
                            Message msg = new Message();
                            msg.what = CHANGE_UI;
                            msg.obj = bitmap;
                            handler.sendMessage(msg);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        Message msg = new Message();
                        msg.what = ERROR;
                        handler.sendMessage(msg);
                    }
                    //關閉連接
                    conn.disconnect();
                }
            }.start();
        }
    }
}

Androidmanifest.xml


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

運行截圖:

點擊瀏覽後
在這裏插入圖片描述
完成。

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