2017-09-23 107 views

回答

0

我怎麼能通過java代碼得到這個JSON http://api.fixer.io/latest並在地圖上寫mas「rates」?

您可以通過使用GsonRetrofit,並Rxjava實現這一目標。

這裏有依賴關係 - 的build.gradle(應用級):

allprojects { 
    repositories { 
     google() 
     jcenter() 
    } 

    project.ext { 
     gsonVersion = "2.8.0" 
     retrofit2Version = "2.3.0" 
     okHttp3Version = "3.8.1" 
     rxandroidVersion = "1.2.0" 
     rxjavaVersion = "1.1.4" 
    } 
} 

而在模塊級的build.gradle:

dependencies { 
    implementation fileTree(dir: 'libs', include: ['*.jar']) 
    implementation 'com.android.support:appcompat-v7:26.1.0' 
    implementation 'com.android.support.constraint:constraint-layout:1.0.2' 
    testImplementation 'junit:junit:4.12' 

    androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', { 
      exclude group: 'com.android.support', module: 'support-annotations' 
     }) 

    compile "com.google.code.gson:gson:$rootProject.ext.gsonVersion" 
    compile "com.squareup.okhttp3:okhttp:$rootProject.ext.okHttp3Version" 
    compile "com.squareup.okhttp3:okhttp-urlconnection:$rootProject.ext.okHttp3Version" 
    compile "com.squareup.retrofit2:retrofit:$rootProject.ext.retrofit2Version" 
    compile "com.squareup.retrofit2:converter-gson:$rootProject.ext.retrofit2Version" 
    compile "io.reactivex:rxandroid:$rootProject.ext.rxandroidVersion" 
    compile "io.reactivex:rxjava:$rootProject.ext.rxjavaVersion" 
} 

我加<uses-permission android:name="android.permission.INTERNET" />到我的清單文件,然後我創建處理從您提供的url獲取數據的界面:

import retrofit2.Call; 
import retrofit2.http.GET; 

public interface RestInterface { 
    @GET("/latest") 
    Call<ResultFromAPI> getJsonObjects(); 
} 

首先,我去我的瀏覽器的URL,我收到了JSON文本,我複製並粘貼到json2pojo,然後我爲目標語言,源類型的註釋風格等以下選擇:

json2pojoimg

點擊預覽,你會看到你可以創建什麼類的響應(JSON文本)從URL。

接下來,我創建了一些類包含從URL的響應:

import com.google.gson.annotations.Expose; 
import com.google.gson.annotations.SerializedName; 

public class ResultFromAPI { 

    @SerializedName("base") 
    @Expose 
    private String base; 

    @SerializedName("date") 
    @Expose 
    private String date; 

    @SerializedName("rates") 
    @Expose 
    private Rates rates; 

    public String getBase() { 
     return base; 
    } 

    public void setBase(String base) { 
     this.base = base; 
    } 

    public String getDate() { 
     return date; 
    } 

    public void setDate(String date) { 
     this.date = date; 
    } 

    public Rates getRates() { 
     return rates; 
    } 

    public void setRates(Rates rates) { 
     this.rates = rates; 
    } 
} 

這是利率類:

import com.google.gson.annotations.Expose; 
import com.google.gson.annotations.SerializedName; 

public class Rates { 

    @SerializedName("AUD") 
    @Expose 
    private Double aUD; 

    @SerializedName("BGN") 
    @Expose 
    private Double bGN; 

    @SerializedName("BRL") 
    @Expose 
    private Double bRL; 

    @SerializedName("CAD") 
    @Expose 
    private Double cAD; 

    @SerializedName("CHF") 
    @Expose 
    private Double cHF; 

    @SerializedName("CNY") 
    @Expose 
    private Double cNY; 

    @SerializedName("CZK") 
    @Expose 
    private Double cZK; 

    @SerializedName("DKK") 
    @Expose 
    private Double dKK; 

    @SerializedName("GBP") 
    @Expose 
    private Double gBP; 

    @SerializedName("HKD") 
    @Expose 
    private Double hKD; 

    @SerializedName("HRK") 
    @Expose 
    private Double hRK; 

    @SerializedName("HUF") 
    @Expose 
    private Double hUF; 

    @SerializedName("IDR") 
    @Expose 
    private Integer iDR; 

    @SerializedName("ILS") 
    @Expose 
    private Double iLS; 

    @SerializedName("INR") 
    @Expose 
    private Double iNR; 

    @SerializedName("JPY") 
    @Expose 
    private Double jPY; 

    @SerializedName("KRW") 
    @Expose 
    private Double kRW; 

    @SerializedName("MXN") 
    @Expose 
    private Double mXN; 

    @SerializedName("MYR") 
    @Expose 
    private Double mYR; 

    @SerializedName("NOK") 
    @Expose 
    private Double nOK; 

    @SerializedName("NZD") 
    @Expose 
    private Double nZD; 

    @SerializedName("PHP") 
    @Expose 
    private Double pHP; 

