Доступ к Twitter REST API работает только в mainActivity, но почему? - PullRequest
0 голосов
/ 09 мая 2019

Я очень запутался и мне нужна ваша помощь! Это только мое второе приложение, и я впервые работаю с REST API. Я просто пытаюсь отобразить некоторую информацию о пользователе, такую ​​как имя и изображение профиля. Он отлично работает, когда я использую код в основном Activity, но как только я использую другой класс для него, вызов API завершается неудачно, и код довольно похож, поэтому я не знаю больше. Так как Twitter использует Retrofit в своем собственном учебном пособии, я использую и его.

My Class, расширяющий TwitterApiClient, файл также включает интерфейс для пользовательской службы:

import android.util.Log
import com.twitter.sdk.android.core.*
import com.twitter.sdk.android.core.models.User
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query

class MyTwitterApiClient(session: TwitterSession) : TwitterApiClient(session) {

    fun getCustomService() : GetUsersShowAPICustomService {
        return getService(GetUsersShowAPICustomService::class.java)
    }

}

interface GetUsersShowAPICustomService {
    @GET("/1.1/users/show.json")
    fun show(@Query("user_id") userId: Long) : Call<User>
}

Мой метод в MainActivity выглядит следующим образом:

private fun loadTwitterAPI(userID: Long) {
        MyTwitterApiClient(session).getCustomService().show(userID).enqueue(object : Callback<User>() {
            override fun success(result: Result<User>?) {
                text.text = (
                        "Name: "+result!!.data.name
                                +"\nLocation: "+result!!.data.location
                                +"\nFriends: "+result!!.data.friendsCount
                        )

                Picasso.with(baseContext).load(result!!.data.profileImageUrl).resize(250, 250).into(imageView)
            }

            override fun failure(exception: TwitterException?)  {

            }
        })

    }

Это прекрасно работает, но я не хочу, чтобы сам вызов вызывался в моей основной деятельности, и я создал в своем классе сопутствующий объект, расширяющий TwitterApi, который должен просто вызываться с параметром TwitterSession в качестве параметра и возвращать объект класса User, который содержит все важные данные.

Сопутствующий объект внутри класса MyTwitterApiClient выглядит следующим образом:

companion object {
        fun start(session: TwitterSession): User {
            val userID = session.userId
            var data: User? = null

            MyTwitterApiClient(session).getCustomService().show(userID).enqueue(object : Callback<User>() {
                override fun success(result: Result<User>?) {
                    data = result!!.data
                }

                override fun failure(exception: TwitterException?) {
                    throw exception!!
                }
            })

            return data!!
        }
    }

Новый метод в MainActivity выглядит следующим образом:

private fun loadTwitterAPI(userID: Long) {
val t = MyTwitterApiClient.start(session)
        text.text = (
                "Name: "+t.name
                        +"\nLocation: "+t.location
                        +"\nFriends: "+t.friendsCount
                )

        Picasso.with(baseContext).load(t.profileImageUrl).resize(250, 250).into(imageView)
}

В ходе тестирования я обнаружил, что ни метод успеха, ни метод отказа не вызывается. И я совсем не понимаю, почему он не вызывает никакого метода и просто терпит неудачу.

Если бы кто-нибудь здесь уже работал с чем-то подобным или у меня был Совет, это было бы очень полезно!

Привет

Кстати: ошибка, которая приводит к сбою моего приложения, в конце концов, представляет собой исключение NullPointerException, так как метод успеха не вызывается, и в конце возвращается null.

Вставьте мои файлы:

1 Ответ

1 голос
/ 09 мая 2019

Хорошо, начиная с вашего кода:

fun start(session: TwitterSession): User {
        val userID = session.userId
        var data: User? = null

        MyTwitterApiClient(session).getCustomService().show(userID).enqueue(object : Callback<User>() {
            override fun success(result: Result<User>?) {
                data = result!!.data
            }

            override fun failure(exception: TwitterException?) {
                throw exception!!
            }
        })

        return data!!
    }

Здесь вы возвращаете data, как если бы он был назначен. Ваш TwitterApiClient выполняет асинхронную задачу, поэтому данные из data = result!!.data не будут правильно считываться из

text.text = (
            "Name: "+t.name
                    +"\nLocation: "+t.location
                    +"\nFriends: "+t.friendsCount
            )

Потому что t равно null тогда. Его данные еще не установлены. Это будет когда-то в будущем, в асинхронном обратном вызове success().

Похоже, ваша главная проблема в том, как работать с асинхронными задачами и как уведомлять результаты. Об этом много источников. LiveData, RxJava, EventBus могут быть ведущими.

Кстати, причина, по которой ваш код работал в MainActivity, заключалась в том, что вы устанавливали текст после получения результата (в success()), поэтому t было хорошо читать.

Удачи и счастливого обучения!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...