【发布时间】:2015-11-08 09:15:29
【问题描述】:
我对 android 还很陌生,并且正在使用改造和领域。我很难从 url 中获取这个 json 字符串来正确解析。 这是我到目前为止所做的。
我的界面:
package com.example.stephen.traveland.Rest;
import android.database.Observable;
import com.example.stephen.traveland.Models.Country;
import java.util.List;
import retrofit.http.GET;
public interface TravelAnDInterface {
@GET("/index-updated.json/")
Observable<List<Country>> getAllCountries();
}
这个 java 类是我使用接口从 url 中提取字符串的地方。
package com.example.stephen.traveland.Rest;
import android.content.Context;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.squareup.okhttp.OkHttpClient;
import io.realm.RealmObject;
import retrofit.RestAdapter;
import retrofit.android.AndroidLog;
import retrofit.client.OkClient;
import retrofit.converter.GsonConverter;
public class TravelAnD {
private static final String URL = "http://data.international.gc.ca/travel-voyage/";
private final static Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class);
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.create();
private static TravelAnDInterface sTravelAnDSvc;
public static TravelAnDInterface getCountries() {
if (sTravelAnDSvc == null) {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(URL)
.setClient(new OkClient(new OkHttpClient()))
.setConverter(new GsonConverter(gson))
.setLogLevel(RestAdapter.LogLevel.FULL)
.setLog(new AndroidLog("RETROFIT"))
.build();
sTravelAnDSvc = restAdapter.create(TravelAnDInterface.class);
}
return sTravelAnDSvc;
}
}
这是我的对象类之一,因此您可以看到我要如何完成。
package com.example.stephen.traveland.Models;
import io.realm.RealmList;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
public class Country extends RealmObject {
@PrimaryKey
private int country_id;
private String country_iso;
private String country_in_english;
private String country_in_french;
private int advisory_state;
private RealmList<DatePublished> datePublished;
private int advisory_warning;
private int regional_advisory;
private int content;
private String recent_update_type;
private RealmList<English> english;
private RealmList<French> french;
public Country() { super(); }
public Country(int country_id, String country_iso, String country_in_english, String country_in_french,
int advisory_state, int advisory_warning, int regional_advisory, int content) {
this.country_id = country_id;
this.country_iso = country_iso;
this.country_in_english = country_in_english;
this.country_in_french = country_in_french;
this.advisory_state = advisory_state;
this.advisory_warning = advisory_warning;
this.regional_advisory = regional_advisory;
this.content = content;
}
public int getAdvisory_state() { return advisory_state; }
public void setAdvisory_state(int advisory_state) { this.advisory_state = advisory_state; }
public int getAdvisory_warning() { return advisory_warning; }
public void setAdvisory_warning(int advisory_warning) { this.advisory_warning = advisory_warning; }
public int getContent() { return content; }
public void setContent(int content) { this.content = content; }
public int getCountry_id() { return country_id; }
public void setCountry_id(int country_id) { this.country_id = country_id; }
public String getCountry_in_english() { return country_in_english; }
public void setCountry_in_english(String country_in_english) { this.country_in_english = country_in_english; }
public String getCountry_in_french() { return country_in_french; }
public void setCountry_in_french(String country_in_french) { this.country_in_french = country_in_french; }
public String getCountry_iso() { return country_iso; }
public void setCountry_iso(String country_iso) {this.country_iso = country_iso; }
public RealmList<DatePublished> getDatePublished() { return datePublished; }
public void setDatePublished(RealmList<DatePublished> datePublished) { this.datePublished = datePublished; }
public RealmList<English> getEnglish() { return english; }
public void setEnglish(RealmList<English> english) {this.english = english;}
public RealmList<French> getFrench() { return french; }
public void setFrench(RealmList<French> french) { this.french = french; }
public String getRecent_update_type() { return recent_update_type; }
public void setRecent_update_type(String recent_update_type) { this.recent_update_type = recent_update_type; }
public int getRegional_advisory() { return regional_advisory; }
public void setRegional_advisory(int regional_advisory) { this.regional_advisory = regional_advisory; }
}
我已经创建了类来存储数据,但是遇到了一个问题,因为字符串本身很奇怪且难以处理。我希望能得到一些指导,说明我做错了什么。任何帮助将不胜感激。
@编辑 不再将 Realm 用于我的任何对象,并且之前的代码已进行了相当多的更改,因为数据太大而无法存储在手机上。对于一台设备来说,信息量太大了。
但是,新问题或相同问题只是在不同的情况下。我的 retofit 调用很好地抓取了数据,就在我将它们放入对象时,当我想从中提取数据时,该对象为空。这是我的代码的一些小sn-ps。
public void gatherData() {
final ProgressDialog progress = new ProgressDialog(this);
progress.setTitle("Please wait...");
progress.setMessage("Loading data...");
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress.setIndeterminate(false);
progress.show();
bossModel1 = new BossModel();
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)
.create();
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://data.international.gc.ca/travel-voyage")
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
Api service = restAdapter.create(Api.class);
service.listRepos(new Callback<BossModel>() {
@Override
public void success(BossModel bossModel, Response response) {
bossModel1 = bossModel;
Log.i("SUCCESS", "" + bossModel1.getData());
for (Field field : bossModel1.getData().getClass().getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
Log.i("ahlsdkjha: ", field.getName());
countryISO.add(field.getName());
}
}
progress.dismiss();
}
@Override
public void failure(RetrofitError error) {
}
});
}
public void gatherVPData(final String countryIso) {
vpModel1 = new VPModel();
Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)
.create();
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://data.international.gc.ca/travel-voyage")
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
Api service = restAdapter.create(Api.class);
service.getCountry(countryIso, new Callback<VPModel>() {
@Override
public void success(VPModel vpModel, Response response) {
vpModel1 = vpModel;
Log.d("SUCCESS2: ", "" + vpModel1.getData());
}
@Override
public void failure(RetrofitError error) {
}
});
}
API
public interface Api {
@GET("/index-updated.json")
void listRepos(Callback<BossModel> callback);
@GET("/countries/cta-cap-{country}.json")
void getCountry(@Path("country") String countryIso, Callback<VPModel> callback);
}
这里是我尝试用gatherVPData 提取的数据填充新对象列表的地方。由于某种原因数据为空,因此未填充。
public void populateCountryList(int id) {
for (int i = 0; i < countryISO.size() - 1; i++) {
gatherVPData(countryISO.get(i));
if (vpModel1.getData().getAdvisoryState() == id) {
countries.add(new Country(
vpModel1.getData().getCountryIso(),
vpModel1.getData().getAdvisoryState(),
vpModel1.getData().getHasAdvisoryWarning(),
vpModel1.getData().getHasRegionalAdvisory(),
vpModel1.getData().getHasContent(),
vpModel1.getData().getUpdateMetadata(),
vpModel1.getData().getEng(),
vpModel1.getData().getFra()
));
}
}
}
【问题讨论】:
-
您确定
Observable部分吗?它看起来像 Rx,但你导入了android.database.Observable。 -
第一个问题是尾随
/。查看您的日志,您应该会看到 404 错误。第二个问题是您尝试解析的 json 不适合您要询问的对象。它不是一个列表。它是一个对象,包含一个键data,其中包含您的对象的映射,通过它们的 iso 代码。您将需要另一个至少包含Map<String, Country> data;的模型类 -
将您的 json 放入格式化程序(例如 jsonlint.com)以查看缩进和新行的样子。
-
那么您将遇到其他问题:您的密钥不匹配。而且它们无法匹配,因为键有
-,这是java字段所没有的。您将需要@SerializedName注释。那么你的 3 个 RealmList 对象看起来不正确。 -
最后一点,您似乎从未真正调用过
getAllCountries方法,我认为它在代码的另一部分?
标签: java android json retrofit realm