使用API​​将电影DB改造库

时间:2016-10-18 21:20:27

标签: android api retrofit picasso

我想构建一个使用改造消耗REST api的电影应用程序,并使用Picasso显示图像并引入Retrofit并显示真实的电影海报以及每部电影的详细信息。

我正在使用The Movie Database Api将一些真实数据输入我们的应用程序。查看他们的文档并熟悉他们的API,特别是电影/热门端点

但是当运行应用程序白屏时,显示图片并不显示电影,我不知道问题出在哪里

此MainActivity:

package com.walkatheri.movies;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.List;

import retrofit.Callback;
import retrofit.RequestInterceptor;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.Response;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        RecyclerView mRecyclerView;
        final MoviesAdapter mAdapter;


        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
        mAdapter = new MoviesAdapter(this);
        mRecyclerView.setAdapter(mAdapter);


        RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint("http://api.themoviedb.org/3")
                .setRequestInterceptor(new RequestInterceptor() {
                    @Override
                    public void intercept(RequestFacade request) {
                        request.addEncodedQueryParam("api_key", "MY _KEY");
                    }
                })
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .build();
        MoviesApiService service = restAdapter.create(MoviesApiService.class);

        service.getPopularMovies(new Callback<Movies.MovieResult>() {
            @Override
            public void success(Movies.MovieResult movieResult, Response response) {
                mAdapter.setMovieList(movieResult.getResults());
            }

            @Override
            public void failure(RetrofitError error) {
                error.printStackTrace();
            }
        });

    }
    public static class MovieViewHolder extends RecyclerView.ViewHolder {

        public ImageView imageView;
        public MovieViewHolder(View itemView) {
            super(itemView);
            imageView = (ImageView) itemView.findViewById(R.id.imageView);

        }
    }

    public static class MoviesAdapter extends RecyclerView.Adapter<MovieViewHolder> {

        List<Movies>MovieList ;
        private LayoutInflater mInflater;
        private Context mContext;
        public MoviesAdapter(Context context)
        {
            this.mContext = context;
            this.mInflater = LayoutInflater.from(context);
            this.MovieList = new ArrayList<>();
        }
        public void setMovieList(List<Movies> movieList)
        {
            this.MovieList=movieList ;
            // The adapter needs to know that the data has changed. If we don't call this, app will crash.
            notifyDataSetChanged();
        }
        @Override
        public MovieViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = mInflater.inflate(R.layout.row_movie, parent, false);
            MovieViewHolder viewHolder = new MovieViewHolder(view);
            return viewHolder;

        }

        @Override
        public void onBindViewHolder(MovieViewHolder holder, int position) {
            Movies movies = MovieList.get(position);
            Picasso.with(mContext)
                    .load(movies.getPoster()).placeholder(R.color.colorAccent)
                    .into(holder.imageView);

        }

        @Override
        public int getItemCount() {

            return (MovieList == null) ? 0 : MovieList.size();
        }
    }
}

Movies上课:

package com.walkatheri.movies;

import android.graphics.Movie;

import com.google.gson.annotations.SerializedName;

import java.util.List;

/**
 * Created by waad on 08/10/2016.
 */

public class Movies {
    private String title;




    @SerializedName("poster_path")
    private String poster;

    @SerializedName("overview")
    private String description;

    @SerializedName("backdrop_path")
    private String backdrop;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {

        this.title = title;
    }
    public String getPoster() {
        return "http://image.tmdb.org/t/p/w500" + poster;
    }
  //  public String getPoster() {
       // return "http://t2.gstatic.com/images?q=tbn:ANd9GcQW3LbpT94mtUG1PZIIzJNxmFX399wr_NcvoppJ82k7z99Hx6in";
   // }
    public void setPoster(String poster) {

        this.poster = poster;
    }

    public String getDescription() {

        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getBackdrop() {

        return backdrop;
    }

    public void setBackdrop(String backdrop) {

        this.backdrop = backdrop;
    }

    public static class MovieResult {

        private List<Movies> resulte;

        public List<Movies> getResults() {
            return resulte;

        }
    }}

MoviesApiService上课:

package com.walkatheri.movies;

import retrofit.Callback;
import retrofit.http.GET;


/**
 * Created by waad on 18/10/2016.
 */

public interface MoviesApiService {
    @GET("/movie/popular")
    void getPopularMovies(Callback<Movies.MovieResult>cb);

}

2 个答案:

答案 0 :(得分:2)

很难指出错误,没有像stacktraces那样的暗示。

一些指针

  1. 使用改造异步调用。

  2. 您需要.addConverterFactory(GsonConverterFactory.create())将json转换为pojos。

  3. 只有当您使用网址http://image.tmdb.org/t/p/w185“+”yourposterpath“时才会加载图片。请检查moviedb链接

  4. 更新您的图书馆并相应更改您的api(推荐)

  5. 最后一个干净的架构将帮助您正确编写测试。您的代码是非结构化的,您需要正确分离组件。建议您阅读有关MVP或MVVM模式的内容。匕首也可以提供帮助。

