我正在使用RecyclerView
和Async 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.movielove W / dalvikvm: threadid = 1:线程退出,未捕获异常(group = 0x41915c08) 12-12 20:24:22.136 4229-4229 / com.example.dell.movielove E / AndroidRuntime:FATAL EXCEPTION:main 处理:com.example.dell.movielove,PID: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) 在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(本地方法)
答案 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抛出。