Android Retrofit 라이브러리에서 수업 용 변환기를 만들 수 없습니다.


130

Volley를 Retrofit으로 마이그레이션하면서 이미 JSONObject 응답을 gson 주석을 구현하는 객체로 변환하기 위해 사용한 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

개조 사이트 의 가이드를 따르고 있으며 이러한 구현을 생각해 냈습니다.

이것은 레트로 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];
        }
    };
}

이 링크의 응답 문자열 추가하시기 바랍니다 mysample.com/development/cuteness
koutuk

@koutuk 그것은 단지 샘플입니다, btw 내가 이미 내 게시물을 변경했습니다
Earwin delos Santos

어떤 라인에서 오류가 발생 ....
koutuk

youtube.com/watch?v=gGuUBlzmtPQ 이 비디오를 통해 가야합니다
koutuk

아, 그게 오래된 것입니다. retrofit square.github.io/retrofit
Earwin delos Santos

답변:


217

이전 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();

또한 gradle 파일에 다음과 같은 종속성을 추가해야합니다.

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

개조 할 때와 동일한 버전의 변환기를 사용하십시오. 위는이 개조 의존성과 일치합니다.

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

또한이 문서를 작성할 때 개장 문서가 완전히 업데이트되지 않았 으므로이 예제로 인해 문제가 발생했습니다. 문서에서 :

참고 :이 사이트는 여전히 새 2.0 API로 확장 중입니다.


여전히 문제가 있습니다
user3475052

217

사용자 정의 변환기 팩토리를 정의하려고 시도하고이 오류가 발생하여 미래에 누군가이 문제가 발생하는 경우, 철자가 틀리거나 동일한 일련 화 된 이름을 가진 클래스에 여러 변수가있을 수 있습니다. IE :

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

직렬화 된 이름을 실수로 두 번 정의하면이 동일한 오류가 발생합니다.

업데이트 :이 논리는 상속을 통해서도 적용됩니다. 서브 클래스에서와 동일한 직렬화 된 이름을 가진 오브젝트를 가진 상위 클래스로 확장하면 동일한 문제가 발생합니다.


2
이것은 저에게 문제였습니다. 부모 클래스로 옮긴 자식 클래스 내부의 필드를 제거하는 것을 잊었습니다. 고마워요!
Vucko

1
고마워 2 일의 투쟁에서 나를 구해주었습니다. 직렬화 된 이름이 같은 두 개의 변수를 선언하여 같은 실수를 저질렀습니다.
Valynk

9

최고 의견을 바탕으로 수입품을 업데이트했습니다.

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

Spotify json 결과에서 pojo를 만들고 Gson 형식을 지정하기 위해 http://www.jsonschema2pojo.org/ 를 사용했습니다 .

요즈음에는 Pojo 또는 Kotlin 데이터 모델을 생성 할 수있는 Android Studio 플러그인이 있습니다. Mac의 훌륭한 옵션 중 하나는 Quicktype입니다. https://itunes.apple.com/us/app/paste-json-as-code-quicktype/id1330801220


6

동일한 직렬화 이름을 두 번 사용하지 않는지 확인하십시오.

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

그냥 그들 중 하나를 제거


감사합니다, 당신은 내 하루를 구했습니다 :)
Hemendra Gangwar

내 문제 였어 .. 감사합니다 ...
happy_Coding

4

필자의 경우 모달 클래스 내에 TextView 객체가 있었고 GSON이 직렬화 방법을 알지 못했습니다. '일시적'으로 표시하면 문제가 해결되었습니다.


이렇게하면 코드를 볼 수 있지만 코드를 난독 처리하고 (IE, proguard를 통해) 게시하면 작동하지 않습니다. 대신 SerializedName 또는 노출 된 주석을 사용하는 것이 좋습니다.
PGMacDesign 18

3

@ Silmarilos의 게시물 이이 문제를 해결하는 데 도움이되었습니다. 제 경우에는 다음과 같이 "id"를 일련 화 된 이름으로 사용했습니다.

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

그리고 나는 그것을 그것을 바꿨다.

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

모두 지금 일하고 있습니다. 'id'가 기본 속성이라는 것을 잊었습니다.


1

이것은 누군가를 도울 수 있습니다

내 경우에는 실수로 다음 과 같이 SerializedName을 작성 했습니다.

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

그것은해야한다

@SerializedName("name")
String name;

@SerializedName("time")
String time;

0

이봐, 나는 오늘 같은 문제를 겪고 있었는데 해결책을 찾기 위해 하루 종일 걸렸지 만 이것이 마침내 찾은 해결책이다. 내 코드에서 Dagger를 사용하고 있으며 개조 인스턴스에서 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();
    }

개조를위한 메소드 호출에 포함했는지 확인하십시오.

다시 한번 이것이 나 같은 사람에게 도움이되기를 바랍니다.


0

필자의 경우 서비스에서 List를 반환하여 ArrayList로 가져 오려고했기 때문입니다. 그래서 내가 가진 것은 :

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

내가 가졌어야 할 때

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

이것이 누군가를 돕기를 바랍니다!


0

제 경우에는 문제는 SUPERCLASS 모델에이 필드가 정의되어 있다는 것입니다. 매우 바보입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.