Android Retrofit kitaplığında sınıfım için dönüştürücü oluşturulamıyor


130

Volley kullanmaktan Retrofit'e geçerken, JSONObject yanıtını gson açıklamalarını uygulayan bir nesneye dönüştürmek için daha önce kullandığım gson sınıfına zaten sahibim. Güçlendirme kullanarak http isteği almaya çalıştığımda, ancak daha sonra uygulamam şu hatayla çöküyor:

 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

Güçlendirme sitesindeki kılavuzu takip ediyorum ve şu uygulamaları buluyorum:

Bu, retro http talebini yerine getirmeye çalıştığım faaliyetim:

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'm oldu arayüzüm

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

Ve son olarak cevabı olması gereken Pet sınıfı:

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];
        }
    };
}

lütfen bu bağlantının yanıt dizesini ekleyin mysample.com/development/cuteness
koutuk

@koutuk bu sadece bir örnek, btw gönderimi çoktan değiştirdim
Earwin delos Santos

hangi satırda hata alıyorsunuz ....
koutuk

Eğer geçmesi gerektiğini youtube.com/watch?v=gGuUBlzmtPQ Bu videoyu
koutuk

ohh bu eski olan. retrofit square.github.io/retrofit'i
Earwin delos Santos

Yanıtlar:


217

Önceden 2.0.0, varsayılan dönüştürücü bir gson dönüştürücüydü, ancak içinde 2.0.0ve sonrasında varsayılan dönüştürücü ResponseBody. Dokümanlardan:

Varsayılan olarak, Retrofitler yalnızca HTTP OkHttp en cesetleri serisini ResponseBodytipi ve sadece onun kabul edebileceği RequestBodyiçin tipini @Body.

İçinde 2.0.0+, bir Gson dönüştürücü istediğinizi açıkça belirtmeniz gerekir:

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

Not defteri dosyanıza aşağıdaki bağımlılığı da eklemeniz gerekir:

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

Güçlendirmeniz için kullandığınız aynı sürümü dönüştürücü için kullanın. Yukarıdakiler bu güçlendirme bağımlılığıyla eşleşir:

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

Ayrıca, bunu yazarken, güçlendirme belgelerinin tamamen güncellenmediğini, bu nedenle bu örneğin başınızı belaya soktuğunu unutmayın. Dokümanlardan:

Not: Bu site, yeni 2.0 API'leri için genişletilme sürecindedir.


hala sorunu yaşıyorum
user3475052

218

Gelecekte herhangi biri bununla karşılaşırsa, kendi özel dönüştürücü fabrikanızı tanımlamaya çalıştığınız için ve bu hatayı alıyorsanız, bunun nedeni bir sınıfta yanlış yazılmış veya aynı serileştirilmiş ada sahip birden çok değişken olabilir. IE:

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

İki kez tanımlanmış serileştirilmiş isimlere sahip olmak (muhtemelen yanlışlıkla) bu aynı hatayı ortaya çıkaracaktır.

Güncelleme : Bu mantığın kalıtım yoluyla da geçerli olduğunu unutmayın. Alt sınıfta yaptığınız gibi aynı Serileştirilmiş ada sahip bir nesneye sahip bir üst sınıfa genişletirseniz, aynı soruna neden olur.


2
Benim için sorun buydu, ebeveyn sınıfa taşıdığım bir alt sınıfın içindeki bir alanı kaldırmayı unuttum. Teşekkürler dostum!
Vucko

1
Teşekkürler, beni 2 günlük mücadeleden kurtardın. Aynı serileştirilmiş isimlerle 2 değişken bildirerek aynı hatayı yaptım.
Valynk

9

En önemli yoruma göre ithalatlarımı güncelledim

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

Spotify json sonuçlarından pojo oluşturmak ve Gson formatını belirttiğinizden emin olmak için http://www.jsonschema2pojo.org/ kullandım .

Bugünlerde sizin için pojo veya Kotlin veri modellerini oluşturabilecek Android Studio eklentileri var. Mac için harika bir seçenek de Quicktype. https://itunes.apple.com/us/app/paste-json-as-code-quicktype/id1330801220


6

aynı serileştirme adını iki kez kullanmadığınızdan emin olun

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

sadece onlardan birini kaldır


Teşekkürler, günümü kurtardınız :)
Hemendra Gangwar

benim
sorunumdu

4

Benim durumumda, modal sınıfımda bir TextView nesnesi vardı ve GSON onu nasıl serileştireceğini bilmiyordu. Bunu 'geçici' olarak işaretlemek sorunu çözdü.


Bu onu görünür kılacak olsa da, kodu gizlerseniz (IE, proguard aracılığıyla) ve yayınlarsanız çalışmayacağını unutmayın; bunun yerine
SeriAdı

3

@ Silmarilos'un gönderisi bunu çözmeme yardımcı oldu. Benim durumumda, serileştirilmiş bir ad olarak "id" yi şu şekilde kullandım:

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

ve ben onu değiştirdim

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

Hepsi şimdi çalışıyor. "İd" nin varsayılan bir özellik olduğunu unuttum.


1

Bu birine yardımcı olabilir

Benim durumumda yanlışlıkla SerializedName yazdım böyle

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

Olmalı

@SerializedName("name")
String name;

@SerializedName("time")
String time;

0

Hey, bugün aynı sorunu yaşıyordum bir çözüm bulmam bütün günümü aldı ama sonunda bulduğum çözüm bu. Kodumda Dagger kullanıyorum ve retrofit örneğimde Gson dönüştürücüsünü uygulamaya ihtiyacım vardı.

yani bu benim önceki kodumdu

@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();
    }

bu benim son bulduğum şeydi

@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();
    }

İlk örnekte nasıl dönüştürücü olmadığına dikkat edin ve eklediğinizde Gson'u somutlaştırmadıysanız, bunu böyle eklersiniz

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

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

ve onu güçlendirme için yöntem çağrısına dahil ettiğinizden emin olun.

bir kez daha umarım bu benim gibi birine yardımcı olur.


0

Benim durumumda, hizmetim tarafından döndürülen bir Listeyi bir ArrayList'e almaya çalışmaktan kaynaklanıyordu. Öyleyse sahip olduğum şey:

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

ne zaman sahip olmalıydım

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

Umarım bu birine yardımcı olur!


0

Benim durumumda sorun, SUPERCLASS modelimde bu alanın tanımlanmış olmasıydı. Çok aptalca, biliyorum ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.