Android框架之路——OKHttp的使用

一攀芯、簡介

OKHttp是一款高效的HTTP客戶端,支持連接同一地址的鏈接共享同一個socket文虏,通過連接池來減小響應(yīng)延遲敲才,還有透明的GZIP壓縮,請求緩存等優(yōu)勢择葡,其核心主要有路由紧武、連接協(xié)議、攔截器敏储、代理阻星、安全性認(rèn)證、連接池以及網(wǎng)絡(luò)適配已添,攔截器主要是指添加妥箕,移除或者轉(zhuǎn)換請求或者回應(yīng)的頭部信息。

這個庫也是square開源的一個網(wǎng)絡(luò)請求庫(okhttp內(nèi)部依賴okio),現(xiàn)在已被Google使用在Android源碼上更舞。

官網(wǎng)地址:http://square.github.io/okhttp/
Github Wiki:https://github.com/square/okhttp/wiki
Wiki 翻譯:http://blog.csdn.net/jackingzheng/article/details/51778793

OKHttp的功能:

  • 聯(lián)網(wǎng)請求文本數(shù)據(jù)
  • 大文件下載
  • 大文件上傳
  • 請求圖片

二畦幢、添加依賴

compile 'com.squareup.okhttp3:okhttp:3.7.0'

三、解鎖技能

