Android基礎(chǔ)(三):網(wǎng)絡(luò)請求

網(wǎng)絡(luò)請求

Http的常用請求方式有:


image.png

Get&Post:
網(wǎng)絡(luò)請求中我們常用鍵值對來傳輸參數(shù)。

JSON

JSON(JavaScript Object Notation)是一種基于文本的數(shù)據(jù)交換格式。無論你的應(yīng)用是用哪種開發(fā)語言編寫的(Java/EE,Ruby插掂,PHP,C#/.Net等等)傀履,你都可以使用JSON來通過網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)交互和處理鸥鹉。
JSON是一種簡單數(shù)據(jù)格式,它有三種數(shù)據(jù)結(jié)構(gòu):

  • 鍵值對 —— Name/Value (Key/Value)
  • 對象 —— Object
  • 數(shù)組 —— Arrays

用Android原生技術(shù)解析JSON:
1余境、解析JSON對象的API:JsonObject
JSONObject(String json)驻呐;將Json字符串解析成Json對象;
XxxgetXxx(String name) 芳来;根據(jù)name在json對象中得到相應(yīng)的value含末。

//獲取JSON數(shù)據(jù)
final String content = response.body().string();
JSONObject jsonObject = null;
try {
    //解析JSON對象
    jsonObject = new JSONObject(content);
    JSONObject result = jsonObject.optJSONObject("result");
    final int detailid = result.optInt("detailid");
    final String title = result.optString("title");
    final String type = result.optString("type");
    String c = result.optString("content");
    // 封裝Java對象
    detailModel = new DetailModel(detailid, title, type, c);
    System.out.println(detailModel);
    handler.post(new Runnable() {
        @Override
        public void run() {
            Log.d("PoetryTag", "detailid:" + detailid + ", title:" + title + ", type:" + type + ", content:" + content);
            //顯示解析后的數(shù)據(jù)
            tv_title.setText(detailModel.getTitle());
            tv_type.setText(detailModel.getType());
            tv_content.setText(Html.fromHtml(detailModel.getContent()));
        }
    });
} catch (JSONException e) {
    e.printStackTrace();
}

2、解析Json數(shù)組的API:JSONArray
JSONArray(String json)即舌;將json字符串解析成json數(shù)組答渔;
int length();得到j(luò)son數(shù)組中元素的個數(shù)侥涵;
XxxgetXxx(int s) 沼撕;根據(jù)下標(biāo)得到j(luò)son數(shù)組中對應(yīng)的元素?cái)?shù)據(jù)。

