1

I am using a RecyclerView and a Async Task to update the view in this RecyclerView but I am getting a null pointer exception at a RecyclerView.setAdapter. My FetchMoviePoster class contains the Async Task and PhotoAlbumAdapter contains the adapter for the Recycler View. Can anyone please help me with that

MainActivityFragment

public class MainActivityFragment extends Fragment implements PhotoAlbumAdapter.OnItemClickListener {

        private RecyclerView recyclerView;
        private RecyclerView.LayoutManager layoutManager;
        PhotoAlbumAdapter mAdapter;
           FetchMoviePoster movie_fetch;
        public MainActivityFragment() {
        }


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

        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

            inflater.inflate(R.menu.movie_sort, menu);
        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {

            int id = item.getItemId();
            if (id == R.id.action_sort) {

                return true;
            }
            if(id== R.id.pop){
                updateMovie("popularity.desc");
                return true;
            }
            if(id== R.id.vote){
                updateMovie("vote_average.desc");
                return true;
            }


            return super.onOptionsItemSelected(item);
        }




        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);

            recyclerView = (RecyclerView) rootView.findViewById(R.id.recyle_view);
            recyclerView.setHasFixedSize(true);
            layoutManager = new GridLayoutManager(getActivity(), 2, GridLayoutManager.VERTICAL, false);

            recyclerView.setLayoutManager(layoutManager);
           movie_fetch= new FetchMoviePoster();

            registerForContextMenu(recyclerView);
            updateMovie("vote_count.desc");
            return rootView;
        }

        private void updateMovie(String c) {
            movie_fetch.execute(c);
        }

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v,
                                        ContextMenu.ContextMenuInfo menuInfo) {
            super.onCreateContextMenu(menu, v, menuInfo);
            getActivity().getMenuInflater().inflate(R.menu.pop_up_menu, menu);
        }

        public void update_the_Adaptor(String[] st){
            mAdapter = new PhotoAlbumAdapter(new ArrayList<>(Arrays.asList(st)), getContext());
            recyclerView.setAdapter(mAdapter);
            mAdapter.SetOnItemClickListener(MainActivityFragment.this);
        }


        @Override
        public void onItemClick(View view, int position) {
            Log.v("Actual position", Integer.toString(position));
            Intent detail= new Intent(getActivity(),DetailActivity.class);
            detail.putExtra("position",position);
            detail.putExtra("poster", movie_fetch.resultStrs);

            detail.putExtra("title",movie_fetch. movie_title);
            detail.putExtra("plot", movie_fetch.movie_plot);
            detail.putExtra("user_rating", movie_fetch.user_rating);
            detail.putExtra("release", movie_fetch.release_date);
            startActivity(detail);
        }
    }




    My PhotoAlbumAdapterClass



    public class PhotoAlbumAdapter extends RecyclerView.Adapter<PhotoAlbumAdapter.ViewHolder> {
        ArrayList<String> image;
        Context context;

        OnItemClickListener mClickListener;
        public PhotoAlbumAdapter(ArrayList<String> imageView, Context context) {
            image=imageView;
            this.context=context;
        }

        @Override
        public PhotoAlbumAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.image_holder,parent,false);
            ViewHolder vh=new ViewHolder(v);
            return vh;
        }

        @Override
        public void onBindViewHolder(final PhotoAlbumAdapter.ViewHolder holder, int position) {
            String st=image.get(position);
            Uri uri=Uri.parse(st);
            Picasso.with(context).load(uri)
                    .into(holder.img);


            AnimationsUtils.animate(holder);

        }

        @Override
        public int getItemCount() {

            return image.size();

        }

        public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

            ImageView img;

            public ViewHolder(View itemView) {
                super(itemView);
                img = (ImageView) itemView.findViewById(R.id.imageView);
                itemView.setOnClickListener(this);
            }

            @Override
            public void onClick(View view) {
                if(mClickListener !=null)
                    mClickListener.onItemClick(view, getAdapterPosition()); //OnItemClickListener mItemClickListener;
            }
        }

        public interface OnItemClickListener {
            void onItemClick(View view, int position);
        }
        public void SetOnItemClickListener(final OnItemClickListener m){
            mClickListener=m;
        }
    }



    My FetchMoviePoster class


    public class FetchMoviePoster extends AsyncTask<String, Void, String[]> {
        private final String LOG_TAG = FetchMoviePoster.class.getSimpleName();

        String choice;
        String[] resultStrs;
        String[] movie_title;
        String[] movie_plot;
        String[] user_rating;
        String[] release_date;
        @Override
        protected String[] doInBackground(String... code) {

            HttpURLConnection urlConnection = null;
            BufferedReader reader = null;
            String[] image_poster = new String[0];
            String API = "api_key";
            String SORT="sort_by";

            choice=code[0];
            String forecastJsonStr = null;

            try {
                Uri fetch_url = Uri.parse("http://api.themoviedb.org/3/discover/movie?");
                Uri builder = fetch_url.buildUpon().
                        appendQueryParameter(SORT,choice)
                        .appendQueryParameter(API, BuildConfig.THE_MOVIE_DB_API_KEY).build();
                URL url = new URL(builder.toString());



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

                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) {
                    return null;
                }
                forecastJsonStr = buffer.toString();


                try {
                    image_poster = getUrlForImage(forecastJsonStr);

                } catch (JSONException e) {
                    e.printStackTrace();
                }


            } catch (IOException e) {
                Log.e(LOG_TAG, "Error ", e);
                // If the code didn't successfully get the weather data, there's no point in attempting
                // to parse it.
                forecastJsonStr = 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);
                    }
                }
            }
            return image_poster;
        }

        private String[] getUrlForImage(String forecastJsonStr) throws JSONException {
            final String OWM_POSTER = "results";
            final String FILE_PATH = "poster_path";
            final String ORIGINAL_TITLE="original_title";
            final String OVERVIEW="overview";
            final String User_RATING="vote_average";
            final String RELEASE="release_date";

            JSONObject forecastJson = new JSONObject(forecastJsonStr);
            JSONArray movieArray = forecastJson.getJSONArray(OWM_POSTER);
            resultStrs = new String[movieArray.length()];
            movie_title=new String[movieArray.length()];
            movie_plot=new String[movieArray.length()];
            user_rating=new String[movieArray.length()];
            release_date=new String[movieArray.length()];
            for (int i = 0; i < movieArray.length(); i++) {

                JSONObject movie = movieArray.getJSONObject(i);

                String file_name = movie.getString(FILE_PATH);
                String title=movie.getString(ORIGINAL_TITLE);
                String plot=movie.getString(OVERVIEW);
                String userRating=movie.getString(User_RATING);
                String release=movie.getString(RELEASE);
                resultStrs[i] = "http://image.tmdb.org/t/p/w185/" +file_name;
                movie_title[i]=title;
                movie_plot[i]=plot;
                user_rating[i]= userRating;
                release_date[i]=release;
            }

            return resultStrs;
        }

        @Override
        protected void onPostExecute(String[] resultStrs) {
            if (resultStrs != null) {

                 new MainActivityFragment().update_the_Adaptor(resultStrs);

            }

        }
    }

