1. 程式人生 > >Retrofit2快速入門使用及檔案上傳(單上傳、多上傳)

Retrofit2快速入門使用及檔案上傳(單上傳、多上傳)

前言

作者:zkbilian

在開發專案中經常會遇到上傳頭像的問題,那我們如果使用Retrofit做網路請求時,如何進行使用,在文章的最後有最清晰的使用方法

Retrofit可以認為是Okhttp的 “升級版”,為什麼這麼說?那是因為其內部預設是基於OkHttp來進行封裝的,它們屬於同一家公司Square

介紹

這裡寫圖片描述

常用的網路請求方法

@GET

 使用@Query單個引數   @QueryMap多個引數

@POST

使用@Field 單個引數   @FieldMap 多個引數   @Part 上傳檔案 @PartMap 上傳多個檔案

總體使用步驟:

1.新增Retrofit依賴庫
2.建立接受伺服器返回資料的類
3.建立用於描述網路請求的介面
4.建立Rerofit例項
5.建立網路請求介面例項
6.傳送網路請求(非同步和同步)
7.處理返回資料 
8.進階理解從複雜到精簡的過程
9.上傳檔案使用

使用

當你想要做任何網路請求的操作時,一定要提前首先加上網路許可權,這是很多新手容易忘記的通病,以前我也老忘哈哈。。。。。

下面來看具體使用方法:

1.匯入依賴包

    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.google.code.gson:gson:2.2.4'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'

2.建立Bean類

用gson 快捷方式,生成一個數據類,這個大家都會把,如果不會的話百度搜gosn 外掛即可

3.建立存放網路請求的介面

//{name}是一個替換塊,搭配@Path("name")動態傳引數 
public interface PostService{
  @GET("{name}/index?key=d05b58fa6901ad9bed77a1ef08bd6ccb")
  Call<Getbean> getString(@Path("name") String name);
}

4..建立並初始化Retrofit例項

       Retrofit retrofit = new Retrofit.Builder()
               .baseUrl
("http://v.juhe.cn/")//設定網路請求的Url地址 .addConverterFactory(GsonConverterFactory.create()) //設定資料解析器 .build();

5.連線網路請求介面呼叫其方法

GetService service = retrofit.create(GetService.class);
Call<GetBean> call = service.getString3("toutiao");

6.同步和非同步請求方式

//同步操作,必須開啟子執行緒
     new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Response<GetBean> execute = call.execute();
                    GetBean bean = execute.body();
                    Message msg=hand.obtainMessage();
                    msg.obj=bean.toString();
                    msg.what=102;
                    hand.sendMessage(msg);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
//非同步操作
  call.enqueue(new Callback<GetBean>() {
            @Override
            public void onResponse(Call<GetBean> call, Response<GetBean> response) {
                GetBean bean = response.body();
                Log.e("zhoukang", "" + bean.toString());
            }
            @Override
            public void onFailure(Call<GetBean> call, Throwable t) {
            }
        });

7.處理返回資料

 Handler hand=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //TODO 處理邏輯
        }
    };

8.進階理解從複雜到精簡的過程

  • GET 請求方式
 //直接拼接,記得加問號
    @GET("toutiao/index?type=shehui&key=d05b58fa6901ad9bed77a1ef08bd6ccb")
    Call<GetBean> getString();

 //{name}可以最簡單的將其理解為路徑替換塊,用”{}”表示,與註解@path配合使用 ,為了解耦,引數name==toutiao
    @GET("{name}/index?type=shehui&key=d05b58fa6901ad9bed77a1ef08bd6ccb")
    Call<GetBean> getString2(@Path("name") String name);

 //對於@GET來說,引數資訊是可以直接放在url中上傳的。那麼你馬上就反應過來了,這一樣也存在嚴重的耦合!
 //於是,就有了@query
    @GET("{name}/index")
    Call<GetBean> getString3(@Path("name")String name,@Query("type") String type 
    ,@Query("key") String key);

 //假設我要在引數中上傳10個引數呢?這意味著我要在方法中宣告10個@Query引數?當然不是!
    //Retrofit也考慮到了這點,所以針對於複雜的引數上傳,為我們準備了@QueryMap
    @GET("{name}/index")
    Call<GetBean> getString4(@Path("name") String name, @QueryMap HashMap<String,String> hashMap);
  • Post方式
    //注意:千萬別忘了標記 @FormUrlEncoded
    @FormUrlEncoded
    @POST("toutiao/index")
    Call<PostBean> postString(@Field("type") String type, @Field("key") String key);

   // Post表單提交-多個引數[email protected]
    @FormUrlEncoded
    @POST("toutiao/index")
    Call<PostBean> postString2(@FieldMap HashMap<String,String> params);
  • MainActivity檔案
/**
 *   https://blog.csdn.net/carson_ho/article/details/73732076
 */
