2 Вопрос: Android Kotlin Retrofit + вызов Rxjava не возвращает запрошенные данные

вопрос создан в Thu, May 2, 2019 12:00 AM

У меня есть приложение для Android, написанное на Kotlin, которое получает данные из API, на данный момент это просто локальный файл JSON. Когда я пытаюсь получить данные, я получаю сообщение об ошибке, что мой список, лица, не инициализирован, таким образом, люди == null и не получили данные. Я не уверен, что я сделал не так и как это исправить.

Модель

data class Person (
  @Json(name = "personId")
  val personId: Int,

  @Json(name = "personName")
  val name: String,

  @Json(name = "personAge")
  val age: Int,

  @Json(name = "isFemale")
  val isFemale: Boolean,
)

Ответ JSON

{
  "persons": [{
      "personId": 1,
      "personName": "Bert",
      "personAge": 19,
      "isFemale": "false",
    }
  ]
}

ApiClient

class ApiClient {
    companion object {

        private const val BASE_URL = "http://10.0.2.2:3000/"

        fun getClient(): Retrofit {
            val moshi = Moshi.Builder()
                .add(customDateAdapter)
                .build()

            return Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(MoshiConverterFactory.create(moshi))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
        }
    }
}

Модифицированные методы http

interface ApiInterface {

    @GET("persons")
    fun getPersons(): Observable<List<Person>>
}

и, наконец, звонок

class PersonActivity: AppCompatActivity(){
  private lateinit var jsonAPI: ApiInterface
  private lateinit var persons: List<Person>

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_person)

    val retrofit = ApiClient.getClient()
    jsonAPI = retrofit.create(ApiInterface::class.java)
    jsonAPI.getPersons()
            .subscribeOn(Schedulers.io())
            .unsubscribeOn(Schedulers.computation())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ persons = it })
  }
}

Ожидается: данные из файла JSON в список лиц вместо NULL.

    
0
  1. Ваш ответ - это не список людей, а объект "people", в котором указанный объект имеет объекты one..many person.
    2019-05-02 14: 49: 30Z
  2. @ GiorgosNeokleous как мне тогда получить список? Я пытался добавить данные PersonResponse {lateinit var: List < Person > } вместо этого, но это не сработало
    2019-05-02 15: 02: 54Z
  3. Я собираюсь опубликовать его в формате ответа ниже
    2019-05-02 15: 07: 12Z
2 ответа                              2                         

Адаптер moshi ожидает объекты person напрямую, но они вложены в массив Json "people".

Вы должны добавить другую модель следующим образом

data class Persons (
    @Json(name="persons")
    val persons : List<Person>
)

Также измените интерфейс для возврата нового объекта.

interface ApiInterface {
    @GET("persons")
    fun getPersons(): Observable<Persons>
}

Также необходимо изменить подписку на

.subscribe({ persons = it.persons })
    
0
2019-05-02 16: 19: 51Z
  1. Несмотря на то, что имеет смысл то, что вы говорите, оно все еще не работает. Но я также не вижу запроса на своем сервере Rest, я размещаюсь на localhost: 3000 , и мне сказали вместо этого использовать 10.0.2.2:3000 , чтобы эмулятор мог получить к нему доступ.
    2019-05-02 15: 45: 22Z
  2. Это еще одна проблема, правда? Если вы не можете получить доступ к своему API, проблема не в анализе. Проверьте stackoverflow.com/a/33256827/3330058 , чтобы включить ведение журнала Retrofit для проверки ошибок
    2019-05-02 15: 47: 39Z
  3. Я так думаю, я не уверен, но я не вижу никаких запросов, поэтому я думаю, что они никогда не будут выполнены? Я могу получить прекрасный доступ к API через мой веб-браузер.
    2019-05-02 15: 51: 07Z
  4. Убедитесь, что ваши журналы могут вас куда-то привести
    2019-05-02 15: 55: 31Z
  5. Хорошо, я вижу, что запросы поступают сейчас, я забыл добавить useCleartextTraffic в файл AndriodManifest. Но у меня все еще есть ошибка, человек не инициализирован
    2019-05-02 16: 10: 23Z

Я думаю, что может быть одна из двух проблем.

Если вы используете отражение moshi, у вас будет что-то вроде этих зависимостей в gradle:

//Moshi Core
implementation "com.squareup.moshi:moshi:1.8.0"

//Moshi Reflection
implementation "com.squareup.moshi:moshi-kotlin:1.8.0"

В этом случае вам нужно будет использовать KotlinJsonAdapterFactory:

  val moshi = Moshi.Builder()
        .add(customDateAdapter)
        .add(KotlinJsonAdapterFactory())
        .build()

Если вы используете codegen, вам понадобится это:

apply plugin: 'kotlin-kapt'
...
//Moshi Core Artifact
implementation "com.squareup.moshi:moshi:1.8.0"

//Moshi Codegen
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.8.0"

Кроме того, каждый классВы хотите, чтобы десериализовать должны быть помечены @JsonClass(generateAdapter = true) (поэтому класс Person и Persons)

    
0
2019-05-13 10: 59: 16Z
источник размещен Вот