Android OkHttp

OkHttp基本用法

URL和Uri

  1. 所屬的包不同。URI位置在java.net.URI,顯然是Java提供的一個(gè)類秽梅。而Uri位置在android.net.Uri,是由Android提供的一個(gè)類。所以初步可以判斷剿牺,Uri是URI的“擴(kuò)展”以適應(yīng)Android系統(tǒng)的需要。
  2. 作用的不同环壤。URI類代表了一個(gè)URI(這個(gè)URI不是類晒来,而是其本來的意義:通用資源標(biāo)志符——Uniform Resource Identifier)實(shí)例。官方文檔Uri類是一個(gè)不可改變的URI引用郑现,包括一個(gè)URI和一些碎片湃崩,碎片時(shí)跟在URI中“#”后面的部分。建立并且轉(zhuǎn)換URI引用接箫。出于對性能的考慮Uri類對無效的行為不敏感攒读,對于無效的輸入沒有定義相應(yīng)的行為,如果沒有另外制定辛友,它將返回垃圾而不是拋出一個(gè)異常薄扁。

綜上所述,Uri是Android開發(fā)的废累,擴(kuò)展了Java中URI的一些功能來特定的適用于Android開發(fā)邓梅。參考自Uri詳解之——Uri結(jié)構(gòu)與代碼提取

那什么時(shí)候需要用到java.net.URL呢。當(dāng)需要訪問某個(gè)網(wǎng)頁時(shí)邑滨,例如https://www.baidu.com日缨,這就是URL。這里有一篇值得閱讀的博客關(guān)于URL編碼

fragment掖看,用于聚焦到資源的某部分匣距。

OkHttp基礎(chǔ)用法

OkHttp是一款優(yōu)秀的HTTP框架,它支持get請求和post請求哎壳,支持基于Http的文件上傳和下載毅待,支持加載圖片,支持下載文件透明的GZIP壓縮耳峦,支持響應(yīng)緩存避免重復(fù)的網(wǎng)絡(luò)請求恩静,支持使用連接池來降低響應(yīng)延遲問題。

配置OkHttp

AndroidStudio可以通過從Maven下載jar包。在build.gradle(app)中構(gòu)建驶乾,

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
    compile 'com.squareup.okhttp3:okhttp:3.4.1'
    compile 'com.squareup.okio:okio:1.11.0'
}

由于okhttp內(nèi)部依賴okio邑飒,所以同時(shí)導(dǎo)入okio。

關(guān)鍵類

OkHttpClient级乐,Request疙咸,RequestBody,Call风科,Callback撒轮,Response,ResponseBody

Http Get

//創(chuàng)建okHttpClient對象
OkHttpClient mOkHttpClient = new OkHttpClient();
//創(chuàng)建一個(gè)Request
final Request request = new Request.Builder()
                .url("https://github.com/hongyangAndroid")
                .build();
//new call
Call call = mOkHttpClient.newCall(request); 
//請求加入調(diào)度
call.enqueue(new Callback()
        {
            @Override
            public void onFailure(Request request, IOException e)
            {
            }

            @Override
            public void onResponse(final Response response) throws IOException
            {
                    //String htmlStr =  response.body().string();
            }
        });             

代碼分析:

  1. 首先實(shí)例化一個(gè)OkHttpClient對象贼穆,OkHttp官方文檔并不建議我們創(chuàng)建多個(gè)OkHttpClient题山,因此全局使用一個(gè)。
  2. 創(chuàng)建一個(gè)請求(Request)故痊,可以通過RequestBuilder來設(shè)置參數(shù)顶瞳,例如header,method愕秫。但是至少有一個(gè)URL
  3. 通過request的對象去構(gòu)造得到一個(gè)Call對象慨菱,類似于將你的請求封裝成了任務(wù),既然是任務(wù)戴甩,就會(huì)有execute()和cancel()等方法符喝。
  4. 以異步的方式去執(zhí)行請求,所以我們調(diào)用的是call.enqueue甜孤,將call加入調(diào)度隊(duì)列协饲,然后等待任務(wù)執(zhí)行完成,我們在Callback中即可得到結(jié)果课蔬。

