无法在 Android 改造库中为我的类创建转换器

我已经从使用 Volley 迁移到卢克菲特,我已经有了 gson 类,我以前用它来将 JSONObject 响应转换为实现 gson 注释的对象。当我试图通过翻新来获取 http 请求时,我的应用程序崩溃了,出现了以下错误:

 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

我遵循 翻新站点的指南,提出了这些实现方案:

这是我尝试执行 retro 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();
}


}
}

我的接口变成了我的 API

public interface GitHubService {
@GET("/ **sample here** /{petId}/{otherPet}")
Call<Pet> getResponse(@Path("petId") String userId, @Path("otherPet") String otherPet);
}

最后是 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];
}
};
}
127359 次浏览

2.0.0之前,默认的转换器是 gson 转换器,但在 2.0.0和以后的版本中,默认的转换器是 ResponseBody。来自文件:

默认情况下,Afterfit 只能将 HTTP 正文反序列化为 OkHttp 正文 ResponseBody类型,它只能接受其 RequestBody类型 @Body.

2.0.0+中,您需要显式地指定希望使用 Gson 转换器:

Retrofit retrofit = new Retrofit.Builder()
.baseUrl("**sample base url here**")
.addConverterFactory(GsonConverterFactory.create())
.build();

您还需要将以下依赖添加到您的等级文件:

compile 'com.squareup.retrofit2:converter-gson:2.1.0'

对转换器使用与改造时相同的版本。以上内容与改造依赖项相匹配:

compile ('com.squareup.retrofit2:retrofit:2.1.0')

另外,在撰写本文时请注意,改造文档没有完全更新,这就是为什么那个示例给您带来麻烦的原因。来自文件:

注意: 这个站点仍然在为新的2.0 API 进行扩展的过程中。

基于最高评论,我更新了我的导入

implementation 'com.squareup.retrofit2:retrofit:2.1.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'

我使用 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

如果将来有人因为试图定义自己的自定义转换器工厂而遇到这个错误,也可能是由于类中有多个变量拼写错误或同样的序列化名称造成的。IE:

public class foo {
@SerializedName("name")
String firstName;
@SerializedName("name")
String lastName;
}

定义了两次序列化名称(可能是错误定义的)也会抛出这个完全相同的错误。

更新 : 请记住,这个逻辑通过继承也是 true。如果扩展到具有与子类中相同序列化名称的对象的父类,则会导致同样的问题。

在我的例子中,模态类中有一个 TextView 对象,而 GSON 不知道如何序列化它。将其标记为“暂时”就解决了这个问题。

这也许能帮到某人

在我的情况下,我错误地写了这样的 序列化名称

@SerializedName("name","time")
String name,time;

应该是的

@SerializedName("name")
String name;


@SerializedName("time")
String time;

@ Silmarilos 的帖子帮我解决了这个问题。在我的例子中,我使用“ id”作为序列化名称,如下所示:

 @SerializedName("id")
var node_id: String? = null

我把它改成了

 @SerializedName("node_id")
var node_id: String? = null

现在一切正常。我忘了‘ id’是默认属性。

嘿,我今天也遇到了同样的问题,我花了一整天的时间才找到一个解决方案,但这就是我最终找到的解决方案。 我在我的代码中使用匕首,我需要在我的改造实例中实现 Gson 转换器。

这就是我以前的原则

@Provides
@Singleton
Retrofit providesRetrofit(Application application,OkHttpClient client) {
String SERVER_URL=URL;
Retrofit.Builder builder = new Retrofit.Builder();
builder.baseUrl(SERVER_URL);
return builder
.client(client)
.build();
}

这就是我的结局

@Provides
@Singleton
Retrofit providesRetrofit(Application application,OkHttpClient client, Gson gson) {
String SERVER_URL=URL;
Retrofit.Builder builder = new Retrofit.Builder();
builder.baseUrl(SERVER_URL);
return builder
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}

注意在第一个例子中没有转换器,如果你没有实例化 Gson,你可以像这样添加它

    @Provides
@Singleton
Gson provideGson() {
GsonBuilder gsonBuilder = new GsonBuilder();


gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
return gsonBuilder.create();
}

并确保您已将其包含在改造的方法调用中。

再次希望这能帮到像我这样的人。

在我的例子中,这是由于尝试将服务返回的 List 转换为 ArrayList。所以我得到的是:

@Json(name = "items")
private ArrayList<ItemModel> items;

我本该那么做的

@Json(name = "items")
private List<ItemModel> items;

希望这对谁有帮助!

在我的例子中,问题是我的 SUPERClass 模型中定义了这个字段。

只要确保不使用相同的序列化名称两次

 @SerializedName("name") val name: String
@SerializedName("name") val firstName: String

只要移除其中一个

build.gradle改变

minifyEnabled true

minifyEnabled false

解决了我的问题。

在我的情况下,我使用 MoshiRetrofit,我的错误是:

我没有为包含在 Response类服务中的对象定义 body

例如:

@JsonSerializable
data class Balance(
@field:Json(name = "balance") var balance: Double,
@field:Json(name = "currency") var currency: Currency

Currency类是空的。所以我完成了它和问题修复!

在我的例子中,我使用的是莫希图书馆中的卢克菲特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'

我忘记将定制的莫希 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()

解决方案: .addConverterFactory(MoshiConverterFactory.create(moshi))

在我使用 kotlinx.serialization的例子中,同样的例外是通过改造引发的,

这是由于缺少 @Serializable注释。

@Serializable
data class MyClass(
val id: String
)