public class MainActivity extends AppCompatActivity {

    private TextView mTv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTv = findViewById(R.id.tv);
        //        initGet();
        try {
            initPost();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    private void initPost() throws UnsupportedEncodingException {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://v.juhe.cn/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        PostService service = retrofit.create(PostService.class);
        //解決中文亂碼,伺服器後臺不認識造成資料為響應
        String name = URLEncoder.encode("社會", "UTF-8");
        HashMap<String, String> map = new HashMap<>();
        map.put("type", name);
        map.put("key", "d05b58fa6901ad9bed77a1ef08bd6ccb");
        Call<PostBean> call = service.postString2(map);

        call.enqueue(new Callback<PostBean>() {
            @Override
            public void onResponse(Call<PostBean> call, Response<PostBean> response) {
                if (response.isSuccessful()) {
                    PostBean bean = response.body();
                    Message msg = hand.obtainMessage();
                    msg.obj = bean.toString();
                    msg.what = 102;
                    hand.sendMessage(msg);
                    Log.e("zhoukang", "" + bean.toString());
                }
            }
            @Override
            public void onFailure(Call<PostBean> call, Throwable t) {
                Log.e("zhoukang", "R1++ 失敗" + t.getMessage());
            }
        });


    }


    private void initGet() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://v.juhe.cn/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        GetService service = retrofit.create(GetService.class);
        final Call<GetBean> call = service.getString3("toutiao", "shehui", "d05b58fa6901ad9bed77a1ef08bd6ccb");
        //非同步請求操作
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Response<GetBean> execute = call.execute();
                    GetBean bean = execute.body();
                    Message msg = hand.obtainMessage();
                    msg.obj = bean.toString();
                    msg.what = 102;
                    hand.sendMessage(msg);
                    Log.e("zhoukang", "" + bean.toString());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

    Handler hand = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //TODO 處理邏輯
            if (msg.what == 102) {
                String result = (String) msg.obj;
                mTv.setText(result);
            }
        }
    };

}

9.圖片檔案上傳

無聊自己寫了一個工具類,可以進行擴充套件使用

public class RetrofitHelper {

    Retrofit retrofit = null;
    String   BASEURL  = "介面地址";
    private final PostService mService;
    public static RetrofitHelper retrofitHelper = new RetrofitHelper();

    private RetrofitHelper() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASEURL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        //通過retrofit類去把我們的網路請求service例項化出來
        mService = retrofit.create(PostService.class);
    }


    public static RetrofitHelper getInstance() {
        return retrofitHelper;
    }

        //提供一些方法去呼叫service實體類的方法,RequestBody上傳單個檔案
    public void uploadFile(RequestBody body, final OnSuccessListener listener) {
        Call<TestBean> call = mService.postFile(body, "");
        call.enqueue(new Callback<TestBean>() {
            @Override
            public void onResponse(Call<TestBean> call, Response<TestBean> response) {
                listener.onSuccess(response);
            }

            @Override
            public void onFailure(Call<TestBean> call, Throwable t) {
                listener.onFaile();
            }
        });
    }

    //提供一些方法去呼叫service實體類的方法,HashMap上傳多個檔案
    public void uploadFile2(HashMap<String, RequestBody> map, final OnSuccessListener listener) {
        Call<TestBean> call = mService.postFile2(map, "");
        call.enqueue(new Callback<TestBean>() {
            @Override
            public void onResponse(Call<TestBean> call, Response<TestBean> response) {
                listener.onSuccess(response);
            }

            @Override
            public void onFailure(Call<TestBean> call, Throwable t) {
                listener.onFaile();
            }
        });
    }
    //當我獲取資料成功後要做什麼處理
    public interface OnSuccessListener {
        void onSuccess(Object o);

        void onFaile();
    }
}

