Как и где позвонить в Retrofit? - PullRequest
0 голосов
/ 01 июля 2018

Я начинающий разработчик Android, пытающийся освоить мобильную разработку, создав приложение для создания базы данных фильмов. Я пишу свое приложение на Kotlin и использую Retrofit для сетевого вызова. Я застрял на том, как и где позвонить, чтобы заполнить Recyclerview плакатами фильмов из API tmdb.

Это мой интерфейс:

interface APImovies {
    fun getMovies()
}

Это моя основная деятельность с моим объектом сервера Retrofit:

class MainActivity() : AppCompatActivity() {

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

        val recyclerView = findViewById<RecyclerView>(R.id.recycler_view);
        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerView.layoutManager = GridLayoutManager(this, 3);
        recyclerView.adapter = PosterAdapter()
    }

    object RetrofitServer{
        val client: APImovies by lazy{
            val client = OkHttpClient.Builder().build()
            val retrofit = Retrofit
                    .Builder()
                    .baseUrl("https://api.themoviedb.org/3/movie/550?api_key=")
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(client)
                    .build()
            retrofit.create(APImovies::class.java)
        }
    }
}

И это мой адаптер, который в настоящее время заполняет Recyclerview изображением-заполнителем:

class PosterAdapter() : RecyclerView.Adapter<PosterHolder>(){

    override fun getItemCount(): Int { return 300}

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PosterHolder{
        val layoutInflater = LayoutInflater.from(parent.context)
        val listItem = layoutInflater.inflate(R.layout.list_item, parent, false)
        return PosterHolder(listItem)
    }

    override fun onBindViewHolder(holder: PosterHolder, position: Int) {
        holder.view.movie_poster?.setImageResource(R.mipmap.beauty_and_the_beast_ver3)
        holder.view.movie_poster?.scaleType = ImageView.ScaleType.FIT_XY
    }
}

class PosterHolder(val view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
    var imageView: ImageView? = null

    fun PosterHolder(view: View){ this.imageView = view.findViewById<View>(R.id.movie_poster) as ImageView }

    override fun onClick(p0: View?) {}
}

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Я использую следующую настройку. Посмотри, может ли это тебе помочь.

interface WebService {

    @GET
    fun getMovies(): Call<List<MyResponseObject>>

    companion object {
        fun create(): WebService {
            val client = OkHttpClient.Builder().build()
            val retrofit = Retrofit.Builder()
                    .baseUrl("YOUR_BASE_URL")
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(client)
                    .build()

            return retrofit.create(WebService::class.java)
        }
    }
}

В MainActivity выполните следующие действия, чтобы выполнить сетевой вызов

class MainActivity : AppCompatActivity() {
    private val webService = WebService.create()
    override fun onCreate(savedInstanceState: Bundle?, persistentState: 
    PersistableBundle?) {
        /*...*/
        fetchMovies()
    }

    private fun fetchMovies() {
        var call = webService.getMovies()
        call.enqueue(object : Callback<MyResponseObject> {
            override fun onFailure(call: Call<MyResponseObject>?, t: Throwable?) { }

            override fun onResponse(call: Call<MyResponseObject>?, response: Response<List<Class>>?) {
                if (response != null && response.isSuccessful) {
                    val myListData: MyResponseObject = response.body()
                    setUpRecyclerView(myListData) // The usual way of setting up a RecyclerView
                }
            }
        })
    }
}

Это только для начинающих. Я бы порекомендовал вам изучить архитектуру MVVM, используя компоненты архитектуры Android и Dagger 2 (для внедрения зависимостей). Поскольку вы используете Kotlin, вы можете воспользоваться Kotlin Coroutines , AndroidKTX и Kodein для DI, как сказал Наиль Шайхразиев

0 голосов
/ 01 июля 2018

Я использую что-то вроде этого:

public final class ApiClient {

private static OkHttpClient sClient;
private static volatile MovieService movieService;

private ApiClient() {
}

public static MovieService getMovieService() {
    MovieService service = movieService;
    if (service == null) {
        synchronized (ApiClient.class) {
            service = movieService;
            if (service == null) {
                service = movieService = buildRetrofit().create(MovieService.class);
            }
        }
    }
    return service; // this is one of the implementation options singlton pattern. You can use some di tools(Kodein, Dagger)
}

private static Retrofit buildRetrofit() {

    return new Retrofit.Builder()
            .baseUrl(BuildConfig.BASE_URL)
            .client(getClient())
            .addConverterFactory(GsonConverterFactory.create(getGson()))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();
}

private static Gson getGson() {
    return new GsonBuilder()
            .setLenient()
            .create();
}

private static OkHttpClient getClient() {
    OkHttpClient client = sClient;
    if (client == null) {
        synchronized (ApiClient.class) {
            client = sClient;
            if (client == null) {
                client = sClient = buildClient();
            }
        }
    }
    return client;
}

private static OkHttpClient buildClient() {
    return new OkHttpClient.Builder()
            .addInterceptor(TokenInterceptor.create())
            .build();
}}

После в вашем методе модификации вызовов Presenter / Interactor / ViewModel:

ApiClient.movieService.popularMovies()
                .map { it.movies }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe { view.showProgress }
                .doAfterTerminate { view.hideProgress }
                .subscribeBy(onSuccess = {
                   view.showMovies(it)
                }, onError = {
                   view.showErrors()
                })

В операции / Фрагмент / Просмотр:

class Activity : AppCompatActivity(), MovieView {

  override fun onCreate(savedInstanceState: Bundle?) {
      // your code
   }

  override fun showMovies(list: List<Movie>) {
     adapter.update(list)
   }
}
...