无法在Android Retrofit库中为我的班级创建转换器

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进行扩展.

  • 我仍然遇到这个问题 (2认同)

Sil*_*los 168

如果有人在将来遇到这种情况,因为您试图定义自己的自定义转换器工厂并且收到此错误,也可能是因为在具有相同序列化名称的类中具有多个变量.IE:

public class foo {
  @SerializedName("name")
  String firstName;
  @SerializedName("name")
  String lastName;
}
Run Code Online (Sandbox Code Playgroud)

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

更新:请记住,此逻辑也适用于继承.如果使用与子类中具有相同序列化名称的对象扩展到父类,则会导致同样的问题.

  • 这对我来说是个问题,忘记删除移到父类的子类中的字段。谢啦! (2认同)
  • 哇。我的问题来自数据模型.. tnx tnx (2认同)
  • 谢谢 !该错误消息是模棱两可的,您对此进行了帮助 (2认同)
  • 谢谢你让我摆脱了两天的挣扎。我通过声明两个具有相同序列化名称的变量犯了同样的错误。 (2认同)

Moh*_*hat 29

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

 @SerializedName("name") val name: String
 @SerializedName("name") val firstName: String
Run Code Online (Sandbox Code Playgroud)

只需删除其中之一


Hme*_*006 9

就我而言,我使用的是 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))


Jua*_*dez 8

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

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


小智 5

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


Gle*_*ito 5

@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”是默认属性。