2015-12-12 3 views
1

Я использую RecyclerView и Async Task, чтобы обновить представление в этом RecyclerView, но я получаю исключение нулевого указателя в RecyclerView.setAdapter. Мой класс FetchMoviePoster содержит задачу Async, а PhotoAlbumAdapter содержит адаптер для просмотра Recycler. Может кто-нибудь, пожалуйста, помогите мне с этимNull указатель Исключение при использовании RecyclerView и Async Задача

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: поток, выходящий с неперехваченным исключением (группа = 0x41915c08) 12-12 20: 24: 22.136 4229-4229/com.example.dell.movielove E/Android Продолжительность: неустранимые: Основной процесс: com.example.dell.movielove, ПИД: 4229 java.lang.NullPointerException на com.example.dell.movielove.MainActivityFragment.update_the_Adaptor (MainActivityFragment.java:99) в com.example.dell.movielove.FetchMoviePoster.onPostExecute (FetchMoviePoster.java:138) на com.example.dell.movielove.FetchMoviePoster.onPostExecute (FetchMoviePoster.java:19) на android.os.AsyncTask.finish (AsyncTask .java: 632) at 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) в java.lang.reflect.Method.invokeNative (нативный метод) в java.lang.reflect.Method.invoke (Method.java:515) на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:1288) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1104) в dalvik.system.NativeStart.main (Native Method)

ответ

0

Вы называете

new MainActivityFragment().update_the_Adaptor(resultStrs); 

Но вы MainActivityFragment не создали, потому что вы не использовали FragmentManager совершить свой фрагмент так onCreateView не будет и recyclerView имеет значение null, ваше исключение NullPointerException будет выбрано из update_the_Adaptor.

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); 
     } 
+0

Для этого либо я должен вновь заявить о update_the_Adaptor статическими или CALLL в onCreateView для нового экземпляра, созданного как longStretched, любое простое решение для него –

+0

Ну, я бы предложил использовать Handler. См. Этот пост http://stackoverflow.com/questions/34241067/how-to-manage-different-task-which-need-to-be-called-by-asynctask/34241460#34241460 – VVJ

+0

Мне не знакома эта концепция обработчика раньше, но благодаря u теперь он работает –

Смежные вопросы