    @SerializedName("PLN") 
    @Expose 
    private Double pLN; 

    @SerializedName("RON") 
    @Expose 
    private Double rON; 

    @SerializedName("RUB") 
    @Expose 
    private Double rUB; 

    @SerializedName("SEK") 
    @Expose 
    private Double sEK; 

    @SerializedName("SGD") 
    @Expose 
    private Double sGD; 

    @SerializedName("THB") 
    @Expose 
    private Double tHB; 

    @SerializedName("TRY") 
    @Expose 
    private Double tRY; 

    @SerializedName("USD") 
    @Expose 
    private Double uSD; 

    @SerializedName("ZAR") 
    @Expose 
    private Double zAR; 

    public Double getAUD() { 
     return aUD; 
    } 

    public void setAUD(Double aUD) { 
     this.aUD = aUD; 
    } 

    public Double getBGN() { 
     return bGN; 
    } 

    public void setBGN(Double bGN) { 
     this.bGN = bGN; 
    } 

    public Double getBRL() { 
     return bRL; 
    } 

    public void setBRL(Double bRL) { 
     this.bRL = bRL; 
    } 

    public Double getCAD() { 
     return cAD; 
    } 

    public void setCAD(Double cAD) { 
     this.cAD = cAD; 
    } 

    public Double getCHF() { 
     return cHF; 
    } 

    public void setCHF(Double cHF) { 
     this.cHF = cHF; 
    } 

    public Double getCNY() { 
     return cNY; 
    } 

    public void setCNY(Double cNY) { 
     this.cNY = cNY; 
    } 

    public Double getCZK() { 
     return cZK; 
    } 

    public void setCZK(Double cZK) { 
     this.cZK = cZK; 
    } 

    public Double getDKK() { 
     return dKK; 
    } 

    public void setDKK(Double dKK) { 
     this.dKK = dKK; 
    } 

    public Double getGBP() { 
     return gBP; 
    } 

    public void setGBP(Double gBP) { 
     this.gBP = gBP; 
    } 

    public Double getHKD() { 
     return hKD; 
    } 

    public void setHKD(Double hKD) { 
     this.hKD = hKD; 
    } 

    public Double getHRK() { 
     return hRK; 
    } 

    public void setHRK(Double hRK) { 
     this.hRK = hRK; 
    } 

    public Double getHUF() { 
     return hUF; 
    } 

    public void setHUF(Double hUF) { 
     this.hUF = hUF; 
    } 

    public Integer getIDR() { 
     return iDR; 
    } 

    public void setIDR(Integer iDR) { 
     this.iDR = iDR; 
    } 

    public Double getILS() { 
     return iLS; 
    } 

    public void setILS(Double iLS) { 
     this.iLS = iLS; 
    } 

    public Double getINR() { 
     return iNR; 
    } 

    public void setINR(Double iNR) { 
     this.iNR = iNR; 
    } 

    public Double getJPY() { 
     return jPY; 
    } 

    public void setJPY(Double jPY) { 
     this.jPY = jPY; 
    } 

    public Double getKRW() { 
     return kRW; 
    } 

    public void setKRW(Double kRW) { 
     this.kRW = kRW; 
    } 

    public Double getMXN() { 
     return mXN; 
    } 

    public void setMXN(Double mXN) { 
     this.mXN = mXN; 
    } 

    public Double getMYR() { 
     return mYR; 
    } 

    public void setMYR(Double mYR) { 
     this.mYR = mYR; 
    } 

    public Double getNOK() { 
     return nOK; 
    } 

    public void setNOK(Double nOK) { 
     this.nOK = nOK; 
    } 

    public Double getNZD() { 
     return nZD; 
    } 

    public void setNZD(Double nZD) { 
     this.nZD = nZD; 
    } 

    public Double getPHP() { 
     return pHP; 
    } 

    public void setPHP(Double pHP) { 
     this.pHP = pHP; 
    } 

    public Double getPLN() { 
     return pLN; 
    } 

    public void setPLN(Double pLN) { 
     this.pLN = pLN; 
    } 

    public Double getRON() { 
     return rON; 
    } 

    public void setRON(Double rON) { 
     this.rON = rON; 
    } 

    public Double getRUB() { 
     return rUB; 
    } 

    public void setRUB(Double rUB) { 
     this.rUB = rUB; 
    } 

    public Double getSEK() { 
     return sEK; 
    } 

    public void setSEK(Double sEK) { 
     this.sEK = sEK; 
    } 

    public Double getSGD() { 
     return sGD; 
    } 

    public void setSGD(Double sGD) { 
     this.sGD = sGD; 
    } 

    public Double getTHB() { 
     return tHB; 
    } 

    public void setTHB(Double tHB) { 
     this.tHB = tHB; 
    } 

    public Double getTRY() { 
     return tRY; 
    } 

    public void setTRY(Double tRY) { 
     this.tRY = tRY; 
    } 

