Estou migrando do Volley para o Retrofit, já tenho a classe gson que usei antes para converter a resposta JSONObject em um objeto que implementa as anotações do gson. Quando estou tentando fazer uma solicitação de obtenção de http usando a atualização, o meu aplicativo trava com este erro:
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
Estou seguindo o guia no site de modernização e eu venho com essas implementações:
Esta é a minha atividade em que estou tentando executar a solicitação http retro:
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();
}
}
}
Minha interface que virou minha API
public interface GitHubService {
@GET("/ **sample here** /{petId}/{otherPet}")
Call<Pet> getResponse(@Path("petId") String userId, @Path("otherPet") String otherPet);
}
E, finalmente, a classe Pet, que deve ser a resposta:
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];
}
};
}
Respostas:
Antes
2.0.0
, o conversor padrão era um conversor gson, mas,2.0.0
posteriormente, o conversor padrão éResponseBody
. Dos documentos:Em
2.0.0+
, você precisa especificar explicitamente que deseja um conversor Gson:Você também precisará adicionar a seguinte dependência ao seu arquivo de classificação:
Use a mesma versão para o conversor e para o seu retrofit. O acima corresponde a essa dependência de atualização:
Além disso, observe que, ao escrever isso, os documentos de atualização não são completamente atualizados, e é por isso que esse exemplo causou problemas. Dos documentos:
fonte
Se alguém se deparar com isso no futuro porque você está tentando definir sua própria fábrica de conversores personalizados e está recebendo esse erro, também pode ser causado por ter várias variáveis em uma classe com um erro de ortografia ou o mesmo nome serializado. IE:
Ter nomes serializados definidos duas vezes (provavelmente por engano) também gera esse mesmo erro.
Atualização : lembre-se de que essa lógica também é verdadeira por herança. Se você estender para uma classe pai com um objeto que tenha o mesmo nome serializado que você faz na subclasse, isso causará o mesmo problema.
fonte
Com base nos comentários principais, atualizei minhas importações
Eu usei o http://www.jsonschema2pojo.org/ para criar pojo's a partir dos resultados do Spotify json e certificar-se de especificar o formato Gson.
Atualmente, existem plugins do Android Studio que podem criar os modelos de dados do pojo ou Kotlin para você. Uma ótima opção para mac é o Quicktype. https://itunes.apple.com/us/app/paste-json-as-code-quicktype/id1330801220
fonte
apenas verifique se você não está usando o mesmo nome de serialização duas vezes
basta remover um deles
fonte
No meu caso, eu tinha um objeto TextView dentro da minha classe modal e o GSON não sabia como serializá-lo. Marcá-lo como 'transitório' resolveu o problema.
fonte
A publicação de @ Silmarilos me ajudou a resolver isso. No meu caso, usei "id" como um nome serializado, assim:
e eu mudei para
Todos trabalhando agora. Esqueci que 'id' é um atributo padrão.
fonte
Isso pode ajudar alguém
No meu caso, por engano, escrevi SerializedName assim
Deveria ser
fonte
Ei, eu estava passando pelo mesmo problema hoje, levei um dia inteiro para encontrar uma solução, mas esta é a solução que encontrei finalmente. Estou usando o Dagger no meu código e eu precisava implementar o conversor Gson na minha instância de atualização.
então esse era meu código antes
foi isso que eu acabei com
observe como não há conversor no primeiro exemplo e, se você não instanciar o Gson, você o adiciona assim
e verifique se você o incluiu na chamada de método para atualização.
mais uma vez espero que isso ajude alguém como eu.
fonte
No meu caso, foi devido a uma tentativa de levar uma lista retornada pelo meu serviço para um ArrayList. Então, o que eu tinha era:
quando eu deveria ter tido
Espero que isso ajude alguém!
fonte
No meu caso, o problema era que meu modelo SUPERCLASS tinha esse campo definido. Muito idiota, eu sei ....
fonte