Ear*_*tos 118 android gson retrofit
我从使用Volley迁移到Retrofit,我已经拥有了我之前使用的gson类,用于将JSONObject响应转换为实现gson注释的对象.当我尝试使用改造来制作http get请求但我的应用程序崩溃时出现此错误:
Unable to start activity ComponentInfo{com.lightbulb.pawesome/com.example.sample.retrofit.SampleActivity}: java.lang.IllegalArgumentException: Unable to create converter for class com.lightbulb.pawesome.model.Pet
for method GitHubService.getResponse
Run Code Online (Sandbox Code Playgroud)
我遵循改造网站的指南,我想出了这些实现:
这是我尝试执行复古http请求的活动:
public class SampleActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("**sample base url here**")
.build();
GitHubService service = retrofit.create(GitHubService.class);
Call<Pet> callPet = service.getResponse("41", "40");
callPet.enqueue(new Callback<Pet>() {
@Override
public void onResponse(Response<Pet> response) {
Log.i("Response", response.toString());
}
@Override
public void onFailure(Throwable t) {
Log.i("Failure", t.toString());
}
});
try{
callPet.execute();
} catch (IOException e){
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的界面变成了我的API
public interface GitHubService {
@GET("/ **sample here** /{petId}/{otherPet}")
Call<Pet> getResponse(@Path("petId") String userId, @Path("otherPet") String otherPet);
}
Run Code Online (Sandbox Code Playgroud)
最后应该是响应的Pet类:
public class Pet implements Parcelable {
public static final String ACTIVE = "1";
public static final String NOT_ACTIVE = "0";
@SerializedName("is_active")
@Expose
private String isActive;
@SerializedName("pet_id")
@Expose
private String petId;
@Expose
private String name;
@Expose
private String gender;
@Expose
private String age;
@Expose
private String breed;
@SerializedName("profile_picture")
@Expose
private String profilePicture;
@SerializedName("confirmation_status")
@Expose
private String confirmationStatus;
/**
*
* @return
* The confirmationStatus
*/
public String getConfirmationStatus() {
return confirmationStatus;
}
/**
*
* @param confirmationStatus
* The confirmation_status
*/
public void setConfirmationStatus(String confirmationStatus) {
this.confirmationStatus = confirmationStatus;
}
/**
*
* @return
* The isActive
*/
public String getIsActive() {
return isActive;
}
/**
*
* @param isActive
* The is_active
*/
public void setIsActive(String isActive) {
this.isActive = isActive;
}
/**
*
* @return
* The petId
*/
public String getPetId() {
return petId;
}
/**
*
* @param petId
* The pet_id
*/
public void setPetId(String petId) {
this.petId = petId;
}
/**
*
* @return
* The name
*/
public String getName() {
return name;
}
/**
*
* @param name
* The name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* @return
* The gender
*/
public String getGender() {
return gender;
}
/**
*
* @param gender
* The gender
*/
public void setGender(String gender) {
this.gender = gender;
}
/**
*
* @return
* The age
*/
public String getAge() {
return age;
}
/**
*
* @param age
* The age
*/
public void setAge(String age) {
this.age = age;
}
/**
*
* @return
* The breed
*/
public String getBreed() {
return breed;
}
/**
*
* @param breed
* The breed
*/
public void setBreed(String breed) {
this.breed = breed;
}
/**
*
* @return
* The profilePicture
*/
public String getProfilePicture() {
return profilePicture;
}
/**
*
* @param profilePicture
* The profile_picture
*/
public void setProfilePicture(String profilePicture) {
this.profilePicture = profilePicture;
}
protected Pet(Parcel in) {
isActive = in.readString();
petId = in.readString();
name = in.readString();
gender = in.readString();
age = in.readString();
breed = in.readString();
profilePicture = in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(isActive);
dest.writeString(petId);
dest.writeString(name);
dest.writeString(gender);
dest.writeString(age);
dest.writeString(breed);
dest.writeString(profilePicture);
}
@SuppressWarnings("unused")
public static final Parcelable.Creator<Pet> CREATOR = new Parcelable.Creator<Pet>() {
@Override
public Pet createFromParcel(Parcel in) {
return new Pet(in);
}
@Override
public Pet[] newArray(int size) {
return new Pet[size];
}
};
}
Run Code Online (Sandbox Code Playgroud)
iag*_*een 203
在此之前2.0.0
,默认转换器是一个gson转换器,但在2.0.0
以后的默认转换器中ResponseBody
.来自文档:
默认情况下,Retrofit只能将HTTP主体反序列化为OkHttp的
ResponseBody
类型,并且只能接受其RequestBody
类型@Body
.
在2.0.0+
,你需要明确指定你想要一个Gson转换器:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("**sample base url here**")
.addConverterFactory(GsonConverterFactory.create())
.build();
Run Code Online (Sandbox Code Playgroud)
您还需要将以下依赖项添加到gradle文件中:
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
Run Code Online (Sandbox Code Playgroud)
使用与转换相同的版本转换器.以上匹配此改进依赖:
compile ('com.squareup.retrofit2:retrofit:2.1.0')
Run Code Online (Sandbox Code Playgroud)
此外,请注意,编写本文时,改进文档并未完全更新,这就是为什么该示例让您陷入困境的原因.来自文档:
注意:此站点仍在为新的2.0 API进行扩展.
Sil*_*los 168
如果有人在将来遇到这种情况,因为您试图定义自己的自定义转换器工厂并且收到此错误,也可能是因为在具有相同序列化名称的类中具有多个变量.IE:
public class foo {
@SerializedName("name")
String firstName;
@SerializedName("name")
String lastName;
}
Run Code Online (Sandbox Code Playgroud)
序列化名称定义两次(可能是错误的)也会抛出这个完全相同的错误.
更新:请记住,此逻辑也适用于继承.如果使用与子类中具有相同序列化名称的对象扩展到父类,则会导致同样的问题.
Moh*_*hat 29
只要确保您没有两次使用相同的序列化名称
@SerializedName("name") val name: String
@SerializedName("name") val firstName: String
Run Code Online (Sandbox Code Playgroud)
只需删除其中之一
就我而言,我使用的是 Moshi 库和 Retrofit 2.0,即
// Moshi
implementation 'com.squareup.moshi:moshi-kotlin:1.9.3'
// Retrofit with Moshi Converter
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
Run Code Online (Sandbox Code Playgroud)
我忘记将自定义 Moshi json 转换器适配器工厂对象传递给 moshi 转换器工厂构造函数。
private val moshi = Moshi.Builder() // adapter
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create()) // <- missing moshi json adapter insance
.baseUrl(BASE_URL)
.build()
Run Code Online (Sandbox Code Playgroud)
使固定: .addConverterFactory(MoshiConverterFactory.create(moshi))
基于最高评论,我更新了我的导入
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
Run Code Online (Sandbox Code Playgroud)
我使用http://www.jsonschema2pojo.org/来从Spotify json结果创建pojo,并确保指定Gson格式.
目前有Android Studio插件可以为您创建pojo或Kotlin数据模型.mac的一个很好的选择是Quicktype. https://itunes.apple.com/us/app/paste-json-as-code-quicktype/id1330801220
@Silmarilos 的帖子帮助我解决了这个问题。就我而言,我使用“id”作为序列化名称,如下所示:
@SerializedName("id")
var node_id: String? = null
Run Code Online (Sandbox Code Playgroud)
我把它改为
@SerializedName("node_id")
var node_id: String? = null
Run Code Online (Sandbox Code Playgroud)
现在一切都在工作。我忘记了“id”是默认属性。