MainAtivity.java

    /**
     * 單張圖片上傳
     *
     * @throws IOException
     */
    private void initUpateBitmap() {

        //獲取圖片路徑,這只是個簡單的例子,專案開發中會有很多圖片需要上傳,一般從相簿和相機裡獲取,並且儲存到後臺伺服器時必須自己定義名字
        // ,這樣就不會發生圖片替換(原因名字重複)
        File file = new File(Environment.getExternalStorageDirectory() + "/" + "retrofit/" + "ceshi.jpg");
        RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        RetrofitHelper.getInstance().uploadFile(body, new RetrofitHelper.OnSuccessListener() {
            @Override
            public void onSuccess(Object o) {
                Log.e("", "成功");
            }

            @Override
            public void onFaile() {
                Log.e("", "失敗");

            }
        });
    }
 /**
     * 多張圖片上傳
     */
    private void initUpateBitmap2() {

        //獲取圖片路徑,這只是個簡單的例子,專案開發中會有很多圖片需要上傳,一般從相簿和相機裡獲取,並且儲存到後臺伺服器時必須自己定義名字
        // ,這樣就不會發生圖片替換(原因名字重複)
        File file = new File(Environment.getExternalStorageDirectory() + "/" + "retrofit/" + "ceshi.jpg");
        File file2 = new File(Environment.getExternalStorageDirectory() + "/" + "retrofit/" + "ceshi2.jpg");
        File file3 = new File(Environment.getExternalStorageDirectory() + "/" + "retrofit/" + "ceshi3.jpg");
        File file4 = new File(Environment.getExternalStorageDirectory() + "/" + "retrofit/" + "ceshi4.jpg");

        RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        RequestBody requestBody2 = RequestBody.create(MediaType.parse("multipart/form-data"), file2);
        RequestBody requestBody3 = RequestBody.create(MediaType.parse("multipart/form-data"), file3);
        RequestBody requestBody4 = RequestBody.create(MediaType.parse("multipart/form-data"), file4);
        RequestBody body = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        //傳一張圖片就要增加一個引數
        String name = "photo\"; filename=\"ceshi.jpg\"";
        String name2 = "photo\"; filename=\"ceshi2.jpg\"";
        String name3 = "photo\"; filename=\"ceshi3.jpg\"";
        String name4 = "photo\"; filename=\"ceshi4.jpg\"";
        HashMap<String, RequestBody> map = new HashMap<>();
        map.put(name, requestBody);
        map.put(name2, requestBody2);
        map.put(name3, requestBody3);
        map.put(name4, requestBody4);

        RetrofitHelper.getInstance().uploadFile2(map, new RetrofitHelper.OnSuccessListener() {
            @Override
            public void onSuccess(Object o) {
                Log.e("", "成功");
            }

            @Override
            public void onFaile() {
                Log.e("", "失敗");

            }
        });
    }

介面

    //Post檔案提交 ,每個鍵值對都需要用@Part註解鍵名字
    //Multipart 支援檔案上傳
    @Multipart
    @POST("拼接引數")

    @Multipart
    @POST("拼接引數")
    Call<TestBean> postFile2(@PartMap HashMap<String,RequestBody> bodyMap, @Field("token") String token);

總結

Retrofit2 的.baseUrl( xxxxxxx / )方法必須以 /(斜線) 結束,
不然會丟擲一個IllegalArgumentException,所以如果你看到別的教程沒有以 / 結束,
那麼多半是直接從Retrofit 1.X 照搬過來的。

這其實都是簡單的使用方式,希望你們能看懂,谷歌推薦搭配Rxjava+Rxandroid+gson 去使用,效率快,邏輯也更加簡單

相關推薦

python文件封裝成*.exe文件文件和文件