LogCat

12-12 20:24:22.066 4229-4229/com.example.dell.movielove W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41915c08) 12-12 20:24:22.136 4229-4229/com.example.dell.movielove E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.dell.movielove, PID: 4229 java.lang.NullPointerException at com.example.dell.movielove.MainActivityFragment.update_the_Adaptor(MainActivityFragment.java:99) at com.example.dell.movielove.FetchMoviePoster.onPostExecute(FetchMoviePoster.java:138) at com.example.dell.movielove.FetchMoviePoster.onPostExecute(FetchMoviePoster.java:19) at android.os.AsyncTask.finish(AsyncTask.java:632) at android.os.AsyncTask.access$600(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5641) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1288) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1104) at dalvik.system.NativeStart.main(Native Method)

Vipul Asri
  • 8,903
  • 3
  • 46
  • 71
Kirti Chaturvedi
  • 1,245
  • 13
  • 24

2 Answers2

1

Check onPostExecute method of Async task:

 @Override
        protected void onPostExecute(String[] resultStrs) {
            if (resultStrs != null) {
                 //creating new instance not using old
                 new MainActivityFragment().update_the_Adaptor(resultStrs);
            }

        }

on new instance of MainActivityFragment you are calling update_the_Adaptor()

public void update_the_Adaptor(String[] st){
            // st is not null
            mAdapter = new PhotoAlbumAdapter(new ArrayList<>(Arrays.asList(st)), getContext());
            recyclerView.setAdapter(mAdapter);//null recycler view as onCreate is not called
            mAdapter.SetOnItemClickListener(MainActivityFragment.this);
        }
VIjay J
  • 736
  • 7
  • 14
  • For this either I have to declare the update_the_Adaptor static or calll the onCreateView again for the new Instance created both are farStretched ,any easy solution for it – Kirti Chaturvedi Dec 12 '15 at 16:34
  • Well I would suggest to use Handler. See this post http://stackoverflow.com/questions/34241067/how-to-manage-different-task-which-need-to-be-called-by-asynctask/34241460#34241460 – VIjay J Dec 14 '15 at 13:11
  • I was not familiar with this concept of Handler earlier but thanks to u now it is working – Kirti Chaturvedi Dec 14 '15 at 20:29
0

You call

new MainActivityFragment().update_the_Adaptor(resultStrs);

But you MainActivityFragment didn't create because you didn't use FragmentManager to commit your fragment so onCreateView will not be called and recyclerView is null, your NullPointerException will be thrown from update_the_Adaptor.

Lan Nguyen
  • 785
  • 5
  • 13