web-dev-qa-db-fra.com

Utilisation de la fonction En attente d’appel dans la modernisation

J'utilise Retrofit-2.0.0 pour mon application. Maintenant, chaque tutoriel sur Retrofit que j'ai trouvé sur le Web est basé sur Retrofit et il n'y avait pas d'interface Call<T> là-bas. C'est la première fois que j'utilise Retrofit et j'obtiens à plusieurs reprises null object reference. Voici l'interface de mon modèle de réseau 

public interface TMovieDBService {
    @GET("/movie")
    Call<MovieResponse> getMovieResponse(@Query("sort_by") String sortKey,
                             @Query("api_key") String apiKey);
}

Et c’est ma fonction updateMovies() qui met à jour la liste des films. 

void updateMovies() {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://api.themoviedb.org/3/discover")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    String sortKey = "popularity.desc";
    TMovieDBService service = retrofit.create(TMovieDBService.class);

    Call<MovieResponse> call = service.getMovieResponse(sortKey, ApiKey.API_KEY);

    call.enqueue(new Callback<MovieResponse>() {
        @Override
        public void onResponse(Response<MovieResponse> response) {
            Log.d(LOG_TAG, "Reached this place");
            if (!response.isSuccess()) {
                Log.d(LOG_TAG, "No Success");
            }
            mMovieList = response.body().getMovies();  // <- response is null here
            // Log.d(LOG_TAG, "Couldn't not reach this place");
            mMovieAdapter.notifyDataSetChanged();
            Log.d(LOG_TAG, "Response returned by website is : " + response.code());
        }

        @Override
        public void onFailure(Throwable t) {
            // Toast for the moment
            // Appropriate error handling code should be present here
            Toast.makeText(getActivity(), "Failed !", Toast.LENGTH_LONG).show();
        }
    });
}

Je ne sais pas quoi implémenter dans la fonction de mise en file d'attente. Le site Web de conversion ne donne que très peu d'informations sur l'utilisation du rappel. Supposons que tout le code fonctionne correctement. Ici, l'objet MovieResponse est renvoyé par l'API movieDB qui contient un tableau de Movies et des informations supplémentaires. Je l'implémente de telle sorte qu'une fois que j'ai la réponse dans MovieResponse à partir de là, je puisse l'extraire à l'aide de getMovies() qui renverra une liste de films. 

Quand je cours, je reçois simplement null object reference car response est null. J'ai essayé de rechercher des tutoriels sur l'utilisation du nouveau Retrofit-2.0.0, en particulier sur l'utilisation de la fonction de mise en file d'attente, mais je n'ai pas de chance. Plus une autre question pour savoir comment appeler updateMovies(). Puis-je l'appeler directement dans l'activité principale. Est-ce que la mise à niveau exécute automatiquement l'appel réseau sur le fil d'arrière-plan? 

16
AbKDs

Avec Retrofit 2, onResponse est appelé même en cas d’échec. Vous avez vérifié si la réponse n'aboutissait pas en utilisant !response.isSuccess(). Mais vous venez de vous connecter - si c’est vrai (c’est-à-dire sans succès). Au lieu de cela, vous pouvez vous connecter à response.errorBody().string() pour voir si le serveur api spécifie l'erreur et appeler quelque chose comme return pour quitter le rappel onResponse, car response.body() n'a pas pu être converti en MovieResponse, d'où l'exception null.

Soit dit en passant, votre code est correct, mais si vous commencez simplement par Retrofit, il serait plus simple d’utiliser la version 1.9, car la version 2.0 est toujours une version bêta (très stable, mais manque de tutoriels).

15
guillaume_fr

Utiliser un intercepteur de OkHttp Sur Retrofit 1.9, vous pouvez utiliser RequestInterceptor pour intercepter une demande, mais celle-ci est déjà supprimée sur Retrofit 2.0 car la couche de connexion HTTP a été déplacée vers OkHttp.

En conséquence, nous devons dorénavant passer à un intercepteur à partir de OkHttp. Vous devez d’abord l’ajouter à build.gradle

compile 'com.squareup.okhttp:okhttp:2.5.0'

puis créez un objet OkHttpClient avec un intercepteur comme celui-ci:

OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Response response = chain.proceed(chain.request());
            // Do anything with response here
            return response;
        }
    });

Ensuite, transmettez le client créé à la chaîne Builder de Retrofit.

  Retrofit retrofit = new Retrofit.Builder().baseUrl("http://api.themoviedb.org/3/discover/").addConverterFactory(GsonConverterFactory.create()).client(client).build();

Supprimez '/' de votre @GET ("/ abc") Parce que Retrofit 2.0 est livré avec un nouveau concept de résolution d'URL. L'URL de base et @Url n'ont pas simplement été combinés mais ont été résolus de la même manière que ce qui a été fait. S'il vous plaît jeter un oeil pour les exemples ci-dessous pour la clarification.

     

Pour en savoir plus sur Retrofit 2.0

5
Abdul Rizwan

@AbKDs, je ne sais pas si vous l'avez déjà résolu, mais j'ai découvert après quelques difficultés avec la mise à niveau 2 qu'il était nécessaire de placer " http://api.themoviedb.org " comme baseUrl et d'ajouter le chemin entier dans @GET. Comme suit: @GET ("/ 3/discover/movie") Et vous ajoutez ensuite vos requêtes en tant que paramètres de votre interface Call.

0
daxgirl