-- 黑板 workday 程序包 代碼 拷貝 4.5 hole nic 環境:win10 64位 python3.7 單*.py文件打包Python GUI:程序打包為exe 一、安裝Pyinstaller,命令pip install Pyinstaller,(大

不同VLAN之間相互通訊的兩種方式 臂路由三層交換

2、將PC5和PC6分別連線到交換機SW3的f0/6和f0/1上,然後配置PC5的IP地址為192.168.2.1/24,閘道器為192.168.2.254。PC6的IP地址為192.168.1.1,閘道器為192.168.1.254。然後用PC5 ping PC6,看是否能ping通。

不同VLAN之間相互通訊的兩種方式臂路由三層交換

2、將PC5和PC6分別連線到交換機SW3的f0/6和f0/1上,然後配置PC5的IP地址為192.168.2.1/24,閘道器為192.168.2.254。PC6的IP地址為192.168.1.1,閘道器為192.168.1.254。然後用PC5 ping PC6,看是否能ping通。

Retrofit2快速入門使用檔案

前言 在開發專案中經常會遇到上傳頭像的問題,那我們如果使用Retrofit做網路請求時,如何進行使用,在文章的最後有最清晰的使用方法 Retrofit可以認為是Okhttp的 “升級版”,為什麼這麼說?那是因為其內部預設是基於OkHttp來進行

nginx檔案大小限制413 Request Entity Too Large錯誤解決

nginx預設上傳最大值是1M 在nginx.conf中新增配置client_max_body_size即可,如下上傳最大為20M client_max_body_size  20m; (修改nginx.conf檔案操作如不會,請參考:  https://blog

QT進行檔案 類似於百度雲網盤

分為伺服器和客戶端 下面來具體貼出程式碼。  每一句的具體註釋都在,幫助理解: 先貼    客戶端 首先在專案檔案  .pro中新增 network widget.h #ifndef WIDGET_H #define WIDGET_H #include &l

SpringBoot進階之檔案檔案/檔案

1.單檔案上傳 private String uploadPath="D:\\tomcat\\apache-tomcat-7.0.81-windows-x64\\apache-tomcat-7

Log4j 學習筆記Log4j快速入門配置檔案log4j.properties

在該教程中,我們將展示使用經典的log4j 1.2.x記錄java應用程式中的debug或者error級別的日誌資訊。 1. 工程目錄 Maven風格的工程目錄結構: 2. 引用Log4j 在pom.xml中引入依賴: <de

VBA學習1_教你快速入門Excel-巨集與VBA

最近在做專案的時候用到了Excel巨集和VBA,本著共享的原則,我把收集的資料結合專案實踐操作進行了總結之後製作了本教程,旨在幫初學者入門,特別是有一定VB基礎的同學,可以通過此教程快速掌握巨集和VBA。 什麼是巨集     Excel巨集就是一系列的操作步驟,比如在單元格

【第二篇】ASP.NET MVC快速入門之數據註解MVC5+EF6

red 數據庫結構 varchar model 菜單 錯誤提示 edi 還需 問題 目錄 【第一篇】ASP.NET MVC快速入門之數據庫操作(MVC5+EF6) 【第二篇】ASP.NET MVC快速入門之數據註解(MVC5+EF6) 【第三篇】ASP.NET MVC快速入

Redis快速入門應用

業務 出現 文件中 配置 反向 spl null 腳本 線程 Redis的使用難嗎?不難,Redis用好容易嗎?不容易。Redis的使用雖然不難,但與業務結合的應用場景特別多、特別緊,用好並不容易。我們希望通過一篇文章及Demo,即可輕松、快速入門並學會應用。

JavaScript快速入門-ECMAScript本地對象RexExp

com 常用 函數 可選 找到 字符串方法 使用 exp 字符替換 一、概述 RegExp 對象表示正則表達式,它是對字符串執行模式匹配的強大工具。 正則表達式是由一個字符序列形成的搜索模式。 當你在文本中搜索數據時,你可以用搜索模式來描述你要查詢的內容。 正則

C#操作Sqlite快速入門相關工具收集

收集 html urn net sel 2.3 dbn .org .sh Sqlite不需要安裝即可使用。Sqlite是不是那個System.Data.SQLite.DLL臨時創建了數據庫引擎?1.新建一個WinForm項目,引用System.Data.SQLite.DLL

.NET Core實戰專案之CMS 第四章 入門篇-Git的快速入門實戰演練

寫在前面 上篇文章我帶著大家通過分析了一遍ASP.NET Core的原始碼瞭解了它的啟動過程,然後又帶著大家熟悉了一遍配置檔案的載入方式,最後引出了依賴注入以及控制反轉的概念!如果大家把前面幾張都理解了,那麼你也就入了ASP.NET Core的大門了。但是我們還需要一個版本控制工具來提高我們的編碼效率。因此

Maven入門指南 Maven 快速入門簡單使用

1.0 用戶名 resource 剛才 pro jdk 軟件 基金 oca Maven入門指南 :Maven 快速入門及簡單使用 前言 Maven是一個Java語言編寫的開源項目管理工具,是Apache軟件基金會的頂級項目。主要用於項目構建,依賴管理,項目信息

Maven入門指南 Maven 快速入門簡單使用

Maven入門指南 :Maven 快速入門及簡單使用 前言       Maven是一個Java語言編寫的開源專案管理工具,是Apache軟體基金會的頂級專案。主要用於專案構建,依賴管理,專案資訊管理。       maven專案在

快速排序五種優化模板

1、快速排序的基本思想: 快速排序排序使用分治的思想,通過一趟排序將待排序列分割成兩部分,其中一部分記錄的關鍵字均比另一部分記錄的關鍵字小。之後分別對這兩部分記錄繼續進行排序,遞迴地以達到整個序列有序的目 2、快速排序的三個步驟: (1)選擇基準: 在待排序列中,按照某種方式

圖片可根據自己得需要封裝元件

話不多說,先上圖 實現簡單得多行多圖片上傳,可以選擇其中任意一個圖片當作你需要得預設圖傳到後臺,然後一次性提交 程式碼: <template> <div> <div v-for="(item,index) in arr"

SpringBoot快速入門部分問題詳解

前言 從根本上說,Spring Boot的專案就是普通的Spring專案,只是它在Spring的基礎上添加了起步依賴和自動配置而已。 建立專案 安裝Spring Boot CLI 建立專案有多種方式,最快的是安裝Spring Boot CLI。這裡我們採用軟體開

Maven 系列 一 :Maven 快速入門簡單使用【轉】

開發環境 MyEclipse 2014 JDK 1.8 Maven 3.2.1 1.什麼是Maven? Maven是一個專案管理工具,主要用於專案構建,依賴管理,專案資訊管理。 2.下載及安裝 解壓檔案: 配置環境變數(需要先配置好%JAVA_HOME%環境變數): 檢視