<1> 使用原生OKHttp的Get請求

  1. 添加網(wǎng)絡(luò)權(quán)限缆蝉;

     <uses-permission android:name="android.permission.INTERNET"/>
    
  2. 使用http://square.github.io/okhttp/中示例get方法宇葱,該方法請求url地址只能在子線程中運(yùn)行瘦真;

     /**
      * get請求,要求在子線程運(yùn)行
      * @param url
      * @return
      * @throws IOException
      */
     private String get(String url) throws IOException {
         Request request = new Request.Builder()
                 .url(url)
                 .build();
    
         Response response = client.newCall(request).execute();
         return response.body().string();
     }
    
  3. 開辟子線程get方式請求數(shù)據(jù);

     case R.id.button:
            new Thread(){
                @Override
                public void run() {
                    super.run();
                    try {
                        String result = get("http://gank.io/api/data/Android/2/1");
                        Message msg = Message.obtain();
                        msg.what = GET;
                        msg.obj = result;
                        mHandler.sendMessage(msg);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
            break;
    
  4. 通過handler更新ui黍瞧,顯示請求結(jié)果诸尽。

     case GET:
        mTextView2.setText((String) msg.obj);
        break;
    

<2> 使用原生OKHttp的Post請求

  1. 官網(wǎng)示例post方法,也需要在子線程中運(yùn)行印颤;

     /**
      * post請求
      * @param url
      * @param json 上傳時需要json
      * @return
      * @throws IOException
      */
     private String post(String url, String json) throws IOException {
         RequestBody body = RequestBody.create(JSON, json);
         Request request = new Request.Builder()
                 .url(url)
                 .post(body)
                 .build();
         Response response = client.newCall(request).execute();
         return response.body().string();
     }
    
  2. 開辟子線程psot請求數(shù)據(jù)您机;

     new Thread(){
         @Override
         public void run() {
             super.run();
             try {
                 String result = post("http://api.m.mtime.cn/PageSubArea/TrailerList.api", null);
                 Message msg = Message.obtain();
                 msg.what = POST;
                 msg.obj = result;
                 mHandler.sendMessage(msg);
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }.start();
    

<3> 使用第三方封裝的OKHttp庫okhttp-utils(鴻洋大神出品)

我們使用原生的OKHttp時,需要自己去開辟子線程請求網(wǎng)絡(luò)數(shù)據(jù)年局,然后通過Handler去更新UI际看,很麻煩,需要我們想法設(shè)法可以再次封裝矢否,方便我們的使用仲闽。

  1. 鴻洋博客地址:http://blog.csdn.net/lmj623565791/article/details/49734867/

  2. 添加依賴:compile 'com.zhy:okhttputils:2.6.2'兴喂;

  3. 使用OkhttpUtils進(jìn)行g(shù)et請求蔼囊;

    /**
     * 使用OkhttpUtils進(jìn)行g(shù)et請求
     * @param url url地址
     * @param id 請求ID號
     */
    private void getByOkhttpUtils(String url, int id) {
        OkHttpUtils.get().url(url).id(id).build().execute(new StringCallback() {
            @Override
            public void onError(Call call, Exception e, int id) {
                e.printStackTrace();
                mTextView2.setText(e.getMessage());
            }
    
            @Override
            public void onResponse(String response, int id) {
                mTextView2.setText(response);
                switch (id){
                    case 100:
                        Toast.makeText(getApplicationContext(), "100請求成功", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        });
    }    
    
  4. 使用OkhttpUtils進(jìn)行post請求焚志;

     /**
      * 使用OkhttpUtils進(jìn)行post請求
      * @param url
      * @param id
      */
     private void postByOkhttpUtils(String url, int id) {
         OkHttpUtils.post().url(url).id(id).build().execute(mStringCallback);
     }
    
     ........
    
     //封裝回調(diào)
     private StringCallback mStringCallback = new StringCallback() {
         @Override
         public void onError(Call call, Exception e, int id) {
             e.printStackTrace();
             mTextView2.setText(e.getMessage());
         }
    
         @Override
         public void onResponse(String response, int id) {
             mTextView2.setText(response);
             switch (id) {
                 case 100:
                     Toast.makeText(getApplicationContext(), "100get請求成功", Toast.LENGTH_SHORT).show();
                     break;
                 case 101:
                     Toast.makeText(getApplicationContext(), "101post請求成功", Toast.LENGTH_SHORT).show();
                     break;
             }
         }
     };   
    
  5. 下載文件衣迷,添加WRITE_EXTERNAL_STORAGE權(quán)限,設(shè)置回調(diào)并進(jìn)行下載酱酬;

     //參數(shù)包含保存路徑和保存文件名
     private FileCallBack mFileCallBack = new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), "test.mp4") {
             @Override
             public void onError(Call call, Exception e, int id) {
                 e.printStackTrace();
                 mTextView2.setText(e.getMessage());
             }
    
         @Override
         public void inProgress(float progress, long total, int id) {
             super.inProgress(progress, total, id);
             mProgressBar.setProgress((int) (100 * progress));
             mTextView2.setText("下載進(jìn)度:" + (int) (100 * progress) + "/%");
         }
    
         @Override
         public void onResponse(File response, int id) {
         }
     };
    
     ......
    
     /**
      * 使用OkhttpUtils進(jìn)行下載大文件
      * @param url
      */
     private void downloadFileByOkhttpUtils(String url){
         OkHttpUtils.get().url(url).build().execute(mFileCallBack);
     }
    
  6. 文件上傳壶谒;
    文件服務(wù)器搭建:下載鏈接,我的測試鏈接: http://192.168.1.102/FileUpload/index.jsp膳沽;

     /**
      * 單文件或多文件上傳
      * @param url url地址
      * @param id 請求id
      * @param username 用戶名參數(shù)
      * @param files 文件集合
      */
     private void uploadFilesByOkhttpUtils(String url, int id, String username, List<File> files) {
         for (File file : files) {
             if (!file.exists()) {
                 Toast.makeText(getApplicationContext(), "文件" + file.getName() + "不存在", Toast.LENGTH_SHORT).show();
                 return;
             }
         }
         Map<String, String> params = new HashMap<>();
         params.put("username", username);
    
         PostFormBuilder builder = OkHttpUtils.post();
         for (File file : files) {
             builder = builder.addFile(username, "server" + file.getName(), file);
         }
         builder.url(url).id(id).params(params).build().execute(mStringCallback);
    
     }
    
     ......
    
     @OnClick(R.id.button3)
     public void onViewClicked() {
         List<File> files = new ArrayList<>();
         files.add(new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "QQ_8.9.2.20760_setup.exe"));
         files.add(new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "test.mp4"));
         uploadFilesByOkhttpUtils("http://192.168.1.102/FileUpload/FileUploadServlet", 102, "Mr.sorrow", files);
     }
    
  7. 請求圖片汗菜;

     private BitmapCallback mBitmapCallback = new BitmapCallback() {
         @Override
         public void onError(Call call, Exception e, int id) {
             e.printStackTrace();
             mTextView2.setText(e.getMessage());
         }
    
         @Override
         public void onResponse(Bitmap response, int id) {
             mImageView.setImageBitmap(response);
         }
     };      
    
     .......
    
     /**
      * 請求單張圖片
      * @param url
      * @param id
      */
     private void getPicByOkhttpUtils(String url, int id) {
         OkHttpUtils
                 .get()
                 .url(url)
                 .tag(this)
                 .id(id)
                 .build()
                 .connTimeOut(20000)    //設(shè)置連接超時、讀取超時挑社、寫入超時
                 .readTimeOut(20000)
                 .writeTimeOut(20000)
                 .execute(mBitmapCallback);
     }
    

<4> 加載圖片集合(并不是okhttp-utils的強(qiáng)項)

  1. Activity:

     public class ThirdActivity extends AppCompatActivity {
     
         private List<String> picsUrl;
     
         @BindView(R.id.listview)
         ListView mListview;
         @BindView(R.id.progressBar)
         ProgressBar mProgressBar;
         @BindView(R.id.textView)
         TextView mTextView;
     
         private StringCallback mStringCallback = new StringCallback() {
             @Override
             public void onError(Call call, Exception e, int id) {
                 e.printStackTrace();
                 mTextView.setVisibility(View.VISIBLE);
                 mProgressBar.setVisibility(View.GONE);
             }
     
             @Override
             public void onResponse(String response, int id) {
                 mTextView.setVisibility(View.GONE);
                 switch (id) {
                     case 100:
                         Toast.makeText(getApplicationContext(), "請求成功", Toast.LENGTH_SHORT).show();
                         break;
                 }
                 if (response != null) {
                     Meizi meizi1 = processData(response);
                     if (meizi1 != null) {
                         List<Meizi.ResultsBean> beanList = meizi1.getResults();
                         if (!beanList.isEmpty()) {
                             for (Meizi.ResultsBean resultsBean : beanList) {
                                 picsUrl.add(resultsBean.getUrl());
                                 Log.i("xxxxx", resultsBean.getUrl());
                             }
                         }
                     }
                 }
     
                 mListview.setAdapter(new MyAdapter(picsUrl, ThirdActivity.this));
     
                 mProgressBar.setVisibility(View.GONE);
             }
     
             @Override
             public void inProgress(float progress, long total, int id) {
                 super.inProgress(progress, total, id);
             }
         };
     
         /**
          * 解析json數(shù)據(jù)
          *
          * @param json
          */
         private Meizi processData(String json) {
             Gson gson = new Gson();
             return gson.fromJson(json, Meizi.class);
         }
     
         @Override
         protected void onCreate(@Nullable Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_third);
             ButterKnife.bind(this);
             picsUrl = new ArrayList<>();
             getDataByOkhttpUtils("http://gank.io/api/data/%E7%A6%8F%E5%88%A9/20/1", 100);
         }
     
         /**
          * get請求json數(shù)據(jù)
          *
          * @param url
          * @param id
          */
         private void getDataByOkhttpUtils(String url, int id) {
             OkHttpUtils.get().url(url).id(id).build().execute(mStringCallback);
         }
     }
    
  2. Adapter:

     public class MyAdapter extends BaseAdapter {
     
         private List<String> data;
         private Context mContext;
     
         public MyAdapter(List<String> data, Context context) {
             this.data = data;
             mContext = context;
         }
     
         @Override
         public int getCount() {
             return data.size();
         }
     
         @Override
         public String getItem(int position) {
             return data.get(position);
         }
     
         @Override
         public long getItemId(int position) {
             return position;
         }
     
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             ViewHolder holder = null;
             if (convertView == null) {
                 convertView = View.inflate(mContext, R.layout.items, null);
                 holder = new ViewHolder(convertView);
                 convertView.setTag(holder);
             } else {
                 holder = (ViewHolder) convertView.getTag();
             }
     
             holder.mTvName.setText(getItem(position));
             holder.mTvDesc.setText(getItem(position));
     
             final ViewHolder finalHolder = holder;
             OkHttpUtils
                     .get()
                     .url(getItem(position))
                     .tag(this)
                     .build()
                     .connTimeOut(20000)    //設(shè)置連接超時陨界、讀取超時、寫入超時
                     .readTimeOut(20000)
                     .writeTimeOut(20000)
                     .execute(new BitmapCallback() {
                         @Override
                         public void onError(Call call, Exception e, int id) {
     
                         }
     
                         @Override
                         public void onResponse(Bitmap response, int id) {
                             finalHolder.mIvIcon.setImageBitmap(response);
                         }
                     });
             return convertView;
         }
     
         static class ViewHolder {
             @BindView(R.id.iv_icon)
             ImageView mIvIcon;
             @BindView(R.id.tv_name)
             TextView mTvName;
             @BindView(R.id.tv_desc)
             TextView mTvDesc;
     
             ViewHolder(View view) {
                 ButterKnife.bind(this, view);
             }
         }
     }
    
  3. GsonFormat生成的實體Bean:

     public class Meizi {
         private boolean error;
         private List<ResultsBean> results;
     
         public boolean isError() {
             return error;
         }
     
         public void setError(boolean error) {
             this.error = error;
         }
     
         public List<ResultsBean> getResults() {
             return results;
         }
     
         public void setResults(List<ResultsBean> results) {
             this.results = results;
         }
     
         public static class ResultsBean {
             private String _id;
             private String createdAt;
             private String desc;
             private String publishedAt;
             private String source;
             private String type;
             private String url;
             private boolean used;
             private String who;
     
             public String get_id() {
                 return _id;
             }
     
             public void set_id(String _id) {
                 this._id = _id;
             }
     
             public String getCreatedAt() {
                 return createdAt;
             }
     
             public void setCreatedAt(String createdAt) {
                 this.createdAt = createdAt;
             }
     
             public String getDesc() {
                 return desc;
             }
     
             public void setDesc(String desc) {
                 this.desc = desc;
             }
     
             public String getPublishedAt() {
                 return publishedAt;
             }
     
             public void setPublishedAt(String publishedAt) {
                 this.publishedAt = publishedAt;
             }
     
             public String getSource() {
                 return source;
             }
     
             public void setSource(String source) {
                 this.source = source;
             }
     
             public String getType() {
                 return type;
             }
     
             public void setType(String type) {
                 this.type = type;
             }
     
             public String getUrl() {
                 return url;
             }
     
             public void setUrl(String url) {
                 this.url = url;
             }
     
             public boolean isUsed() {
                 return used;
             }
     
             public void setUsed(boolean used) {
                 this.used = used;
             }
     
             public String getWho() {
                 return who;
             }
     
             public void setWho(String who) {
                 this.who = who;
             }
         }
     }
    

四痛阻、栗子效果

???????演示視頻

五菌瘪、栗子下載

???????下載地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市阱当,隨后出現(xiàn)的幾起案子俏扩,更是在濱河造成了極大的恐慌,老刑警劉巖弊添,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件录淡,死亡現(xiàn)場離奇詭異,居然都是意外死亡油坝,警方通過查閱死者的電腦和手機(jī)嫉戚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門刨裆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人彼水,你說我怎么就攤上這事崔拥。” “怎么了凤覆?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵链瓦,是天一觀的道長。 經(jīng)常有香客問我盯桦,道長慈俯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任拥峦,我火速辦了婚禮贴膘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘略号。我一直安慰自己刑峡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布玄柠。 她就那樣靜靜地躺著突梦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪羽利。 梳的紋絲不亂的頭發(fā)上宫患,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機(jī)與錄音这弧,去河邊找鬼娃闲。 笑死,一個胖子當(dāng)著我的面吹牛匾浪,可吹牛的內(nèi)容都是我干的皇帮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蛋辈,長吁一口氣:“原來是場噩夢啊……” “哼属拾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起梯浪,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤捌年,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后挂洛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體礼预,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年虏劲,在試婚紗的時候發(fā)現(xiàn)自己被綠了托酸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片褒颈。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖励堡,靈堂內(nèi)的尸體忽然破棺而出谷丸,到底是詐尸還是另有隱情,我是刑警寧澤应结,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布刨疼,位于F島的核電站,受9級特大地震影響鹅龄,放射性物質(zhì)發(fā)生泄漏揩慕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一扮休、第九天 我趴在偏房一處隱蔽的房頂上張望迎卤。 院中可真熱鬧,春花似錦玷坠、人聲如沸蜗搔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽樟凄。三九已至,卻和暖如春秕重,著一層夾襖步出監(jiān)牢的瞬間不同,已是汗流浹背厉膀。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工溶耘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人服鹅。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓凳兵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親企软。 傳聞我的和親對象是個殘疾皇子庐扫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)仗哨,斷路器形庭,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法厌漂,內(nèi)部類的語法萨醒,繼承相關(guān)的語法,異常的語法苇倡,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,811評論 0 11
  • 上篇文章介紹了IPC機(jī)制的基本概念以及簡單使用富纸,文章鏈接:Android 關(guān)于IPC機(jī)制的理解(一) 這篇文章主要...
    老實任閱讀 724評論 0 2
  • 搜索引擎即是百度晓褪,百度顯然已經(jīng)是中文搜索引擎的代名詞堵漱。 百度作為全球最大的中文搜索引擎,一直在行業(yè)內(nèi)處于技術(shù)涣仿、市場...
    張柒念閱讀 1,485評論 3 5