我有片段的Activity,我想在GridView中显示图像。在onPostExecute方法中将适配器分配给gridview时出现NullPointerException。
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
MainActivityFragment.java
public class MainActivityFragment extends Fragment {
private final String API_KEY = BuildConfig.MOVIE_DB_API_KEY;
private final String POSTER_BASE_PATH ="https://image.tmdb.org/t/p/";
// posible poster sizes "w92", "w154", "w185", "w342", "w500", "w780", or "original"
private final String POSTER_SIZE = "w185";
private MoviesAdapter moviesAdapter;
public MainActivityFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
if (id == R.id.action_download){
DownloadMovies downloadTask = new DownloadMovies();
downloadTask.execute();
}
return super.onOptionsItemSelected(item);
}
public class DownloadMovies extends AsyncTask<Void, Void, Movie[]>{
private String LOG_TAG = this.getClass().getSimpleName();
private Movie[] getMoviesFromJson(String json) throws JSONException{
final String MOVIE_POSTER_PATH = "poster_path";
final String MOVIE_IS_FOR_ADULTS = "adult";
final String MOVIE_OVERVIEW = "overview";
final String MOVIE_RELASE_DATE = "release_date";
final String MOVIE_ID = "id";
final String MOVIE_ORIGINAL_TITLE = "original_title";
final String MOVIE_ORIGINAL_LANGUAGE = "original_language";
final String MOVIE_TITLE = "title";
final String MOVIE_BACKDROP_PATH = "backdrop_path";
final String MOVIE_POPULARITY = "popularity";
final String MOVIE_VOTE_COUNT = "vote_count";
final String MOVE_VOTE_AVERAGE = "vote_average";
JSONObject moviesJson = new JSONObject(json);
JSONArray moviesArray = moviesJson.getJSONArray("results");
Movie[] movies = new Movie[moviesArray.length()];
for (int i=0; i<moviesArray.length(); i++){
JSONObject movieJsonObject = moviesArray.getJSONObject(i);
movies[i] = new Movie(
POSTER_BASE_PATH + POSTER_SIZE + movieJsonObject.getString(MOVIE_POSTER_PATH),
movieJsonObject.getString(MOVIE_IS_FOR_ADULTS),
movieJsonObject.getString(MOVIE_OVERVIEW),
movieJsonObject.getString(MOVIE_RELASE_DATE),
movieJsonObject.getString(MOVIE_ID),
movieJsonObject.getString(MOVIE_ORIGINAL_TITLE),
movieJsonObject.getString(MOVIE_ORIGINAL_LANGUAGE),
movieJsonObject.getString(MOVIE_TITLE),
movieJsonObject.getString(MOVIE_BACKDROP_PATH),
movieJsonObject.getString(MOVIE_POPULARITY),
movieJsonObject.getString(MOVIE_VOTE_COUNT),
movieJsonObject.getString(MOVE_VOTE_AVERAGE)
);
Log.v(LOG_TAG, movies[i].toString());
}
return movies;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Movie[] doInBackground(Void... voids) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String movieJSONStr;
//final String MOVIE_DB_BASE_URL = "https://api.themoviedb.org/3/movie/now_playing?";
final String MOVIE_DB_BASE_URL = "http://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc";
final String API_PARAM= "api_key";
try{
Uri buildUri = Uri.parse(MOVIE_DB_BASE_URL).buildUpon().
appendQueryParameter(API_PARAM,API_KEY).build();
URL url = new URL(buildUri.toString());
Log.v(LOG_TAG, "Url: " + url);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) return null;
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null){
buffer.append(line + "\n");
}
if (buffer.length() == 0) return null;
movieJSONStr = buffer.toString();
Log.v(LOG_TAG, "Movies " + movieJSONStr);
} 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 getMoviesFromJson(movieJSONStr);
} catch (JSONException e){
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Movie[] result) {
if(result != null){
//super.onPostExecute(result);
GridView gridView = (GridView) getActivity().findViewById(R.id.posters_grid);
moviesAdapter = new MoviesAdapter(getActivity(), Arrays.asList(result));
gridView.setAdapter(moviesAdapter);
}
}
}
}
MoviesAdapter.java
public class MoviesAdapter extends ArrayAdapter<Movie> {
private static final String LOG_TAG = MoviesAdapter.class.getSimpleName();
public MoviesAdapter(Activity context, List<Movie> moviesList){
super(context, 0, moviesList);
}
public View getView(int position, View convertView, ViewGroup parent){
Movie movie = getItem(position);
if (convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.movie_item, parent, false);
}
ImageView imageView = (ImageView) convertView.findViewById(R.id.poster_imageview);
Picasso.with(getContext()).load(movie.getPosterPath()).into(imageView);
TextView textView = (TextView) convertView.findViewById(R.id.movie_title_textview);
textView.setText(movie.getTitle());
return convertView;
}
}
fragment_main.xml
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="150dp"
android:numColumns="auto_fit"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:stretchMode="columnWidth"
tools:context=".MainActivityFragment"
android:id="@+id/posters_grid">
</GridView>
activity_main.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment"
android:name="pl.example.movies.MainActivityFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="@layout/fragment_main" />
栈跟踪
03-03 12:20:29.947 32590-32590/pl.example.movies E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: pl.example.movies, PID: 32590
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.GridView.setAdapter(android.widget.ListAdapter)' on a null object reference
at pl.example.movies.MainActivityFragment$DownloadMovies.onPostExecute(MainActivityFragment.java:189)
at pl.example.movies.MainActivityFragment$DownloadMovies.onPostExecute(MainActivityFragment.java:72)
at android.os.AsyncTask.finish(AsyncTask.java:636)
at android.os.AsyncTask.access$500(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5389)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
此行(189)出错:
gridView.setAdapter(moviesAdapter);
就在这条线后面(187):
GridView gridView = (GridView) getActivity().findViewById(R.id.posters_grid);
所以我很难理解我在这里犯的错误。