Android app - Attempt to invoke interface method &

2019-02-19 22:20发布

I'm creating an app that display movie poster in a gridview. I'm using an API from themoviedb.org. The problem is I'm getting the follow error when I run my app and I'm struggling to fix it:

07-18 20:27:39.244    2751-2751/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.projmobileapp.pmdbadd.pmdb, PID: 2751
    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
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2693)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
            at android.app.ActivityThread.access$900(ActivityThread.java:177)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:145)
            at android.app.ActivityThread.main(ActivityThread.java:5942)
            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:1400)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
     Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:770)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:483)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
            at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:249)
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:106)
            at com.projmobileapp.pmdbadd.pmdb.MainActivity.onCreate(MainActivity.java:15)
            at android.app.Activity.performCreate(Activity.java:6289)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
            at android.app.ActivityThread.access$900(ActivityThread.java:177)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:145)
            at android.app.ActivityThread.main(ActivityThread.java:5942)
            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:1400)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
     Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
            at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
            at android.widget.GridView.setAdapter(GridView.java:201)
            at com.projmobileapp.pmdbadd.pmdb.MainActivityFragment.onCreateView(MainActivityFragment.java:53)
            at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:924)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1116)
            at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1218)
            at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2170)
            at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:300)
            at android.support.v7.app.AppCompatDelegateImplV7.callActivityOnCreateView(AppCompatDelegateImplV7.java:838)
            at android.support.v7.app.AppCompatDelegateImplV11.callActivityOnCreateView(AppCompatDelegateImplV11.java:34)
            at android.support.v7.app.AppCompatDelegateImplV7.onCreateView(AppCompatDelegateImplV7.java:826)
            at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:732)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:483)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:415)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:366)
            at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:249)
            at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:106)
            at com.projmobileapp.pmdbadd.pmdb.MainActivity.onCreate(MainActivity.java:15)
            at android.app.Activity.performCreate(Activity.java:6289)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758)
            at android.app.ActivityThread.access$900(ActivityThread.java:177)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:145)
            at android.app.ActivityThread.main(ActivityThread.java:5942)
            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:1400)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
07-18 20:27:39.244    2702-2702/? W/ResourcesManager﹕ Asset path '/system/framework/twframework.jar' does not exist or contains no resources.

Here's my code

package com.projmobileapp.pmdbadd.pmdb;

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.GridView;

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.List;

public class MainActivityFragment extends Fragment {

    private ArrayList<Movie> flavorList;


    public MainActivityFragment() {
    }

    MovieAdapter mMovieAdapter;


    public void onSaveInstanceState(Bundle outState) {
        outState.putParcelableArrayList("flavors", flavorList);
        super.onSaveInstanceState(outState);
    }


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

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

        mMovieAdapter = new MovieAdapter(getActivity(), flavorList);
        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<Movie>> {
        private final String LOG_TAG = FetchMovieTask.class.getSimpleName();

        @Override
        protected List<Movie> 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=InsertAPIKey");

                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<Movie> getMovieDataFromJson(String forecastJsonStr)
                throws JSONException {
            List<Movie> movies = new ArrayList<>();
            JSONObject movieJson = new JSONObject(forecastJsonStr);
            JSONArray movieArray = movieJson.getJSONArray("results");
            for (int i = 0; i < movieArray.length(); i++) {
                JSONObject movie = movieArray.getJSONObject(i);
                Movie movie1 = new Movie(movieJson.getString("original_title"), movieJson.getDouble("vote_average"), movieJson.getString("release_date"), movieJson.getString("overview"), movieJson.getString("poster_path"));
                movies.add(movie1);

            }
            return movies;
        }





        @Override
        protected void onPostExecute(List<Movie> movies) {
            if (movies != null) {
                mMovieAdapter.clear();
                for(Movie dayForecastStr : movies) {
                    mMovieAdapter.add(dayForecastStr);
                }
                // New data is back from the server.  Hooray!
            }
        }
    }


}

Could someone please advise

3条回答
▲ chillily
2楼-- · 2019-02-19 22:48

I believe that you are supposedly saving the list out into the bundle on saveInstanceState for rotation, you're not actually reading it back in onCreate or onCreateView in case the bundle is not null. Also, I'm not even sure if Movie is actually a parcelable (use http://parcelabler.com ), but even if it were, this wouldn't work as you need to use writeTypedList and readTypedList and NOT writeParcelableArrayList (that returns List<Parcelable> on read, and that is NOT what you want).

But the current problem is that you should not give a null to the adapter in this line:

mMovieAdapter = new MovieAdapter(getActivity(), flavorList);

Initialize the adapter and set it only when you actually have data, or initialize it with an empty list.

Really though, use writeTypedList and readTypedList, otherwise you'll run into a lot of issues later on with state saving.

查看更多
SAY GOODBYE
3楼-- · 2019-02-19 22:53

For anyone that is using GsonFormatter plugin to retrieve information from a RESTful API, make sure that you do a clean Format of the Gson Formatter (Remove generated code in the class and redo it)..

查看更多
欢心
4楼-- · 2019-02-19 23:07
mMovieAdapter = new MovieAdapter(getActivity(), flavorList);

At this point in the code, flavorList is null. Do not create the MovieAdapter and call setAdapter() on the ListView until you have your movies. Or, initialize flavorList to be an empty ArrayList<Movie> before creating the adapter.

Also, please remove your broken MainActivityFragment constructor, or chain to the superclass constructor from inside of it.

查看更多
登录 后发表回答