fbpx
Android高效入門-讀取JSON資料與okHttp

Android高效入門-讀取JSON資料與okHttp

讀取並解析JSON資料

當Android應用程式連線到網路上的服務讀取資料時,並不像先前的登入範例讀取一個字元這麼簡單,在實務上,讀取更多的文字資料如網頁原始碼、XML或JSON格式等,與伺服器連線後使用的通訊協定大都是網頁HTTP協定。

使用Java語言讀取網路HTTP協定的資料大都使用java.io.BufferedReader類別,再以readLine方法在迴圈中收集所有資料,這些設計目的都是取得一個網址的連線,若能用更簡短、有效率的方式能快速取得資料的字串,再進行解析、處理,能夠加快開發速度。

本篇先使用一般的方式取得網址回應的資料,資料為目前的主流JSON格式,先使用內建的JSON.org類別庫解析資料後,在下一篇文章,再更換使用第三方函式庫GsonJackson進行資料的解析並使用Material Design實感設計所推出的新版清單元件RecyclerView類別,以清單的方式展示已取得的資料。

讀取JSON資料

JSON資料格式是一種輕量級的資料交換格式,以文字為基礎、易於閱讀,全名為「JavaScript Object Notation」,它原是在Javascript中表示資料的一種格式,但目前大量使用在各類程式語言中,用來表示資料或提供資料的格式。

請使用瀏覽器開啟以下網址進行測試。

網址: http://atm201605.appspot.com/h

A5104

這是一個JSON格式的測試網址,模擬一個伺服器提供交易資料明細,有五筆交易資料。

  • JSON陣列

用來表示多筆資料,以程式語言的陣列來看,它含有一筆以上的資料,資料間用逗號分隔,並以中括號集合多筆資料成為一個陣列,如下:

[物件1, 物件2, 物件3, … ]
  • JSON物件

用以表示一筆資料,資料中的每個欄位名稱以冒號表示它的值,並以大括號集合所有欄位成為一個物件,如下:

{欄位名稱:欄位值 , 欄位名稱:欄位值 , … }

以下是一筆交易JSON物件的範例:

{“account”:”jack”,”date”:”20160501″,”amount”:1500,”type”:0}

資料的意義如下:

欄位名稱 說明
account jack 帳號名稱
date 20150501 交易日期
amount 1500 交易金額
type 0 交易類型

取得伺服端傳來回應

使用AsyncTask類別設計HTTP連線工作,讀取完成後回傳字串結果,在TransActivity內設計一內部類別TransTask,並繼承AsyncTask,在doInBackground設計連線並讀取伺服器傳來回應的所有字串,程式碼如下:

package com.tom.atm;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class TransActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_trans);
        new TransTask()
               .execute("http://atm201605.appspot.com/h");
   }
   class TransTask extends AsyncTask<String, Void, String>{

       @Override
       protected String doInBackground(String... params) {
           StringBuilder sb = new StringBuilder();
           try {
               URL url = new URL(params[0]);
               BufferedReader in = new BufferedReader(
                       new InputStreamReader(url.openStream()));
               String line = in.readLine();
               while(line!=null){
                   Log.d("HTTP", line);
                    sb.append(line);
                    line = in.readLine();
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return sb.toString();
        }
    }
}

接下來請再覆寫TransTask內的onPostExecute方法,接收doInBackground最後return回值的字串,進行後續解析工作,如下:

public class TransActivity extends AppCompatActivity {
    ...
    class TransTask extends AsyncTask<String, Void, String>{
        ...
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            Log.d("JSON", s);
            parseJSON(s);
        }
    }

    private void parseJSON(String s) {
    }
}

第5-10行,覆寫的onPostExecute方法,在doInBackground方法執行完成後自動執行的方法。

第8行,使用Log類別印出除錯訊息

第9行,呼叫自行設計的parseJSON方法,並傳入從網頁讀取的字串資料。

第13-14行,自行設計的方法,為了解析JSON資料而建立。

以上是連線網路並讀取資料的設計過程,必須設計AsyncTask類別、實作方法、建立網路連線、讀取並收集資料等,這樣的任務實在繁複。如果應用程式中經常需要這類的工作設計時,有無方法可以簡化呢?

第三方類別庫

由於開放原始碼的盛行,有許多專案都提供這類的函式庫,可加快開發速度,簡化繁雜的工作。例如網路連線常用的okHttp、Volley,JSON解析使用Gson或Jackson類別庫。

Gradle設定檔

Android Studio的每一個模組(Module)可以擁有自己的設定檔,而一個專案可以擁有多個模組,設計Android應用程式時就是自動產生個名為「app」的模組。設定檔檔名統一為「build.gradle」,它是一個使用Groovy語法的純文字檔案,記錄這個模組如何編譯、包裝、執行等工作,若模組使用到外來的函式庫也在此檔中加入。一般來說,我們通常只需要修改app模組的build.gradle,如下圖:

A5112

在模組中使用JDK與Android SDK以外的函式庫前,必須在Gradle的設定檔「build.gradle」中設定,請展開專案區的「Gradle Scripts」,點擊開啟「build.gradle(Module:app)」,檔案如下:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "24.0.0 rc2"
    defaultConfig {
        applicationId "com.tom.atm"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.android.support:design:23.3.0'
}

 

相關文章:

Hank Tom

專長為程式語言、雲端服務開發,Linux系統管理, 任職:利拓科技 技術長,海林行動科技 技術總監 輔仁大學 兼任助理教授 , 為 Android高效入門>深度學習、CentOS 7建置、管理與伺服器架設實戰、Java網路程式設計、雲端網頁程式設計-Google App Engine應用實作 等書作者

This Post Has 5 Comments

  1. Avatar

    老師您好:
    想請教老師,如果該URL需要登入的動作
    一般網頁URL輸入方式為http://admin:admin@192.xxx.xxx.xx…
    而admin就是帳號與密碼,
    那如果要使用這個api,是否URL也能這樣設定呢?
    還是需要其他寫法呢?謝謝.

  2. Avatar

    您好
    請問若要強制中斷請求的話
    該如何實作呢

  3. Avatar

    老師您好,
    最近看到Hahow上面有您的課程非常想要購買,
    可是我現在比較有問題的是關於用Web API讀取JSON這方面的問題
    尤其是在JSON Get Post上面的選擇有許多的疑問想上課
    請問課程裡面會有講解嗎?
    感謝您的回答!

    1. Avatar

      hahow的Android APP高效入門線上課程中,JSON讀取是以GET方式,也無編碼問題(純英文UTF-8),如果有這類需求,可以在學習後在hahow課程單元中留言討論,如果太繁雜無法用寫的,我會利用粉絲專頁的直播機會實作,請追蹤加搶先看 🙂
      Android APP高效入門線上課程: https://hahow.in/cr/androidx
      FB粉專: https://www.facebook.com/Androidpa/

發佈留言

×
×

Cart