java - GridView setAdapter 方法给出 NullPointerException

标签 java android gridview android-adapter android-gridview

将 ArrayAdapter 设置为 GridView 适配器时,出现以下 NullPointerException。应用程序在运行时崩溃。

Logcat:

02-07 19:34:36.599: E/AndroidRuntime(26304): FATAL EXCEPTION: main
02-07 19:34:36.599: E/AndroidRuntime(26304): Process: com.shreyans.moviemania, PID: 26304
02-07 19:34:36.599: E/AndroidRuntime(26304): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.shreyans.moviemania/com.shreyans.moviemania.MainActivity}: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2411)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2474)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.app.ActivityThread.access$800(ActivityThread.java:144)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1359)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.os.Handler.dispatchMessage(Handler.java:102)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.os.Looper.loop(Looper.java:155)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.app.ActivityThread.main(ActivityThread.java:5702)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at java.lang.reflect.Method.invoke(Native Method)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at java.lang.reflect.Method.invoke(Method.java:372)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
02-07 19:34:36.599: E/AndroidRuntime(26304): Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class fragment
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.view.LayoutInflater.parseInclude(LayoutInflater.java:892)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:802)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at com.shreyans.moviemania.MainActivity.onCreate(MainActivity.java:17)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.app.Activity.performCreate(Activity.java:5958)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
02-07 19:34:36.599: E/AndroidRuntime(26304):    ... 10 more
02-07 19:34:36.599: E/AndroidRuntime(26304): Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.widget.GridView.setAdapter(GridView.java:201)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at com.shreyans.moviemania.MainActivityFragment.onCreateView(MainActivityFragment.java:107)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1036)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1226)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1328)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2284)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:111)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:314)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:79)
02-07 19:34:36.599: E/AndroidRuntime(26304):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
02-07 19:34:36.599: E/AndroidRuntime(26304):    ... 21 more

这是我的适配器类:

public class MovieAdapter extends ArrayAdapter<Movie>{
    private static final String LOG_TAG = MovieAdapter.class.getSimpleName();

    public MovieAdapter(Activity context, List<Movie> movieList) {
        super(context, 0, movieList);
    }

    @Override
    public View getView(int position, View recycledView, ViewGroup parent) {
        Movie movie = getItem(position);

        if (recycledView == null){
            recycledView = LayoutInflater.from(getContext()).inflate(
            R.layout.grid_item_movies, parent, false);
        }
        ImageView imageView = (ImageView) recycledView.findViewById(R.id.grid_item_movies_image);
        imageView.setAdjustViewBounds(true);
        String baseUrl= "http://image.tmdb.org/t/p/";
        final String SIZE="w185/";
        Picasso.with(getContext())
                .load(baseUrl + SIZE + movie.getPosterPath())
                .into(imageView);
        return recycledView;
    }
}

MainActivityFragment.java:

public class MainActivityFragment extends Fragment {
    private static final String LOG_TAG = "ServiceGenerator";
    public static final String API_BASE_URL = "http://api.themoviedb.org/3/";
    private String sortBy="popularity.desc"; //Default sorting order
    private ArrayList<Movie> movieArrayList;
    private MovieAdapter movieAdapter;

    public MainActivityFragment() {
    }

        private void onLoadMoviesEvent() {
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            // set your desired log level
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            OkHttpClient httpClient = new OkHttpClient();
            httpClient.interceptors().add(logging);

            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(httpClient)
                    .build();

            MovieApiService movieApiService = retrofit.create(MovieApiService.class);

            Call<MovieResults> call = movieApiService.fetchMovies(BuildConfig.MY_MOVIE_DB_API_KEY, sortBy);

            call.enqueue(new Callback<MovieResults>(){
                @Override
                public void onResponse(Response<MovieResults> response, Retrofit retrofit1) {
                    MovieResults movieResults = response.body();
                    if (movieResults != null) {
                        Log.i(LOG_TAG, "Got requested object: " + movieResults.getTotalPages() + " results.");

                        movieArrayList = (ArrayList<Movie>) movieResults.getResults();

                        Log.i(LOG_TAG, "Retrieved arraylist with 1st movie: \n" +
                                "Name: " + movieArrayList.get(0).getTitle()+
                                "\nPoster path: " + movieArrayList.get(0).getPosterPath() +
                                "\nRelease Date: " + movieArrayList.get(0).getReleaseDate() +
                                "\nOverview: " + movieArrayList.get(0).getOverview());
                        movieAdapter.clear();
                        movieAdapter.addAll(movieArrayList);
                    }
                    else {
                        Log.e(LOG_TAG, "Getting null object of MovieResults");
                        try {
                            String string = response.errorBody().string();
                            Log.i(LOG_TAG, string);
                        }
                        catch (IOException e) {
                            Log.e(LOG_TAG, "IOException inside the response");
                        }
                    }

                }
                @Override
                public void onFailure(Throwable throwable) {
                    Log.i(LOG_TAG, "Retrofit response failure");
                }

            });
        }

    @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);
        movieAdapter = new MovieAdapter(getActivity(), movieArrayList);

        GridView gridView = (GridView) rootView.findViewById(R.id.gridview);
        gridView.setAdapter(movieAdapter);
        onLoadMoviesEvent();
        return rootView;
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

最佳答案

您正在使用异步请求来加载数据。因此,当您在 onCreateView() 中实例化适配器时方法中,您的数据尚未加载,并且 movieArrayList 为 null,这就是为什么在您创建适配器时它会抛出 NullPointerException

1) 用空数组初始化数组列表,以避免 NPE:

private ArrayList<Movie> movieArrayList = new ArrayList<Movie>();

2) 调用 notifyDataSetChanged()onResponse() 更新数据后方法,刷新GridView :

@Override
public void onResponse(Response<MovieResults> response, Retrofit retrofit1) {
       MovieResults movieResults = response.body();
       if (movieResults != null) {
            movieArrayList = (ArrayList<Movie>) movieResults.getResults();
            movieAdapter.clear();// no need for this line in the first call
            movieAdapter.addAll(movieArrayList);
            movieAdapter.notifyDataSetChanged();
        }

        // ....
 }

关于java - GridView setAdapter 方法给出 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35254843/

相关文章:

java - 如何为多个 JMenuItem 创建 ActionListener?

android - 将多个 Admob 广告预加载到数组中?

android - 如何在android中获取用相机拍摄的最后一张照片?

java - Jpcap处理程序不起作用

java - 如何从请求对象获取客户端时间。没有 JavaScript

java - 尝试注入(inject)两个具有通用实现的存储库失败

java - AlarmManager 没有触发我的服务

android - 在 Android 中静态创建 2X2 ImageView 的 GridView

android - GridView : How to fill entire space with text view

c# - 获取 gridview 列值作为 javascript 函数的参数