制作一个从tmdb.org

时间:2016-07-07 11:01:24

标签: android json

我正在尝试创建一个应用程序,我想要我的应用程序,在发布时,显示一个流行的电影海报网格。电影海报是从TheMovieDataBase API下载的。然后我使用Picasso加载图像。对于GridView,我也使用自定义适配器。我无法理解如何做到这一点。这是我到目前为止所做的事情

     MovieFragment.java

     import android.content.Context;
     import android.os.AsyncTask;
     import android.os.Bundle;
      import android.support.v4.app.Fragment;
      import android.util.Log;
      import android.view.LayoutInflater;
      import android.view.Menu;
      import android.view.MenuInflater;
      import android.view.MenuItem;
      import android.view.View;
      import android.view.ViewGroup;
      import android.widget.BaseAdapter;
      import android.widget.GridView;
      import android.widget.ImageView;

       import com.squareup.picasso.Picasso;

       import org.json.JSONArray;
       import org.json.JSONException;
       import org.json.JSONObject;

       import java.io.BufferedReader;
        import java.io.IOException;
        import java.io.InputStream;
        import java.io.InputStreamReader;
         import java.net.HttpURLConnection;
          import java.net.URL;
         import java.util.ArrayList;
         import java.util.Collections;
         import java.util.List;


         public class MovieFragment extends Fragment {
         //ArrayAdapter<String> mMovieAdapter;
        String[]movieId,movieTitle,movieOverview,
        movieReleaseDate,
        moviePosterPath,movieVoteAverage;
        public MovieFragment() {
        }

        MovieAdapter mMovieAdapter;

          @Override
       public View onCreateView(LayoutInflater inflater, ViewGroup     container,
                         Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_main, container, false);

    mMovieAdapter = new MovieAdapter(getActivity());
    GridView listView = (GridView) rootView.findViewById(R.id.gridView);
    listView.setAdapter(mMovieAdapter);
    updateMovie();
    return rootView;
}


public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // Inflate the menu; this adds items to the action bar if it is present.
    inflater.inflate(R.menu.menu_fragment, menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_refresh) {
        updateMovie();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

private void updateMovie() {
    FetchMovieTask movieTask = new FetchMovieTask();
    movieTask.execute();
}

class FetchMovieTask extends AsyncTask<Void, Void, List<String>> {
    private final String LOG_TAG = FetchMovieTask.class.getSimpleName();

    @Override
    protected List<String> doInBackground(Void... params) {
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;

        // Will contain the raw JSON response as a string.
        String movieJsonStr = null;

        try {
            URL url = new URL("http://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=c20129fdf73b5df3ab44548ad7f73586");

            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            // Read the input stream into a String
            InputStream inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();
            if (inputStream == null) {
                // Nothing to do.
                return null;
            }
            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null) {

                buffer.append(line + "\n");
            }

            if (buffer.length() == 0) {
                // Stream was empty.  No point in parsing.
                return null;
            }
            movieJsonStr = buffer.toString();

        } catch (IOException e) {
            Log.e(LOG_TAG, "Error ", e);
            return null;
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException e) {
                    Log.e(LOG_TAG, "Error closing stream", e);
                }
            }
        }
        try {
            return getMovieDataFromJson(movieJsonStr);
        } catch (JSONException j) {
            Log.e(LOG_TAG, "JSON Error", j);
        }
        return null;
    }

    private List<String> getMovieDataFromJson(String forecastJsonStr)
            throws JSONException {
        JSONObject movieJson = new JSONObject(forecastJsonStr);
        JSONArray movieArray = movieJson.getJSONArray("results");
        List<String> urls = new ArrayList<>();
        for (int i = 0; i < movieArray.length(); i++) {
            JSONObject movie = movieArray.getJSONObject(i);
            urls.add("http://image.tmdb.org/t/p/w185" + movie.getString("poster_path"));
        }
        return urls;
    }

    @Override
    protected void onPostExecute(List<String> strings) {
        mMovieAdapter.replace(strings);
    }
}

class MovieAdapter extends BaseAdapter {
    private final String LOG_TAG = MovieAdapter.class.getSimpleName();
    private final Context context;
    private final List<String> urls = new ArrayList<String>();

    public MovieAdapter(Context context) {
        this.context = context;
        Collections.addAll(urls, moviePosterPath);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = new ImageView(context);
        }
        ImageView imageView = (ImageView) convertView;


        String url = getItem(position);

        Log.e(LOG_TAG," URL "+url);

        Picasso.with(context).load(url).into(imageView);

        return convertView;
    }

    @Override
    public int getCount() {
        return urls.size();
    }

    @Override
    public String getItem(int position) {
        return urls.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
    public void replace(List<String> urls) {
        this.urls.clear();
        this.urls.addAll(urls);
        notifyDataSetChanged();
    }
}

}

当我运行此代码时,它显示NullPointerException和RuntimeException

        java.lang.RuntimeException: Unable to start activity ComponentInfo
         {com.codesetters.verader/com.codesetters.verader.MainActivity}:          java.lang.NullPointerException                                                                          atandroid.app.ActivityThreadperformLaunchActivity(ActivityThread.java:2404)




        Caused by: java.lang.NullPointerException                                                                               atjava.util.Collections.addAll(Collections.java:2582)

我该如何解决? 请帮忙

2 个答案:

答案 0 :(得分:1)

您收到此错误是因为您在此处使用了moviePosterPath

Collections.addAll(urls, moviePosterPath);

但是你没有在任何地方初始化它。用一些值初始化它,它应该解决错误。

答案 1 :(得分:0)

空指针可能是因为未初始化 String数组moviePosterPath 。你正在 Collections.addAll

中使用它

这是初始化数组的方法。无论如何,我建议你使用ArrayList

String[] moviePosterPath = new String[N];