  6. 关于改造https://inthecheesefactory.com/blog/retrofit-2.0/en

    的好读物

    所以改变

    public class TestActivity extends AppCompatActivity {
    
        private RecyclerView mRecyclerView;
        private MoviesAdapter mAdapter;
    
        public static final String MOVIE_DB_API_URL = "http://api.themoviedb.org/3/";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
            mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
            mAdapter = new MoviesAdapter(this);
            mRecyclerView.setAdapter(mAdapter);
    
    
            final OkHttpClient client = new OkHttpClient.Builder()
                    .addInterceptor(new LoggingInterceptor())
                    .connectTimeout(15, TimeUnit.SECONDS)
                    .readTimeout(15,TimeUnit.SECONDS)
                    .build();
            Retrofit restAdapter = new Retrofit.Builder()
                    .baseUrl(MOVIE_DB_API_URL)
                     .client(client)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
            MoviesApiService service = restAdapter.create(MoviesApiService.class);
    
    
            Call<MoviesList> movieResultCallback = service.getPopularMovies();
            // asynchronous call
            movieResultCallback.enqueue(new Callback<MoviesList>() {
                @Override
                public void onResponse(Call<MoviesList> call, Response<MoviesList> response) {
    
                    //int code = response.code();
                    // can check the status code 
                    mAdapter.setMovieList(response.body().getResults());
                }
    
                @Override
                public void onFailure(Call<MoviesList> call, Throwable t) {
    
                }
            });
    
        }
        public static class MovieViewHolder extends RecyclerView.ViewHolder {
    
            public ImageView imageView;
            public MovieViewHolder(View itemView) {
                super(itemView);
                imageView = (ImageView) itemView.findViewById(R.id.image);
    
            }
        }
    
        public static class MoviesAdapter extends RecyclerView.Adapter<MovieViewHolder> {
    
            List<Movies>MovieList ;
            private LayoutInflater mInflater;
            private Context mContext;
            public MoviesAdapter(Context context)
            {
                this.mContext = context;
                this.mInflater = LayoutInflater.from(context);
                this.MovieList = new ArrayList<>();
            }
            public void setMovieList(List<Movies> movieList)
            {
                this.MovieList=movieList ;
                // The adapter needs to know that the data has changed. If we don't call this, app will crash.
                notifyDataSetChanged();
            }
            @Override
            public MovieViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                View view = mInflater.inflate(R.layout.row, parent, false);
                MovieViewHolder viewHolder = new MovieViewHolder(view);
                return viewHolder;
    
            }
    
            @Override
            public void onBindViewHolder(MovieViewHolder holder, int position) {
                Movies movies = MovieList.get(position);
                Picasso.with(mContext)
                        .load("http://image.tmdb.org/t/p/w185"+movies.getPoster_path()).placeholder(R.color.colorAccent)
                        .into(holder.imageView);
    
            }
    