    public Double getUSD() { 
     return uSD; 
    } 

    public void setUSD(Double uSD) { 
     this.uSD = uSD; 
    } 

    public Double getZAR() { 
     return zAR; 
    } 

    public void setZAR(Double zAR) { 
     this.zAR = zAR; 
    } 
} 

接下來,我創建的類將負責處理呼叫(使用先前創建的其餘接口),它也將負責接收響應:

import android.support.annotation.NonNull; 
import android.support.annotation.WorkerThread; 
import android.util.Log; 

import retrofit2.Call; 
import retrofit2.Callback; 
import retrofit2.Response; 
import rx.Observable; 
import rx.functions.Action1; 

public class CallToFixerAPI { 

    private static final String TAG = "CallToFixerAPITAG_"; 
    private final RestInterface restInterface; 

    public CallToFixerAPI(RestInterface restInterface) { 
     this.restInterface = restInterface; 
    } 

    @WorkerThread 
    public void call(String url, final Action1<ResultFromAPI> responseAction1) throws Exception { 
     try { 
      Call<ResultFromAPI> call = restInterface.getJsonObjects(); 

      call.enqueue(new Callback<ResultFromAPI>() { 
       @Override 
       public void onResponse(@NonNull Call<ResultFromAPI> call, 
             @NonNull Response<ResultFromAPI> responseFromAPI) { 
        Observable.just(responseFromAPI.body()).subscribe(responseAction1); 
       } 

       @Override 
       public void onFailure(@NonNull Call<ResultFromAPI> call, 
             @NonNull Throwable t) { 
        Log.e(TAG, "onFailure: " + t.getMessage()); 
       } 
      }); 
     } catch (Exception e) { 
      Log.e(TAG, "Failed to execute call to fixer api: " + url + ": " + e.toString()); 
     } 
    } 
} 

最後,我在MainActivity綁在一起的一切:

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

import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.util.HashMap; 
import java.util.Map; 

import retrofit2.Retrofit; 
import retrofit2.converter.gson.GsonConverterFactory; 
import rx.Observable; 
import rx.functions.Action1; 

public class MainActivity extends AppCompatActivity { 

    private static final String TAG = "MainActivityTAG_"; 
    private CallToFixerAPI callToFixerAPI; 
    private HashMap<String, Object> ratesHashMap = new HashMap<>(); 

    public static Map<String, Object> ConvertObjectToMap(Object obj) 
      throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 
     Method[] methods = obj.getClass().getMethods(); 

     Map<String, Object> map = new HashMap<>(); 
     for (Method m : methods) { 
      if (m.getName().startsWith("get") && !m.getName().startsWith("getClass")) { 
       Object value = m.invoke(obj); 
       map.put(m.getName().substring(3), value); 
      } 
     } 
     return map; 
    } 

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

     String url = "http://api.fixer.io/"; 

     Retrofit retrofit = new Retrofit.Builder() 
       .baseUrl(url) 
       .addConverterFactory(GsonConverterFactory.create()) 
       .build(); 

     RestInterface restInterface = retrofit.create(RestInterface.class); 

     callToFixerAPI = new CallToFixerAPI(restInterface); 

     getResponseFromAPI(url, new Action1<ResultFromAPI>() { 
      @Override 
      public void call(ResultFromAPI resultFromAPI) { 
       Log.d(TAG, "Base is: " + resultFromAPI.getBase()); 
       Log.d(TAG, "Date is: " + resultFromAPI.getDate()); 
       try { 
        ratesHashMap = (HashMap<String, Object>) ConvertObjectToMap(resultFromAPI.getRates()); 
        Log.d(TAG, "Rates are: " + ratesHashMap); 
       } catch (IllegalAccessException | InvocationTargetException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public void getResponseFromAPI(String url, final Action1<ResultFromAPI> resultAction1) { 
     try { 
      callToFixerAPI.call(url, new Action1<ResultFromAPI>() { 
       @Override 
       public void call(ResultFromAPI results) { 
        Observable.just(results).subscribe(resultAction1); 
       } 
      }); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

我知道這可能看起來很多來包裝你的頭部周圍,如果你是新來的Android,或者如果你不知道Rxjava或改造 - 但是如果你請按照上述步驟進行編譯,並且無需任何錯誤即可編譯程序,您應該在調試器模式下運行該應用程序,並在MainActivityCallToFixerAPI之間設置多個斷點。

我會建議爲所有Log.d語句和以Observable.just(...)開頭的任何句子添加一個斷點。

注意

  • 我使用過Android Studio 3.0 - 所以有些事情,如果你沒有使用過Android Studio 3.0,以及可能與您的IDE不同。
  • 我有意將所有內容添加到Logcat(Android監視器)中,而屏幕上沒有任何內容,答案變得太長了。另外,我離開了如何最好地向您展示ratesHashMap的決定。
+0

這是很多的樣板,只是爲了在Android中創建Web請求並提取一些JSON值 –