使用RecyclerView和Async Task

时间:2015-12-12 15:10:13

标签: android android-fragments

我正在使用RecyclerViewAsync Task来更新此RecyclerView中的视图,但我在RecyclerView.setAdapter处获得了空指针异常。我的FetchMoviePoster类包含异步任务,PhotoAlbumAdapter包含Recycler View的适配器。 任何人都可以帮助我

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.movi​​elove W / dalvikvm:   threadid = 1:线程退出,未捕获异常(group = 0x41915c08)           12-12 20:24:22.136 4229-4229 / com.example.dell.movi​​elove E / AndroidRuntime:FATAL EXCEPTION:main                                                                                     处理:com.example.dell.movi​​elove,PID:4229                                                                                     显示java.lang.NullPointerException                                                                                         在   com.example.dell.movi​​elove.MainActivityFragment.update_the_Adaptor(MainActivityFragment.java:99)                                                                                         在   com.example.dell.movi​​elove.FetchMoviePoster.onPostExecute(FetchMoviePoster.java:138)                                                                                         在   com.example.dell.movi​​elove.FetchMoviePoster.onPostExecute(FetchMoviePoster.java:19)                                                                                         在android.os.AsyncTask.finish(AsyncTask.java:632)                                                                                         在android.os.AsyncTask.access $ 600(AsyncTask.java:177)                                                                                         在   android.os.AsyncTask $ InternalHandler.handleMessage(AsyncTask.java:645)                                                                                         在android.os.Handler.dispatchMessage(Handler.java:102)                                                                                         在android.os.Looper.loop(Looper.java:146)                                                                                         在android.app.ActivityThread.main(ActivityThread.java:5641)                                                                                         at java.lang.reflect.Method.invokeNative(Native Method)                                                                                         在java.lang.reflect.Method.invoke(Method.java:515)                                                                                         在   com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1288)                                                                                         在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1104)                                                                                         在dalvik.system.NativeStart.main(本地方法)

2 个答案:

答案 0 :(得分:1)

检查异步任务的onPostExecute方法:

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

        }

在新的MainActivityFragment实例上调用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);
        }

答案 1 :(得分:0)

你打电话

new MainActivityFragment().update_the_Adaptor(resultStrs);

但是您没有创建MainActivityFragment,因为您没有使用FragmentManager来提交您的片段,因此onCreateView将不会被调用且recyclelerView为null,您的NullPointerException将从update_the_Adaptor抛出。

相关问题