當(dāng)整個(gè)GET成功囱稽,我們就回調(diào)在onResponse()方法中的方法處理ResponseBody包含的數(shù)據(jù)。通過response.body()方法得到ResponseBody對象二跋。ResponseBody有幾種方式轉(zhuǎn)換返回的數(shù)據(jù)战惊,

  • string(),獲得返回的字符串扎即,方法對于小文檔來說十分方便吞获、高效。但是如果響應(yīng)體太大(超過1MB)谚鄙,應(yīng)避免適應(yīng) string()方法 各拷,因?yàn)樗麜?huì)將把整個(gè)文檔加載到內(nèi)存中。
  • btyes()闷营,返回二進(jìn)制字節(jié)數(shù)組烤黍。
  • byteStream()知市,返回InputStream。

Call有一個(gè)線程阻塞方法速蕊,execute()嫂丙。可以直接調(diào)用這個(gè)方法返回一個(gè)Response规哲。

注意當(dāng)我們使用Call.execute()方法返回的Response跟啤,首先要進(jìn)行判斷是否成功。調(diào)用Response.isSuccessful()(Returns true if the code is in [200..300),這里的code指的是Http響應(yīng)消息的狀態(tài)碼)方法來判斷唉锌。

Http Post

關(guān)鍵類

MediaType隅肥,F(xiàn)ormEncodingBuilder

POST提交Json數(shù)據(jù)

public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
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();
    f (response.isSuccessful()) {
        return response.body().string();
    } else {
        throw new IOException("Unexpected code " + response);
    }
}

使用Request的post方法來提交請求體RequestBody

POST提交鍵值對

很多時(shí)候我們會(huì)需要通過POST方式把鍵值對數(shù)據(jù)傳送到服務(wù)器。 OkHttp提供了很方便的方式來做這件事情袄简。

OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
 
     RequestBody formBody = new FormEncodingBuilder()
    .add("platform", "android")
    .add("name", "bug")
    .add("subject", "XXXXXXXXXXXXXXX")
    .build();
 
      Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();
 
      Response response = client.newCall(request).execute();
    if (response.isSuccessful()) {
        return response.body().string();
    } else {
        throw new IOException("Unexpected code " + response);
    }
}

實(shí)踐

圖片的下載

封裝OkHttp的GET訪問