            @Override
            public int getItemCount() {
    
                return (MovieList == null) ? 0 : MovieList.size();
            }
        }
    
        public static class LoggingInterceptor implements Interceptor {
            @Override public okhttp3.Response intercept(Chain chain) throws IOException {
    
                HttpUrl url = chain.request().url()
                        .newBuilder()
                        .addQueryParameter("api_key", "4848b32592990671646565fa3240a7bc")
                        .build();
    
                Request request = chain.request().newBuilder().url(url).build();;
    
                long t1 = System.nanoTime();
                String requestLog = String.format("Sending request %s on %s%n%s",
                        request.url(), chain.connection(), request.headers());
                //YLog.d(String.format("Sending request %s on %s%n%s",
                //        request.url(), chain.connection(), request.headers()));
                if(request.method().compareToIgnoreCase("post")==0){
                    requestLog ="\n"+requestLog+"\n"+bodyToString(request);
                }
                Log.d("TAG","request"+"\n"+requestLog);
    
                okhttp3.Response response = chain.proceed(request);
                long t2 = System.nanoTime();
    
                String responseLog = String.format("Received response for %s in %.1fms%n%s",
                        response.request().url(), (t2 - t1) / 1e6d, response.headers());
    
                String bodyString = response.body().string();
    
                Log.d("TAG","response"+"\n"+responseLog+"\n"+bodyString);
    
                return response.newBuilder()
                        .body(ResponseBody.create(response.body().contentType(), bodyString))
                        .build();
                //return response;
            }
        }
    
        private static String bodyToString(final Request request) {
    
            try {
                final Request copy = request.newBuilder().build();
                final Buffer buffer = new Buffer();
                if (copy != null && copy.body() != null) // make sure its not null to avoif NPE
                    copy.body().writeTo(buffer);
                return buffer.readUtf8();
            } catch (final IOException e) {
                return "did not work";
            }
        }
    }
    

    然后

    public interface MoviesApiService {
        @GET("movie/popular")
        Call<MoviesList> getPopularMovies();
    
    }
    

    我的模型类

    使用http://www.jsonschema2pojo.org/将json转换为pojo

    我在github上复制了下面的一个存储库。

    github上有很多类似的存储库。 https://github.com/ewintory/udacity-popular-movies等等......     公共类电影实现了Parcelable {

        private int id,vote_count,favourite,reviewsaved,trailersaved;
        private float vote_average,popularity;
    
        private String original_language,original_title,overview,release_date,poster_path,title,generids,backdrop_path;
        private boolean video,favored;
    
        public Movies()
        {
    
        }
    
        public void setReviewsaved(int reviewsaved) {
            this.reviewsaved = reviewsaved;
        }
    
        public void setTrailersaved(int trailersaved) {
            this.trailersaved = trailersaved;
        }
    
        public int getTrailersaved() {
            return trailersaved;
        }
    
        public int getReviewsaved() {
            return reviewsaved;
        }
    
        public void setFavored(boolean favored) {
            this.favored = favored;
        }
    
    
    
        public void setId(int id) {
            this.id = id;
        }
    
        public void setVote_count(int vote_count) {
            this.vote_count = vote_count;
        }
    
        public void setFavourite(int favourite) {
            this.favourite = favourite;
        }
    
        public void setVote_average(float vote_average) {
            this.vote_average = vote_average;
        }
    
        public void setOriginal_language(String original_language) {
            this.original_language = original_language;
        }
    
    
        public void setOriginal_title(String original_title) {
            this.original_title = original_title;
        }
    
        public void setOverview(String overview) {
            this.overview = overview;
        }
    
        public void setRelease_date(String release_date) {
            this.release_date = release_date;
        }
    
        public void setPoster_path(String poster_path) {
            this.poster_path = poster_path;
        }
    
        public void setPopularity(float popularity) {
            this.popularity = popularity;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public void setGenerids(String generids) {
            this.generids = generids;
        }
    
        public void setbackdrop_path(String backdrop_path) {
            this.backdrop_path = backdrop_path;
        }
    
        public void setVideo(boolean video) {
            this.video = video;
        }
    
        public String getGenerids() {
            return generids;
        }
    
        public int getId() {
            return id;
        }
    
        public int getVote_count() {
            return vote_count;
        }
    
        public float getVote_avarage() {
            return vote_average;
        }
    
        public String getOriginal_language() {
            return original_language;
        }
    
        public String getOriginal_title() {
            return original_title;
        }
    
        public String getOverview() {
            return overview;
        }
    
        public String getRelease_date() {
            return release_date;
        }
    
        public String getBackdrop_path() {
            return backdrop_path;
        }
    
        public int getFavourtite() {
            return favourite;
        }
    
        public String getPoster_path() {
            return poster_path;
        }
    
        public float getPopularity() {
            return popularity;
        }
    
        public String getTitle() {
            return title;
        }
    
        public boolean isVideo() {
            return video;
        }
    
        // Parcelling part
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(this.original_language);
            dest.writeString(this.original_title);
            dest.writeString(this.overview);
            dest.writeString(this.poster_path);
    
            dest.writeString(this.generids);
            dest.writeString(this.title);
            dest.writeString(this.release_date);
    
            dest.writeString(this.backdrop_path);
    
            dest.writeInt(this.favourite);
            dest.writeInt(this.id);
            dest.writeInt(this.vote_count);
            dest.writeFloat(this.vote_average);
            dest.writeFloat(this.popularity);
    
    
        }
    
        protected Movies(Parcel in) {
            this.original_language = in.readString();
            this.original_title = in.readString();
            this.overview = in.readString();
            this.poster_path = in.readString();
            this.generids = in.readString();
            this.title = in.readString();
            this.release_date = in.readString();
            this.backdrop_path = in.readString();
    
            this.favourite = in.readInt();
            this.id = in.readInt();
            this.vote_count = in.readInt();
            this.vote_average =in.readFloat();
            this.popularity = in.readFloat();
    
        }
    
        public static final Creator<Movies> CREATOR = new Creator<Movies>() {
            public Movies createFromParcel(Parcel source) {
                return new Movies(source);
            }
    
            public Movies[] newArray(int size) {
                return new Movies[size];
            }
        };
    
        @Override
        public int describeContents() {
            return 0;
        }
    }
    

    MoviesList

    public class MoviesList {
    
        private int total_pages;
    
        public int getTotal_pages() {
            return total_pages;
        }
    
        private ArrayList<Movies> results;
    
        public ArrayList<Movies> getResults() {
            return results;
        }
    }
    

    最后更新的库

    // Okhttp
    compile 'com.squareup.okhttp3:okhttp:3.4.1'
    
    //Retrofit and adapters
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.picasso:picasso:2.5.2'
    

    您可以查看日志

答案 1 :(得分:0)

根据你的模糊输入几乎不可能确切地知道发生了什么,但我的赌注是你没有在应用程序的清单中指定互联网许可:

<uses-permission android:name="android.permission.INTERNET"/>

(在src / main / AndroidManifest.xml中,在manifest标签下)