private List<PoetryModel> data(String content) {
    List<PoetryModel> poetryModels = new ArrayList<>();
    try {
        //解析json數(shù)組
        JSONObject jsonObject = new JSONObject(content);
        JSONArray jsonArray = jsonObject.optJSONArray("result");

        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject object = jsonArray.getJSONObject(i);
            if (object != null) {
                int detailid = object.optInt("detailid");
                String name = object.optString("name");
                String author = object.optString("author");
                // 封裝Java對象
                PoetryModel poetryModel = new PoetryModel(detailid, name, author);
                //顯示解析后的數(shù)據(jù)
                poetryModels.add(poetryModel);
                Log.d("PoetryTag", "detail:" + detailid + ", name:" + name + ", author:" + author);
            }
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return poetryModels;
}

OkHttp

導(dǎo)入Jar包

implementation 'com.squareup.okhttp3:okhttp:3.2.0’

在日常開發(fā)中最常用到的網(wǎng)絡(luò)請求就是GET和POST兩種請求方式芜飘。

  • Requests(請求)
    每一個HTTP請求中都應(yīng)該包含一個URL务豺,一個GET或POST方法以及Header或其他參數(shù),當(dāng)然還可以含特定內(nèi)容類型的數(shù)據(jù)流嗦明。
  • Responses(響應(yīng))
    響應(yīng)則包含一個回復(fù)代碼(200代表成功笼沥,404代表未找到),Header和定制可選的body娶牌。
final OkHttpClient client = new OkHttpClient();

public void run(int id) {

    Request request = new Request.Builder()

            .url("[https://api.jisuapi.com/tangshi/detail?appkey=ccb0bd990f91c687&detailid=](https://api.jisuapi.com/tangshi/detail?appkey=ccb0bd990f91c687&detailid=)" + id)

            .get()

            .build();

    client.newCall(request).enqueue(new Callback() {

        @Override

        public void onFailure(Call call, IOException e) {

            e.printStackTrace();

        }

        @Override

        public void onResponse(Call call, Response response) throws IOException {

            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

        // ...JSON解析... 

}
  • 同步&異步
    這2個概念僅存在于多線程編程中奔浅。
    android中默認(rèn)只有一個主線程,也叫UI線程诗良。因?yàn)閂iew繪制只能在這個線程內(nèi)進(jìn)行汹桦。
    所以如果你阻塞了(某些操作使這個線程在此處運(yùn)行了N秒)這個線程,這期間View繪制將不能進(jìn)行鉴裹,UI就會卡舞骆。所以要極力避免在UI線程進(jìn)行耗時操作钥弯。
    網(wǎng)絡(luò)請求是一個典型耗時操作。
    同步:直接耗時操作阻塞線程直到數(shù)據(jù)接收完畢然后返回督禽。Android不允許的脆霎。
    異步:在子線程進(jìn)行耗時操作,完成后通過Handler將更新UI的操作發(fā)送到主線程執(zhí)行狈惫。

使用handler中的post方法:

handler.post(new Runnable() {
    @Override
    public void run() {
        Log.d("PoetryTag", "detailid:" + detailid + ", title:" + title + ", type:" + type + ", content:" + content);
        //顯示解析后的數(shù)據(jù)
        tv_title.setText(detailModel.getTitle());
        tv_type.setText(detailModel.getType());
        tv_content.setText(Html.fromHtml(detailModel.getContent()));
    }
});

這樣處理的話我們就可以不用重寫handlerMessage()方法了睛蛛,適合子線程與主線程進(jìn)行較為單一的交流。

實(shí)例:

MainActivity:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button bt_get;
    private Button bt_post;
    private PoetryAdapter adapter;
    private RecyclerView recycler;

    final OkHttpClient client = new OkHttpClient();

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

        recycler = findViewById(R.id.recycler);
        recycler.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));

        bt_get = findViewById(R.id.bt_get);
        bt_post = findViewById(R.id.bt_post);

        bt_get.setOnClickListener(this);
        bt_post.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.bt_get:
                run();
                try {
                    run();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    private void getRequest() {

        final Request request = new Request.Builder()
                .get()
                .tag(this)
                .url("https://api.apiopen.top/recommendPoetry")
                .build();

        new Thread(new Runnable() {
            @Override
            public void run() {
                Response response = null;
                try {
                    response = client.newCall(request).execute();
                    if (response.isSuccessful()) {
                        Log.i("WY", "打印GET響應(yīng)的數(shù)據(jù):" + response.body().string());
                    } else {
                        throw new IOException("Unexpected code " + response);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public void run() {

        Request request = new Request.Builder()
                .url("https://api.jisuapi.com/tangshi/chapter?appkey=ccb0bd990f91c687")
                .get()
                .build();

        client.newCall(request).enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

                String content = response.body().string();
                final List<PoetryModel> poetryModels = data(content);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        PoetryAdapter adapter = new PoetryAdapter(poetryModels);
                        recycler.setAdapter(adapter);

                        adapter.setOnItemClickListener(new PoetryAdapter.OnItemClickListener() {
                            @Override
                            public void onItemClick(PoetryModel poetryModel) {
                                Intent intent = new Intent(MainActivity.this,DetailActivity.class);
                                intent.putExtra("entity",poetryModel);
                                startActivity(intent);
                            }
                        });
                    }
                });
            }
        });
    }

    private List<PoetryModel> data(String content) {
        List<PoetryModel> poetryModels = new ArrayList<>();

        try {
            //解析json數(shù)組
            JSONObject jsonObject = new JSONObject(content);
            JSONArray jsonArray = jsonObject.optJSONArray("result");
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject object = jsonArray.getJSONObject(i);

                if (object != null) {

                    int detailid = object.optInt("detailid");
                    String name = object.optString("name");
                    String author = object.optString("author");
                    // 封裝Java對象
                    PoetryModel poetryModel = new PoetryModel(detailid, name, author);
                    //顯示解析后的數(shù)據(jù)
                    poetryModels.add(poetryModel);

                    Log.d("PoetryTag", "detail:" + detailid + ", name:" + name + ", author:" + author);
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return poetryModels;
    }
}

DetailAcivity:

public class DetailActivity extends AppCompatActivity {

    private TextView tv_title;
    private TextView tv_type;
    private TextView tv_content;
    private DetailModel detailModel;
    private PoetryModel poetryModel;

    private Handler handler = new Handler();

    final OkHttpClient client = new OkHttpClient();

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

        tv_title = findViewById(R.id.tv_title);
        tv_type = findViewById(R.id.tv_type);
        tv_content = findViewById(R.id.tv_content);

        poetryModel = getIntent().getParcelableExtra("entity");

        run(poetryModel.getDetailid());
    }

    public void run(int id) {
        Request request = new Request.Builder()
                .url("https://api.jisuapi.com/tangshi/detail?appkey=ccb0bd990f91c687&detailid=" + id)
                .get()
                .build();

        client.newCall(request).enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

                //獲取JSON數(shù)據(jù)
                final String content = response.body().string();

                JSONObject jsonObject = null;
                try {
                    //解析JSON對象
                    jsonObject = new JSONObject(content);
                    JSONObject result = jsonObject.optJSONObject("result");

                    final int detailid = result.optInt("detailid");
                    final String title = result.optString("title");
                    final String type = result.optString("type");
                    String c = result.optString("content");

                    // 封裝Java對象
                    detailModel = new DetailModel(detailid, title, type, c);
                    System.out.println(detailModel);

                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            Log.d("PoetryTag", "detailid:" + detailid + ", title:" + title + ", type:" + type + ", content:" + content);
                            //顯示解析后的數(shù)據(jù)
                            tv_title.setText(detailModel.getTitle());
                            tv_type.setText(detailModel.getType());
                            tv_content.setText(Html.fromHtml(detailModel.getContent()));
                        }
                    });
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

運(yùn)行結(jié)果:


image.png

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胧谈,一起剝皮案震驚了整個濱河市玖院,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌第岖,老刑警劉巖难菌,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蔑滓,居然都是意外死亡郊酒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門键袱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來燎窘,“玉大人,你說我怎么就攤上這事蹄咖『纸。” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵澜汤,是天一觀的道長蚜迅。 經(jīng)常有香客問我,道長俊抵,這世上最難降的妖魔是什么谁不? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮徽诲,結(jié)果婚禮上刹帕,老公的妹妹穿的比我還像新娘。我一直安慰自己谎替,他們只是感情好偷溺,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著钱贯,像睡著了一般挫掏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喷舀,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天砍濒,我揣著相機(jī)與錄音淋肾,去河邊找鬼硫麻。 笑死爸邢,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拿愧。 我是一名探鬼主播杠河,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼浇辜!你這毒婦竟也來了券敌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤柳洋,失蹤者是張志新(化名)和其女友劉穎待诅,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熊镣,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卑雁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绪囱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片测蹲。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鬼吵,靈堂內(nèi)的尸體忽然破棺而出扣甲,到底是詐尸還是另有隱情,我是刑警寧澤齿椅,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布琉挖,位于F島的核電站,受9級特大地震影響涣脚,放射性物質(zhì)發(fā)生泄漏粹排。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一涩澡、第九天 我趴在偏房一處隱蔽的房頂上張望顽耳。 院中可真熱鬧,春花似錦妙同、人聲如沸射富。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胰耗。三九已至,卻和暖如春芒涡,著一層夾襖步出監(jiān)牢的瞬間柴灯,已是汗流浹背卖漫。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赠群,地道東北人羊始。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像查描,于是被迫代替她去往敵國和親突委。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

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

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,090評論 1 32
  • 1.請簡單說明多線程技術(shù)的優(yōu)點(diǎn)和缺點(diǎn)冬三? 優(yōu)點(diǎn):1.能夠適當(dāng)提高程序的執(zhí)行效率匀油;2.能夠適當(dāng)?shù)奶岣哔Y源的利用率,比如...
    Jorunk閱讀 405評論 0 0
  • 該文章屬于<簡書 — Timhbw>原創(chuàng)勾笆,轉(zhuǎn)載請注明: <簡書社區(qū) — Timhbw>http://www.jia...
    伯虔閱讀 17,095評論 3 158
  • 本文出自 Eddy Wiki 敌蚜,轉(zhuǎn)載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,070評論 0 14
  • 平時與小區(qū)里的阿姨關(guān)系還是不錯的,這不前些日子窝爪,阿姨托我?guī)退?7歲的侄子介紹對象弛车,思忖了幾日,在我的朋友中還...
    九夏遇見三冬閱讀 186評論 0 1