public static void get(String url, Callback callback) {
        URL requestURL = null;
        try {
            requestURL = new URL(Constant.BASE_URL + url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        Request request = new Request.Builder()
                .url(requestURL)
                .build();
        Call call = mClient.newCall(request);
        call.enqueue(callback);
    }

    public static void getImage(String url, Callback callback) {
        Request request = new Request.Builder()
                .url(url)
                .build();
        Call call = mClient.newCall(request);
        call.enqueue(callback);
    }

調(diào)用封裝的訪問方法

HttpUtil.get(imageUrl, new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {
                            e.printStackTrace();
                            startActivity();
                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            try {
                                 //獲取到真正圖片下載URL
                                JSONObject jsonObject = new JSONObject(response.body().string());
                                String imageUrl = jsonObject.getString("img");
                                loadImage(imageUrl, imageFile);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    });

下載圖片并保存

private void loadImage(String url, final File file) {
        HttpUtil.getImage(url, new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
                startActivity();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                byte[] imageBytes = response.body().bytes();
                //保存圖片到app私有文件中
                saveImage(file, imageBytes);
                startActivity();
            }
        });
    }

總結(jié)腥放,這里主要思想就是利用ResponseBody.bytes()方法實(shí)現(xiàn)圖片的下載。

檢測網(wǎng)絡(luò)連接

既然App需要連接網(wǎng)絡(luò)來下載一些文件绿语,那么應(yīng)該在下載之前判斷用戶是否打開數(shù)據(jù)連接(蜂窩數(shù)據(jù)捉片,wifi等)。確保連接正常后再進(jìn)行網(wǎng)絡(luò)操作汞舱。

Internet權(quán)限在6.0中屬于安全權(quán)限,所以只需要在AndroidManifest.xml中申請權(quán)限就可以

獲取網(wǎng)絡(luò)狀態(tài)

獲取連接管理對象

// 獲取手機(jī)所有連接管理對象(包括對wi-fi,net等連接的管理)
Context context = activity.getApplicationContext();
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

獲取NetworkInfo對象

NetworkInfo networkInfo = manager.getActiveNetworkInfo();

判斷當(dāng)前連接是否可用

if(networkInfo != null) {
                return networkInfo.isAvailable();
            }

注意權(quán)限

由于需要訪問連接狀態(tài)宗雇,所以需要申請安全權(quán)限ACCESS_NETWORK_STATE昂芜。

問題

ConnectivityManager包含了所有的數(shù)據(jù)連接,wifi赔蒲,蜂窩數(shù)據(jù)泌神,藍(lán)牙...當(dāng)設(shè)備同時(shí)有很多數(shù)據(jù)連接保持連接狀態(tài)時(shí),怎么判斷某一個(gè)連接是否可用呢舞虱?

雜技

獲取屏幕的寬欢际,高像素

DisplayMetrics metrics = getResources().getDisplayMetrics();
                    int screenWidth = metrics.widthPixels;
                    int screenHeight = metrics.heightPixels;

參考

Android OkHttp完全解析 是時(shí)候來了解OkHttp了

OkHttp官方教程解析-徹底入門OkHttp使用

OkHttp使用教程

Android獲取網(wǎng)絡(luò)狀態(tài)

Android之獲取屏幕的尺寸像素及獲取狀態(tài)欄標(biāo)題欄高度

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市矾兜,隨后出現(xiàn)的幾起案子损趋,更是在濱河造成了極大的恐慌,老刑警劉巖椅寺,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浑槽,死亡現(xiàn)場離奇詭異,居然都是意外死亡返帕,警方通過查閱死者的電腦和手機(jī)桐玻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荆萤,“玉大人镊靴,你說我怎么就攤上這事。” “怎么了偏竟?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵煮落,是天一觀的道長。 經(jīng)常有香客問我苫耸,道長州邢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任褪子,我火速辦了婚禮量淌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嫌褪。我一直安慰自己呀枢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布笼痛。 她就那樣靜靜地躺著裙秋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缨伊。 梳的紋絲不亂的頭發(fā)上摘刑,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音刻坊,去河邊找鬼枷恕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谭胚,可吹牛的內(nèi)容都是我干的徐块。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼灾而,長吁一口氣:“原來是場噩夢啊……” “哼胡控!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起旁趟,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對情侶失蹤昼激,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后轻庆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體癣猾,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年余爆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纷宇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛾方,死狀恐怖像捶,靈堂內(nèi)的尸體忽然破棺而出上陕,到底是詐尸還是另有隱情,我是刑警寧澤拓春,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布释簿,位于F島的核電站,受9級(jí)特大地震影響硼莽,放射性物質(zhì)發(fā)生泄漏庶溶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一懂鸵、第九天 我趴在偏房一處隱蔽的房頂上張望偏螺。 院中可真熱鬧,春花似錦匆光、人聲如沸套像。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夺巩。三九已至,卻和暖如春周崭,著一層夾襖步出監(jiān)牢的瞬間柳譬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工续镇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留征绎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓磨取,卻偏偏與公主長得像,于是被迫代替她去往敵國和親柴墩。 傳聞我的和親對象是個(gè)殘疾皇子忙厌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,082評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)江咳,斷路器逢净,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • 安卓開發(fā)領(lǐng)域,很多重要的問題都有了很好的開源解決方案歼指,例如網(wǎng)絡(luò)請求 OkHttp + Retrofit 簡直就是不...
    我是濤鍋鍋閱讀 500評(píng)論 0 0
  • ———無憂無慮的童年時(shí)光爹土,永遠(yuǎn)是記憶中的一片凈土。 那里沒有紛爭 只有無垠的田野 和奔跑的孩童踩身。 那時(shí)年少 爬上樹...
    我是大丫閱讀 286評(píng)論 0 2
  • 在我們項(xiàng)目中經(jīng)常會(huì)接觸到時(shí)間等的轉(zhuǎn)換胀茵,將日期轉(zhuǎn)化成時(shí)間字符串顯示,將時(shí)間字符串轉(zhuǎn)化成日期等挟阻。 轉(zhuǎn)換方法 系統(tǒng)有提供...
    追沐閱讀 1,547評(píng)論 0 0