Reputation: 418
I'm creating an app that present the user a list of movies in a Gridview. I'm using API from themoviedb.org. When I run my app it doesn't start at all and I'm getting this error in LogCat. Could you please explain how to fix this issue:
07-13 21:50:56.954: E/AndroidRuntime(25898): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.projmobileapp.pmdbadd.pmdb/com.projmobileapp.pmdbadd.pmdb.MainActivity}: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2693)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.app.ActivityThread.access$900(ActivityThread.java:177)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.os.Handler.dispatchMessage(Handler.java:102)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.os.Looper.loop(Looper.java:145)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.app.ActivityThread.main(ActivityThread.java:5942)
07-13 21:50:56.954: E/AndroidRuntime(25898): at java.lang.reflect.Method.invoke(Native Method)
07-13 21:50:56.954: E/AndroidRuntime(25898): at java.lang.reflect.Method.invoke(Method.java:372)
07-13 21:50:56.954: E/AndroidRuntime(25898): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
07-13 21:50:56.954: E/AndroidRuntime(25898): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
07-13 21:50:56.954: E/AndroidRuntime(25898): Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:770)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.view.LayoutInflater.inflate(LayoutInflater.java:483)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:249)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:106)
07-13 21:50:56.954: E/AndroidRuntime(25898): at com.projmobileapp.pmdbadd.pmdb.MainActivity.onCreate(MainActivity.java:15)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.app.Activity.performCreate(Activity.java:6289)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
07-13 21:50:56.954: E/AndroidRuntime(25898): ... 10 more
07-13 21:50:56.954: E/AndroidRuntime(25898): Caused by: java.lang.NullPointerException: Attempt to get length of null array
07-13 21:50:56.954: E/AndroidRuntime(25898): at java.util.Collections.addAll(Collections.java:2582)
07-13 21:50:56.954: E/AndroidRuntime(25898): at com.projmobileapp.pmdbadd.pmdb.MainActivityFragment$MovieAdapter.<init>(MainActivityFragment.java:171)
07-13 21:50:56.954: E/AndroidRuntime(25898): at com.projmobileapp.pmdbadd.pmdb.MainActivityFragment.onCreateView(MainActivityFragment.java:48)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:924)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1116)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1218)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2170)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:300)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v7.app.AppCompatDelegateImplV7.callActivityOnCreateView(AppCompatDelegateImplV7.java:838)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v7.app.AppCompatDelegateImplV11.callActivityOnCreateView(AppCompatDelegateImplV11.java:34)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:826)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44)
07-13 21:50:56.954: E/AndroidRuntime(25898): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:732)
07-13 21:50:56.954: E/AndroidRuntime(25898): ... 19 more
07-13 21:50:56.954: V/ApplicationPolicy(864): isApplicationStateBlocked userId 0 pkgname com.projmobileapp.pmdbadd.pmdb
07-13 21:50:56.954: W/ActivityManager(864): Force finishing activity com.projmobileapp.pmdbadd.pmdb/.MainActivity
07-13 21:50:56.954: D/FocusedStackFrame(864): Set to : 0
07-13 21:50:56.964: I/Process(25898): Sending signal. PID: 25898 SIG: 9
Here's my code:
MainActivityFragment
package com.projmobileapp.pmdbadd.pmdb;
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 MainActivityFragment extends Fragment {
//ArrayAdapter<String> mMovieAdapter;
String[] movieId,movieTitle,movieOverview,movieReleaseDate,moviePosterPath,movieVoteAverage;
public MainActivityFragment() {
}
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_movie);
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.mainactivityfragment, 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=InsertAPIKeyHere");
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();
}
}
}
Upvotes: 0
Views: 394
Reputation: 1937
The problem is moviePosterPath. Maybe you can initialize this with empty array. Example: String[] movePosterPath = new String[0];
Upvotes: 1
Reputation: 7834
Pretty basic Android debugging stuff. Read down the chain of "Caused by:" exceptions in the log file.
The line of interest in the exception log is:
idRuntime(25898): Caused by: java.lang.NullPointerException: Attempt to get length of null array
If you scan down the callstack at the point this exception occured you will see:
E/AndroidRuntime(25898): at com.projmobileapp.pmdbadd.pmdb.MainActivityFragment$MovieAdapter.(MainActivityFragment.java:171)
For some reason, the FetchMovieTask AsyncTask has returned a null result from the background operation. You have then passed the null result as an argument to the call to mMovieAdapter.replace(strings); The strings argument is null; it should be an instance of ArrayList.
Set some breakpoints in FetchMovieTask.doInBackground and debug through that routine to see where things go wrong.
Upvotes: 1