This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
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)
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);
}
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.
Related
I have a problem, when i swipe to refresh the data, the first swipe is ok but after that every swipe reload and add the same data over and over again, by the end i have a list with same items over and over... I'm using a loader.
I tried to clear before but i don't understand what's wrong with my code, if someone could explain it to me. Thank You.
Here my code :
public abstract class NewsFragment extends Fragment implements LoaderManager.LoaderCallbacks<ArrayList<Articles>> {
protected ItemAdapter mArticleAdapter;
protected RecyclerView mRecyclerView;
protected NewsFragment.OnNewSelectedInterface mListener;
protected RecyclerView.LayoutManager mManager;
protected SwipeRefreshLayout mSwipeRefreshLayout;
protected LoaderManager mLoaderManager;
private boolean mStateSaved;
private static final int NEWS_LOAD_ID = 1;
public static final String KEY_LIST = "key_list";
public interface OnNewSelectedInterface {
void onListNewSelected(int index, ArrayList<Articles> articles);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.list_present_news, container, false);
mListener = (NewsFragment.OnNewSelectedInterface) getActivity();
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeContainer);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
mManager = new LinearLayoutManager(getActivity());
mArticleAdapter = new ItemAdapter(getActivity(), new ArrayList<Articles>(), mListener);
mLoaderManager = getLoaderManager();
mStateSaved = mArticleAdapter.isStateSaved();
mRecyclerView.setAdapter(mArticleAdapter);
mRecyclerView.setLayoutManager(mManager);
getData();
refreshData();
if(!isNetworkAvailable())alertUserAboutError();
setDivider();
return view;
}
private void setDivider() {
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mRecyclerView
.getContext(), DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(dividerItemDecoration);
}
private void getData() {
getLoaderManager().initLoader(NEWS_LOAD_ID, null, this).forceLoad();
}
private void alertUserAboutError() {
AlertDialogFragment alertDialogFragment = new AlertDialogFragment();
alertDialogFragment.show(getActivity().getFragmentManager(), "error_dialog");
}
protected abstract String[] getUrl();
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager)
getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
private void refreshData() {
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mArticleAdapter.clear();
mSwipeRefreshLayout.setRefreshing(false);
}
});
mSwipeRefreshLayout.setColorSchemeResources(
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
#Override
public Loader<ArrayList<Articles>> onCreateLoader(int id, Bundle args) {
return new NewsLoader(getActivity(), getUrl());
}
#Override
public void onLoadFinished(Loader<ArrayList<Articles>> loader, ArrayList<Articles> data) {
if (data != null && !data.isEmpty()) {
mArticleAdapter.addAll(data);
}
}
#Override
public void onLoaderReset(Loader<ArrayList<Articles>> loader) {
mArticleAdapter.clear();
}
}
My loader class :
public class NewsLoader extends AsyncTaskLoader<ArrayList<Articles>>{
private ArrayList<Articles> mArticlesArrayList;
private String[] mUrl;
public NewsLoader(Context context, String[] url) {
super(context);
mUrl = url;
}
#Override
public ArrayList<Articles> loadInBackground() {
OkHttpClient mClient = new OkHttpClient();
for (String aMUrl : mUrl) {
Request mRequest = new Request.Builder().url(aMUrl).build();
try {
Response response = mClient.newCall(mRequest).execute();
try {
if (response.isSuccessful()) {
String json = response.body().string();
getMultipleUrls(json);
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return mArticlesArrayList;
}
private void getMultipleUrls(String jsonData) throws JSONException {
if (mArticlesArrayList == null) {
mArticlesArrayList = getArticleForecast(jsonData);
} else {
mArticlesArrayList.addAll(getArticleForecast(jsonData));
}
}
private ArrayList<Articles> getArticleForecast(String jsonData) throws JSONException {
JSONObject forecast = new JSONObject(jsonData);
JSONArray articles = forecast.getJSONArray("articles");
ArrayList<Articles> listArticles = new ArrayList<>(articles.length());
for (int i = 0; i < articles.length(); i++) {
JSONObject jsonArticle = articles.getJSONObject(i);
Articles article = new Articles();
String urlImage = jsonArticle.getString("urlToImage");
article.setTitle(jsonArticle.getString("title"));
article.setDescription(jsonArticle.getString("description"));
article.setImageView(urlImage);
article.setArticleUrl(jsonArticle.getString("url"));
listArticles.add(i, article);
}
return listArticles;
}
}
My Adapter class :
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ArticleViewHolder> {
private static final String TAGO = ItemAdapter.class.getSimpleName();
private final NewsFragment.OnNewSelectedInterface mListener;
private ArrayList<Articles> mArticlesList;
private Context mContext;
private int lastPosition = -1;
private boolean mStateSaved = false;
public boolean isStateSaved() {
return mStateSaved;
}
public void setStateSaved(boolean stateSaved) {
mStateSaved = stateSaved;
}
public ItemAdapter(Context context, ArrayList<Articles> articles, NewsFragment.OnNewSelectedInterface listener){
mContext = context;
mArticlesList = articles;
mListener = listener;
}
#Override
public ArticleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_card_view, parent, false);
ArticleViewHolder articleViewHolder = new ArticleViewHolder(view);
articleViewHolder.setIsRecyclable(false);
return articleViewHolder;
}
#Override
public void onBindViewHolder(ArticleViewHolder holder, int position) {
holder.bindArticle(mArticlesList.get(holder.getAdapterPosition()));
setAnimation(holder.itemView, holder.getAdapterPosition());
}
private void setAnimation(View viewToAnimate, int position) {
if (position > lastPosition) {
Animation animation = AnimationUtils.loadAnimation(viewToAnimate.getContext(), android.R.anim.slide_in_left);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
#Override
public int getItemCount() {
return mArticlesList.size();
}
public void clear() {
mArticlesList.clear();
notifyDataSetChanged();
}
public void addAll(ArrayList<Articles> articles) {
mArticlesList.addAll(articles);
notifyDataSetChanged();
}
protected class ArticleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private ImageView mImageView;
private TextView mTitleTextView, mDescriptionTextView;
private FloatingActionButton mSaveButton;
private ArticleViewHolder(View itemView) {
super(itemView);
mImageView = (ImageView) itemView.findViewById(R.id.photoImageView);
mTitleTextView = (TextView) itemView.findViewById(R.id.titleWithoutImage);
mDescriptionTextView = (TextView) itemView.findViewById(R.id.descriptionTextView);
mSaveButton = (FloatingActionButton) itemView.findViewById(R.id.floatingActionButton);
itemView.setOnClickListener(this);
}
private void bindArticle(final Articles article) {
Glide.with(mContext).load(article.getImageView()).into(mImageView);
mTitleTextView.setText(article.getTitle());
mDescriptionTextView.setText(article.getDescription());
if(mDescriptionTextView.getText().equals("")){
mDescriptionTextView.setVisibility(View.GONE);
}
mSaveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
insertArticle(article);
article.setStateSaved(true);
}
});
Log.v(TAGO, "Item id : " + getItemId()
+ "Item count : " + getItemCount()
+ "Item position : " + getAdapterPosition()
+ String.valueOf(article.isStateSaved()));
}
private void insertArticle(Articles articles) {
String title = articles.getTitle();
String description = articles.getDescription();
String url = articles.getArticleUrl();
ContentValues contentValues = new ContentValues();
contentValues.put(ArticleContract.ArticleEntry.COLUMN_TITLE_ARTICLE, title);
contentValues.put(ArticleContract.ArticleEntry.COLUMN_DESCRIPTION_ARTICLE, description);
contentValues.put(ArticleContract.ArticleEntry.COLUMN_URL_ARTICLE, url);
Uri uri = mContext.getContentResolver().insert(ArticleContract.ArticleEntry.CONTENT_URI, contentValues);
if(uri == null) {
Log.v(TAGO, "Error");
} else Toast.makeText(mContext, "Article Saved", Toast.LENGTH_SHORT).show();
}
#Override
public void onClick(View view) {
mListener.onListNewSelected(getLayoutPosition(), mArticlesList);
}
}
}
You are using ViewHolder#setIsRecyclable incorrectly; this method is meant to be used to prevent a ViewHolder from being recycled only while changes are being made to it. According to the documentation:
Calls to setIsRecyclable() should always be paired (one call to
setIsRecyclabe(false) should always be matched with a later call to
setIsRecyclable(true)).
This means none of your ViewHolder objects will be recycled, effectively making the use of a RecyclerView worthless, and preventing it from reusing the views when you attempt to bind new objects to your RecyclerView.
So, in short, remove that line of code.
I noticed a few other small issues with your adapter code as well, which can cause a multitude headaches in the future; so I took the liberty of highlighting some of the changes I would make.
Just for my own sanity, I will refer to your Articles class as Article.
It is usually not a good idea to pass around your Context all over the place. The View passed to your ViewHolder already has a reference to a Context, so you can use that instead.
As for the insertArticle() code, the Activity should be handling this anyway. So you can pass the Article back to the Activity by passing a listener to your Adapter (and subsequently, each ViewHolder) instead of the Context.
You should also consider using the DiffUtil class instead of just calling notifyDataSetChanged(); it is much more efficient. Just make sure your Article class is implementing equals() and hashCode() or it will not work.
I didn't include the animation code (that can easily be added back in) or the saved state code (mostly because I don't know what you were trying to do).
public class ArticleAdapter extends RecyclerView.Adapter<Article> {
private List<Article> mData;
private ArticleViewHolder.OnSelectedListener mOnSelectedListener;
private ArticleViewHolder.OnSaveListener mOnSaveListener;
public ArticleAdapter(ArticleViewHolder.OnSelectedListener onSelectedListener, ArticleViewHolder.OnSaveListener onSaveListener) {
mOnSelectedListener = onSelectedListener;
mOnSaveListener = onSaveListener;
mData = new ArrayList<>();
}
public void replaceData(final List<Article> data) {
final List<Article> oldData = new ArrayList<>(mData);
mData.clear();
if (data != null) {
mData.addAll(data);
}
DiffUtil.calculateDiff(new DiffUtil.Callback() {
#Override
public int getOldListSize() {
return oldData.size();
}
#Override
public int getNewListSize() {
return mData.size();
}
#Override
public int areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldData.get(oldItemPosition).equals(mData.get(newItemPosition));
}
#Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldData.get(oldItemPosition).equals(mData.get(newItemPosition));
}
}).dispatchUpdatesTo(this);
}
#Override
public ArticleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_card_view, parent, false);
return new SelectLocationViewHolder(view, mOnSelectedListener, mOnSaveListener);
}
#Override
public void onBindViewHolder(ArticleViewHolder holder, int position) {
holder.bind(mData.get(position));
}
#Override
public int getItemCount() {
return mData.size();
}
}
public class ArticleViewHolder extends RecyclerView.ViewHolder {
public interface OnSelectedListener {
void onSelected(Article article);
}
public interface OnSaveListener {
void onSave(Article article);
}
private View mView;
private Article mArticle;
private OnSelectedListener mOnSelectedListener;
private OnSaveListener mOnSaveListener;
private ImageView mImageView;
private TextView mTitleTextView, mDescriptionTextView;
private FloatingActionButton mSaveButton;
public ArticleViewHolder(View itemView, final OnSelectedListener onSelectedListener, final OnSaveListener onSaveListener) {
super(itemView);
mImageView = (ImageView) itemView.findViewById(R.id.photoImageView);
mTitleTextView = (TextView) itemView.findViewById(R.id.titleWithoutImage);
mDescriptionTextView = (TextView) itemView.findViewById(R.id.descriptionTextView);
mSaveButton = (FloatingActionButton) itemView.findViewById(R.id.floatingActionButton);
mView = itemView;
mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onSelectedListener.onSelected(mArticle);
}
});
mSaveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onSaveListener.onSave(mArticle);
}
});
}
public void bind(Article article) {
mArticle = article;
mTitleTextView.setText(article.getTitle());
mDescriptionTextView.setText(article.getDescription());
if(TextUtils.isEmpty(article.getDescription())) {
mDescriptionTextView.setVisibility(View.GONE);
}
Glide.with(mView.getContext()).load(article.getImage()).into(mImageView);
}
}
Edit
The actual issue is that your loader uses the same ArrayList every time, and keeps adding the new results to it.
public class NewsLoader extends AsyncTaskLoader<List<Article>> {
private final String[] mUrls;
private final OkHttpClient mClient;
public NewsLoader(Context context, OkHttpClient client, String... urls) {
super(context);
mClient = client;
mUrls = urls;
}
#Override
public List<Article> loadInBackground() {
List<Article> articles = new ArrayList<>();
for (String url : mUrls) {
Request request = new Request.Builder().url(url).build();
try {
Response response = mClient.newCall(request).execute();
if (response.isSuccessful()) {
parseData(response.body().string(), articles);
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
}
return articles;
}
private void parseData(List<Article> articles, String data) throws JSONException {
JSONObject forecast = new JSONObject(data);
JSONArray a = forecast.getJSONArray("articles");
for (int i = 0; i < a.length(); i++) {
JSONObject o = a.getJSONObject(i);
Article article = new Article(
o.getString("title"),
o.getString("description"),
o.getString("url"),
o.getString("urlToImage"));
articles.add(article);
}
}
}
Also, you may have noticed, I made a small change to your Article constructor. You should consider making the Article class immutable, as this will prevent you from making mistakes when dealing with multithreading. It should look something like this:
public class Article {
private final String mTitle;
private final String mDescription;
private final String mUrl;
private final String mImageUrl;
public Article(String title, String description, String url, String imageUrl) {
mTitle = title;
mDescription = description;
mUrl = url;
mImageUrl = imageUrl;
}
public String title() {
return mTitle;
}
public String description() {
return mDescription;
}
public String url() {
return mUrl;
}
public String imageUrl() {
return mImageUrl;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Article other = (Article) o;
return mTitle != null && mTitle.equals(other.mTitle) &&
mDescription != null && mDescription.equals(other.mDescription) &&
mUrl != null && mUrl.equals(other.mUrl) &&
mImageUrl != null && mImageUrl.equals(other.mImageUrl);
}
#Override
public int hashCode() {
int result = mTitle != null ? mTitle.hashCode() : 0;
result = 31 * result + (mDescription != null ? mDescription.hashCode() : 0);
result = 31 * result + (mUrl != null ? mUrl.hashCode() : 0);
result = 31 * result + (mImageUrl != null ? mImageUrl.hashCode() : 0);
return result;
}
}
#Override
public void onBindViewHolder(ArticleViewHolder holder, int position) {
holder.bindArticle(mArticlesList.get(position));
setAnimation(holder.itemView, position);
}
public void addAll(ArrayList<Articles> articles) {
mArticlesList.clear();
mArticlesList.addAll(articles);
notifyDataSetChanged();
}
If this doesn't wrok then I think your api is giving you redundant data.
Why you are using articleViewHolder.setIsRecyclable(false);
One another place which might cause the problem is
private void getMultipleUrls(String jsonData) throws JSONException {
if (mArticlesArrayList == null) {
mArticlesArrayList = getArticleForecast(jsonData);
} else {
mArticlesArrayList.addAll(getArticleForecast(jsonData));
}
}
You are calling it from a loop add adding data to your arraylist. There somehow multiple data can be inserted in your ArrayList
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I am getting this error-Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
This is what i have done!
PeopleListFragment
**PeopleListFragment**
public class PeopleListFragment extends Fragment{
public static final String DISPLAY_URL = ServiceAPI.URL_CONTACTS;
private static final String TAG = "PeopleListActivity";
public static final boolean DEBUG = Constant.DEBUG;
private ProgressDialog progressDialog;
public PeopleAdapter adapter;
private GetAllPeopleTask mGetAllPeople = null;
private Intent intent;
public static ListView mContactlistView;
public PeopleListFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_people_list, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mContactlistView = (ListView) view.findViewById(R.id.people_list);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
List<People> contactList = new ArrayList<People>();
adapter = new PeopleAdapter(getActivity().getApplicationContext(),
R.layout.people_list_item, contactList);
mContactlistView.setAdapter(adapter);
mContactlistView.setTextFilterEnabled(true);
mContactlistView.setFastScrollEnabled(true);
mContactlistView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String empId = String.valueOf(adapter.getItem(position).getEmployeeId());
String name = String.valueOf(adapter.getItem(position).getFirstName());
intent = new Intent(getActivity(),
PeopleDetailsActivity.class);
intent.putExtra("EmployeeId", empId);
intent.putExtra("name", name);
startActivity(intent);
}
});
startAsyncTask();
TextView textView = new TextView(getContext());
textView.setText("Empty");
mContactlistView.setEmptyView(textView);
}
public void startAsyncTask() {
mGetAllPeople = new GetAllPeopleTask();
mGetAllPeople.execute(DISPLAY_URL, "12345678");
}
public class GetAllPeopleTask extends AsyncTask<String, Void, List<People>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Loading");
progressDialog.show();
}
#Override
protected ArrayList<People> doInBackground(String... params) {
ArrayList<People> peopleList = new ArrayList<>();
try {
URL url = new URL(params[0]);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setReadTimeout(40000);
httpURLConnection.setConnectTimeout(50000);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Content-Type", "application/json");
httpURLConnection.setRequestProperty("Accept", "application/json");
httpURLConnection.setDoOutput(true);
JSONObject request = new JSONObject();
request.put("session", params[1]);
String bodyParams = request.toString();
if (DEBUG) {
Log.i(TAG, bodyParams);
}
httpURLConnection.setRequestProperty("Content-Length",
String.valueOf(bodyParams.getBytes().length));
DataOutputStream outputStream = new DataOutputStream(httpURLConnection.getOutputStream());
outputStream.writeBytes(bodyParams);
outputStream.flush();
outputStream.close();
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == 200) {
Log.i(TAG, "Success");
} else {
Log.i(TAG, "Error Code :" + httpURLConnection.getResponseCode());
}
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {
builder.append(line);
}
Log.i(TAG, "Builder String : " + builder.toString());
JSONObject jsonObject = new JSONObject(builder.toString());
Log.i(TAG, "Response JSON : " + jsonObject.toString());
if (jsonObject.has("responseData")) {
JSONArray responseDataArr = jsonObject.optJSONArray("responseData");
for (int i = 0; i < responseDataArr.length(); i++) {
JSONObject peopleJSON = responseDataArr.optJSONObject(i);
People people = new People();
people.setEmployeeId(peopleJSON.optString("employeeId"));
people.setFirstName(peopleJSON.optString("firstName"));
people.setLastName(peopleJSON.optString("lastName"));
// Log.i("hebsiba ", "People first name" + people.getFirstName() + ", last name is " + people.getLastName()) ;
if((!people.getFirstName().isEmpty()) && (!people.getLastName().isEmpty())) {
peopleList.add(people);
}
if (DEBUG) {
Log.i(TAG, "People " + people.getEmployeeId());
}
}
}
} catch (IOException | JSONException e) {
Log.e(TAG, e.toString());
}
return peopleList;
}
#Override
protected void onPostExecute(List<People> people) {
super.onPostExecute(people);
Collections.sort(people, new Comparator<People>() {
#Override
public int compare(People lhs, People rhs) {
return lhs.getFirstName().compareToIgnoreCase(rhs.getFirstName());
}
});
adapter.addAll(people);
if (DEBUG) {
Log.i(TAG, adapter.getCount() + " ");
}
Log.v(TAG, String.valueOf(people.size()));
progressDialog.dismiss();
}
}
}
This is the PeopleAdapter
**PeopleAdapter**
public class PeopleAdapter extends ArrayAdapter<People> implements Filterable {
private PeopleListActivity activity;
private PeopleFilter peopleFilter;
private List<People> peopleList;
private List<People> filteredList;
public PeopleAdapter(Context applicationContext, int people_list_item, List<People> contactList) {
super(applicationContext, people_list_item, contactList);
filteredList = contactList;
getFilter();
}
#Override
public int getCount() {
return filteredList.size();
}
#Override
public People getItem(int i) {
return filteredList.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
People peopleList = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.people_list_item, null);
holder = new ViewHolder();
holder.firstName = (TextView) convertView.findViewById(R.id.firstName);
holder.lastName = (TextView) convertView.findViewById(R.id.lastName);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.firstName.setText(peopleList.getFirstName());
holder.lastName.setText(peopleList.getLastName());
return convertView;
}
/**
* Get custom filter
* #return filter
*/
#Override
public Filter getFilter() {
if (peopleFilter == null) {
peopleFilter = new PeopleFilter();
}
return peopleFilter;
}
static class ViewHolder {
TextView firstName;
TextView lastName;
}
private class PeopleFilter extends Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint!=null && constraint.length()>0) {
ArrayList<People> tempList = new ArrayList<>();
// search content in friend list
for (People user : peopleList) {
if (user.getFirstName().toLowerCase().contains(constraint.toString().toLowerCase())) {
tempList.add(user);
}
}
filterResults.count = tempList.size();
filterResults.values = tempList;
} else {
filterResults.count = peopleList.size();
filterResults.values = peopleList;
}
return filterResults;
}
/**
* Notify about filtered list to ui
* #param constraint text
* #param results filtered result
*/
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
filteredList = (ArrayList<People>) results.values;
notifyDataSetChanged();
}
}
}
And this is PeopleListActivity
**PeopleListActivity**
public class PeopleListActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {
private PeopleListFragment fragment;
private FragmentManager displayFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.argb(255, 180, 110, 60));
}
setContentView(R.layout.activity_people);
Toolbar toolbar = (Toolbar) findViewById(R.id.people_toolbar);
setSupportActionBar(toolbar);
toolbar.setNavigationIcon(R.drawable.ic_back_arrow);
getSupportActionBar().setDisplayShowTitleEnabled(false);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(PeopleListActivity.this, NavigationActivity.class);
startActivity(intent);
}
});
displayFragment = getSupportFragmentManager();
fragment = new PeopleListFragment();
displayFragment.beginTransaction().add(R.id.people_fragment, fragment).commit();
if (savedInstanceState == null) {
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
SearchManager searchManager =(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
// searchView.setIconifiedByDefault(false);
searchView.setSubmitButtonEnabled(true);
searchView.setOnQueryTextListener(this);
return true;
// return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
PeopleAdapter peopleAdapter = (PeopleAdapter) PeopleListFragment.mContactlistView.getAdapter();
peopleAdapter.getFilter().filter(newText);
return true;
}
}
Could anyone help me with this..?
Assign some value to filteredList when you create the Adapter
Example:
public PeopleAdapter(Context applicationContext, int people_list_item, List<People> contactList) {
super(applicationContext, people_list_item, contactList);
filteredList = contactList;
getFilter();
}
filteredList is null when getCount() is called. Instantiate it first or make sure filteredList has some content.
MyFragment
#Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
// Inflate the layout for this fragment
final View layoutSearch = inflater.inflate(R.layout.fragment_search, container, false);
mswipeRefreshLayout=(SwipeRefreshLayout) layoutSearch.findViewById(R.id.searchMoviesRefresh);
mswipeRefreshLayout.setOnRefreshListener(this);
textVolleyError = (TextView) layoutSearch.findViewById(R.id.textVolleyError);
listMovieHits = (RecyclerView) layoutSearch.findViewById(R.id.search_movies);
listMovieHits.setLayoutManager(new LinearLayoutManager(getActivity()));
search=(SearchView) layoutSearch.findViewById(R.id.searchView1);
search.setQueryHint("Start typing to search...");
buttonBarcode = (ImageButton) layoutSearch.findViewById(R.id.imageButton2);
buttonAudio = (ImageButton) layoutSearch.findViewById(R.id.imageButton1);
search.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
}
});search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
L.t(getActivity(), newText);
if (newText.length() > 3) {
listMovieHits.setVisibility(layoutSearch.getVisibility());
searchForMovies m = (searchForMovies) new searchForMovies().execute(newText);
} else {
listMovieHits.setVisibility(layoutSearch.INVISIBLE);
}
return false;
}
});
listMovieHits.setAdapter(mAdapterBoxOffice);
if (savedInstanceState != null) {
mlistMovies = savedInstanceState.getParcelableArrayList(STATE_MOVIES);
} else {
L.t(getActivity(), "executing task from the fragment");
/*new TaskLoadSearchMovies(this).execute();*/
}
/* mAdapterBoxOffice.setMovieList(filteredProductResults);
mAdapterBoxOffice.SetOnclickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
container.getContext().startActivity(new Intent(container.getContext(), Details_Activity.class));
}
});*/
return layoutSearch;
}
public void filterProductArray(String newText){
String sName;
filteredProductResults.clear();
for (int i=0; i<mlistMovies.size(); i++)
{
sName=mlistMovies.get(i).getTitle().toLowerCase();
if (sName.contains(newText.toLowerCase()))
{
filteredProductResults.add(mlistMovies.get(i));
}
}
}
class searchForMovies extends AsyncTask<String, Void, String>
{
Parser parser;
JSONArray listMovies;
String url=new String();
String textSearch;
ProgressDialog progressDialog;
#Override
protected void onPreExecute(){
super.onPreExecute();
listMovies=new JSONArray();
parser =new Parser();
progressDialog=new ProgressDialog(getActivity());
progressDialog.setCancelable(false);
progressDialog.setMessage("Searching....");
progressDialog.getWindow().setGravity(Gravity.CENTER);
progressDialog.show();
}
#Override
protected String doInBackground(String... params) {
url="http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey={MyID}="+params+"limit=30";
String returnMovieResult= getMovieList();
this.textSearch=params[0];
return returnMovieResult;
}
private String getMovieList() {
Movie tempMovie=new Movie();
String mathFound="N";
try{
JSONObject response = Requestor.sendRequestBoxOfficeMovies(requestQueue, url);
ArrayList<Movie> listMovies = Parser.parseMoviesJSON(response);
L.m(String.valueOf(listMovies));
}catch (Exception e){
e.printStackTrace();
return "error";
}
return ("Exception");
}
protected void onPostExecute(String result){
super.onPostExecute(result);
if(result.equalsIgnoreCase("Exception Caught"))
{
Toast.makeText(getActivity(), "Unable to connect to server,please try later", Toast.LENGTH_LONG).show();
progressDialog.dismiss();
}
else
{
//calling this method to filter the search results from productResults and move them to
//filteredProductResults
filterProductArray(textSearch);
listMovieHits.setAdapter(mAdapterBoxOffice);
mAdapterBoxOffice.setFilteredMovies(mlistMovies);
progressDialog.dismiss();
}
}
}
AdapterClass
public class AdapterBoxOffice extends RecyclerView.Adapter<AdapterBoxOffice.ViewHolderBoxOffice> {
private LayoutInflater layoutInflater;
private ArrayList<Movie> mlistMovies = new ArrayList<>();
private VolleySingleton volleySingleton;
private ImageLoader imageLoader;
private DateFormat dateFormat = new SimpleDateFormat("yyy-MM-dd");
private int previousPosition=0;
AdapterView.OnItemClickListener mOnItemClickListener;
public AdapterBoxOffice(Context context) {
layoutInflater = LayoutInflater.from(context);
volleySingleton = VolleySingleton.getsInstance();
imageLoader = volleySingleton.getImageLoader();
}
public void setMovieList(ArrayList<Movie> listMovies) {
this.mlistMovies = listMovies;
notifyDataSetChanged();
}
public void setFilteredMovies(ArrayList<Movie> filteredProductResults){
this.mlistMovies=filteredProductResults;
}
#Override
public ViewHolderBoxOffice onCreateViewHolder(ViewGroup parent, int viewType) {
View view = layoutInflater.inflate(R.layout.custom_movie_box_office, parent, false);
ViewHolderBoxOffice viewHolder = new ViewHolderBoxOffice(view);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolderBoxOffice holder, int position) {
Movie currentMovie = mlistMovies.get(position);
holder.movieTitle.setText(currentMovie.getTitle());
Date movieReleaseDate = currentMovie.getReleaseDateTheater();
if (movieReleaseDate != null) {
String formmattedDate = dateFormat.format(movieReleaseDate);
holder.movieReleaseDate.setText(formmattedDate);
} else {
holder.movieReleaseDate.setText(Constants.NA);
}
int audienceScore=currentMovie.getAudienceScore();
if (audienceScore==-1){
holder.movieAudienceScore.setRating(0.0F);
holder.movieAudienceScore.setAlpha(0.5F);
}
else
{
holder.movieAudienceScore.setRating(currentMovie.getAudienceScore() / 20.0F);
holder.movieAudienceScore.setAlpha(1.0F);
}
if(position>previousPosition)
{
comeagain.materialdesign.anim.AnimationUtils.animate(holder, true);
}else {
comeagain.materialdesign.anim.AnimationUtils.animate(holder, false);
}
previousPosition=position;
String urlThumbnail = currentMovie.getUrlThumbnail();
loadImages(urlThumbnail, holder);
}
private void loadImages(String urlThumbnail, final ViewHolderBoxOffice holder) {
if (urlThumbnail != null) {
imageLoader.get(urlThumbnail, new ImageLoader.ImageListener() {
#Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
holder.movieThumbnail.setImageBitmap(response.getBitmap());
}
#Override
public void onErrorResponse(VolleyError error) {
}
});
}
}
#Override
public int getItemCount() {
return mlistMovies.size();
}
class ViewHolderBoxOffice extends RecyclerView.ViewHolder implements View.OnClickListener {
private ImageView movieThumbnail;
private TextView movieTitle;
private TextView movieReleaseDate;
private RatingBar movieAudienceScore;
public ViewHolderBoxOffice(View itemView) {
super(itemView);
movieThumbnail = (ImageView) itemView.findViewById(R.id.movieThumbnail);
movieTitle = (TextView) itemView.findViewById(R.id.movieTitle);
movieReleaseDate = (TextView) itemView.findViewById(R.id.movieReleaseDate);
movieAudienceScore = (RatingBar) itemView.findViewById(R.id.movieAudienceScore);
}
}
LogCat
01-23 22:00:18.141 19563-19563/comeagain.materialdesign E/AndroidRuntime: FATAL EXCEPTION: main
Process: comeagain.materialdesign, PID: 19563
java.lang.NullPointerException: Attempt to invoke virtual method 'void comeagain.materialdesign.adapters.AdapterBoxOffice.setFilteredMovies(java.util.ArrayList)' on a null object reference
at comeagain.materialdesign.fragments.FragmentSearch$searchForMovies.onPostExecute(FragmentSearch.java:270)
at comeagain.materialdesign.fragments.FragmentSearch$searchForMovies.onPostExecute(FragmentSearch.java:209)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I want to implement search query in Json Api, the problem is that the I am getting a null exception . I do not know why the filteredArray is returning null, I really do not know where is the problem, Please help me solve this issue.
I have recyclerview (in fragment) and fragment with details information to one of the element. All is good, but when my data was saved. I have bad results in my JSON file. All times when i open element of list he add new element inside JSON file, while he must overwrite oneself.
My Activity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start_page_activity);
Log.i("MainActivity", "onCreate");
if(savedInstanceState==null) {
getFragment(new ObjectListFragment());
}
}
public void getFragment(Fragment fragment) {
FragmentManager fm = getSupportFragmentManager();
Fragment mFragment = fm.findFragmentById(R.id.fragment_container);
if (mFragment == null) {
mFragment = fragment;
fm.beginTransaction()
.add(R.id.fragment_container, mFragment)
.commit();
}
if (mFragment != null) {
mFragment = fragment;
fm.beginTransaction().addToBackStack(null)
.replace(R.id.fragment_container, mFragment)
.commit();
}
}
}
My Model:
public class Object {
private static final String JSON_ID = "id";
private static final String JSON_TITLE = "title";
private UUID mId;
private String mTitle;
public Object() {
mId=UUID.randomUUID();
}
public Object(JSONObject json) throws JSONException {
mId = UUID.fromString(json.getString(JSON_ID));
mTitle = json.getString(JSON_TITLE);
}
public JSONObject toJSON()throws JSONException{
JSONObject json = new JSONObject();
json.put(JSON_ID, mId.toString());
json.put(JSON_TITLE, mTitle);
return json;
}
public UUID getId() {
return mId;
}
public String getTitle() {
return mTitle;
}
public void setTitle(String title) {
mTitle = title;
}
#Override
public String toString() {
return mTitle;
}
}
ObjectLab:
public class ObjectLab {
private static final String TAG = "ObjectLab";
private static final String FILENAME = "reminder.json";
private ObjectJSON mSerializer;
private ArrayList<Object> mObjects;
private static ObjectLab sObjectLab;
private Context mContext;
private ObjectLab(Context context){
mContext = context;
mSerializer = new ObjectJSON(mContext, FILENAME);
try {
mObjects = mSerializer.loadReminders();
} catch (Exception e) {
mObjects = new ArrayList<Object>();
Log.e(TAG, "Error loading crimes: ", e);
}
}
public static ObjectLab get(Context c){
if(sObjectLab == null){
sObjectLab = new ObjectLab(c.getApplicationContext());
}
return sObjectLab;
}
public ArrayList<Object> getObjects(){
return mObjects;
}
public Object getReminder(UUID id){
for(Object c : mObjects){
if(c.getId().equals(id))
return c;
}
return null;
}
public void addReminder(Object c){
mObjects.add(0,c);
}
public void deleteReminder(Object c){
mObjects.remove(c);
}
public boolean saveReminders(){
try{
mSerializer.saveReminders(mObjects);
Log.d(TAG, "reminders saved to file");
return true;
}catch (Exception e){
Log.e(TAG, "Error saving crimes: ", e);
return false;
}
}
ObjectJSON:
public class ObjectJSON {
private Context mContext;
private String mFilename;
public ObjectJSON(Context context, String filename) {
mContext = context;
mFilename = filename;
}
public void saveReminders(ArrayList<Object> objects) throws JSONException, IOException {
Log.i("Save","saveReminders");
JSONArray array = new JSONArray();
for (Object f : objects)
array.put(f.toJSON());
Writer writer = null;
try {
OutputStream out = mContext.openFileOutput(mFilename, Context.MODE_APPEND);
writer = new OutputStreamWriter(out);
writer.write(array.toString());
} finally {
if (writer != null)
writer.close();
}
}
public ArrayList<Object> loadReminders() throws IOException, JSONException {
Log.i("Save","loadReminders");
ArrayList<Object> objects = new ArrayList<Object>();
BufferedReader reader = null;
try {
InputStream in = mContext.openFileInput(mFilename);
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder jsonString = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
jsonString.append(line);
}
JSONArray array = (JSONArray) new JSONTokener(jsonString.toString())
.nextValue();
for (int i = 0; i < array.length(); i++) {
objects.add(new Object(array.getJSONObject(i)));
}
} catch (FileNotFoundException e) {
//when 0
} finally {
if (reader != null)
reader.close();
}
return objects;
}
ObjectListFragment:
public class ObjectListFragment extends Fragment {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerAdapter mAdapter;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.reminder_activity, container, false);
Log.i("ObjectListFragment", "onCreateView");
final ArrayList<Object> mData = ObjectLab.get(getActivity()).getObjects();
getActivity().setTitle("Object");
mRecyclerView = (RecyclerView)v. findViewById(R.id.my_recycler_view);
//registerForContextMenu(mRecyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new RecyclerAdapter(mData);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(v.getContext(), new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Log.i("ObjectListFragment", "onItemClick");
Object f = mData.get(position);
FragmentManager fm = getFragmentManager();
Fragment mFragment = fm.findFragmentById(R.id.fragment_container);
Bundle bundle = new Bundle();
bundle.putSerializable(ObjectFragment.EXTRA_REMINDER_ID, f.getId());
if (mFragment != null) {
mFragment = new ObjectFragment();
mFragment.setArguments(bundle);
fm.beginTransaction().addToBackStack(null)
.replace(R.id.fragment_container, mFragment)
.commit();
}
}
}));
return v;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_main, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
Log.d("Testing", "ID == " + id);
switch (id) {
case R.id.action_settings: {
Log.d("onOptionsItemSelected", " SETTings");
Object f = new Object();
ObjectLab.get(getActivity()).addReminder(f);
FragmentManager fm = getFragmentManager();
Fragment mFragment = fm.findFragmentById(R.id.fragment_container);
Bundle bundle = new Bundle();
bundle.putSerializable(ObjectFragment.EXTRA_REMINDER_ID, f.getId());
if (mFragment != null) {
mFragment = new ObjectFragment();
mFragment.setArguments(bundle);
fm.beginTransaction().addToBackStack(null)
.replace(R.id.fragment_container, mFragment)
.commit();
}
return true;
}
}
return super.onOptionsItemSelected(item);
}
}
RecyclerAdapter:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
ArrayList<Object> mData;
public RecyclerAdapter(ArrayList<Object> objects) {
mData = objects;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.reminder_item, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTitleTextView.setText(mData.get(position).getTitle());
}
#Override
public int getItemCount() {
return mData.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private TextView mTitleTextView;
public ViewHolder(View itemView) {
super(itemView);
mTitleTextView = (TextView) itemView.findViewById(R.id.forget_list_titleTextView);
}
}
RecyclerItemClickListener:
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
#Override public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
#Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildLayoutPosition(childView));
return true;
}
return false;
}
#Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
and last ObjectFragmet
public class ObjectFragment extends Fragment{
public static final String EXTRA_REMINDER_ID = "id";
private Object mObject;
public static ObjectFragment newInstance(UUID crimeId) {
Log.i("ObjectFragment", "newInstance");
Bundle args = new Bundle();
args.putSerializable(EXTRA_REMINDER_ID, crimeId);
ObjectFragment fragment = new ObjectFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UUID uuid = (UUID) getArguments().getSerializable(EXTRA_REMINDER_ID);
Log.i("ObjectFragment", " "+uuid);
mObject = ObjectLab.get(getContext()).getReminder(uuid);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.remind_act, container, false);
EditText editText = (EditText)v.findViewById(R.id.editText1);
editText.setText(mObject.getTitle());
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
mObject.setTitle(charSequence.toString());
}
#Override
public void afterTextChanged(Editable editable) {
}
});
return v;
}
#Override
public void onPause() {
super.onPause();
Log.i("ObjectFragment", "onPause");
ObjectLab.get(getActivity()).saveReminders();
}
Links to the project(Android Studio).
Where my problem is that I do not. With pleasure hear all your comments and advice on the topic as well as that off-topic.
Your help will not forsake unattended.
When opening the OutputStream for writing into the file, you're using the Context.MODE_APPEND flag, which is causing the write operation to append and not overwrite as you intended, change it to:
OutputStream out = mContext.openFileOutput(mFilename, 0);
Also, there was no need to mention the RecyclerView at all, since it has nothing to do with the problem at hand.
I am using this Tutorial and its sourcecodes to make listview in android. I had implemented using this tutorial but during updating the setListAdapter i cannot update the listview dynamically.
I have gone through many stackoverflow questions and they are giving adapter.notifyDataSetChanged() as the solution. But i am unable to implement it in AsyncTask.
ItemListFragment.java
public class ItemListFragment extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = super.onCreateView(inflater, container, savedInstanceState);
setListAdapter(new ItemAdapter(getActivity(), setArray(getActivity())));
return v;
}
public ArrayList<Item> setArray(Context context)
{
ArrayList<Item> items = new ArrayList<Item>();
Realm realm = Realm.getInstance(context);
RealmResults<Books> bs = realm.where(Books.class).findAll();
for (int i = 0; i < bs.size(); i++) {
Bitmap url = BitmapFactory.decodeFile(bs.get(i).getCover());
String title = bs.get(i).getName();
String description = bs.get(i).getAuthor();
Item item = new Item(url, title, description);
items.add(item);
}
realm.close();
return items;
}
}
ItemAdapter.java
public class ItemAdapter extends ArrayAdapter<Item> {
public ItemAdapter(Context context, List<Item> items) {
super(context, 0, items);
}
public View getView(int position, View convertView, ViewGroup parent)
{
ItemView itemView = (ItemView) convertView;
if (null == itemView)
{
itemView = ItemView.inflate(parent);
}
itemView.setItem(getItem(position));
return itemView;
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
if (BuildConfig.DEBUG)
ViewServer.get(this).addWindow(this);
}
#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;
}
else if (id == R.id.update) {
Update update = new Update(getApplicationContext(), MainActivity.this);
update.execute();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (BuildConfig.DEBUG)
ViewServer.get(this).removeWindow(this);
}
#Override
protected void onResume() {
super.onResume();
if (BuildConfig.DEBUG)
ViewServer.get(this).setFocusedWindow(this);
}
}
Update.java
public class Update extends AsyncTask<Void,Void,Void>{
private Context context;
public Activity activity;
public Update(Context context, Activity activity)
{
this.context = context;
this.activity = activity;
}
#Override
protected Void doInBackground(Void... params) {
ServerAddress = context.getString(R.string.ServerAddress);
StringExtras = context.getString(R.string.CheckBook);
Realm realm = null;
try {
URL url = new URL(ServerAddress + StringExtras);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setRequestProperty("Content-length", "0");
httpURLConnection.setUseCaches(false);
httpURLConnection.setAllowUserInteraction(false);
httpURLConnection.setConnectTimeout(1000);
httpURLConnection.setReadTimeout(1000);
httpURLConnection.connect();
int responseCode = httpURLConnection.getResponseCode();
Log.i("Response Code",responseCode+"");
BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
String InputLine;
StringBuilder response = new StringBuilder();
while ((InputLine = br.readLine()) != null)
{
response.append(InputLine);
}
br.close();
httpURLConnection.disconnect();
Log.i("Response Data", response.toString());
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
JSONArray array = new JSONArray(response.toString());
//booksList = Arrays.asList(books);
//JSONArray jsonArray = object.getJSONArray("cover");
realm = Realm.getInstance(context);
for (int i=0; i< array.length(); i++ ) {
JSONObject object = array.getJSONObject(i);
Books books = gson.fromJson(object.toString(), Books.class);
Publish(books, realm);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (realm != null){
realm.close();
}
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//i want to call the setarray that contains my database data which has been updated on `doinbackground` and update the listview accordingly.
//The below codes are just the codes that i have tried but what should i do to update the listview.
activity.runOnUiThread(new Runnable() {
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
public void run() {
ItemListFragment activity1 = new ItemListFragment();
ArrayList<Item> arrayList = activity1.setArray(context);
List<Item> list = new ArrayList<Item>();
int i = 0;
for (Item item : arrayList)
{
list.add(arrayList.get(i));
i++;
}
activity1.arrayAdapter.addAll(list);
activity1.arrayAdapter.notifyDataSetChanged();
}
});
}
I am trying to update the listview from postexcution. So, how can i update the view through it.
Error From AsyncTask
just incase you need but it's not the problem
8-30 16:31:47.976 1167-1167/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at np.com.thefourthgeneration.Update$1.run(Update.java:124)
at android.app.Activity.runOnUiThread(Activity.java:4673)
at np.com.thefourthgeneration.Update.onPostExecute(Update.java:108)
at np.com.thefourthgeneration.Update.onPostExecute(Update.java:34)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
layout/activity_list
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
layout/list_fragment
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
MainActivity
public class MainActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
FragmentManager fm = getFragmentManager();
itemListFragment = (ItemListFragment) fm.findFragmentByTag(ItemListFragment.class.getSimpleName());
if (itemListFragment == null) {
itemListFragment = new ItemListFragment();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.content_frame, itemListFragment, ItemListFragment.class.getSimpleName());
fragmentTransaction.commit();
}
if (BuildConfig.DEBUG) {
ViewServer.get(this).addWindow(this);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (BuildConfig.DEBUG) {
ViewServer.get(this).removeWindow(this);
}
}
#Override
protected void onResume() {
super.onResume();
if (BuildConfig.DEBUG) {
ViewServer.get(this).setFocusedWindow(this);
}
}
}
ItemListFragment
public class ItemListFragment extends Fragment
{
private ListView listView;
private ItemAdapter itemAdapter;
private ArrayList<Item> itemArrayList = new ArrayList<>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.list_fragment, container, false);
itemAdapter = new ItemAdapter(getActivity(), itemArrayList);
listView = (ListView) view.findViewById(R.id.listView);
listView.setAdapter(itemAdapter);
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case R.id.update:
new Update(getActivity()).execute();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public class Update extends AsyncTask<Void, Void, Void>
{
private Context context;
public Update(Context context) {
this.context = context;
}
#Override
protected Void doInBackground(Void... params) {
ServerAddress = context.getString(R.string.ServerAddress);
StringExtras = context.getString(R.string.CheckBook);
Realm realm = null;
try {
URL url = new URL(ServerAddress + StringExtras);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setRequestProperty("Content-length", "0");
httpURLConnection.setUseCaches(false);
httpURLConnection.setAllowUserInteraction(false);
httpURLConnection.setConnectTimeout(1000);
httpURLConnection.setReadTimeout(1000);
httpURLConnection.connect();
int responseCode = httpURLConnection.getResponseCode();
Log.i("Response Code", responseCode + "");
BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
String InputLine;
StringBuilder response = new StringBuilder();
while ((InputLine = br.readLine()) != null) {
response.append(InputLine);
}
br.close();
httpURLConnection.disconnect();
Log.i("Response Data", response.toString());
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
JSONArray array = new JSONArray(response.toString());
//booksList = Arrays.asList(books);
//JSONArray jsonArray = object.getJSONArray("cover");
realm = Realm.getInstance(context);
for (int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
Books books = gson.fromJson(object.toString(), Books.class);
Publish(books, realm);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (realm != null) {
realm.close();
}
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
itemArrayList.clear();
itemArrayList.addAll(getArray(context));
itemAdapter.notifyDataSetChanged();
}
public ArrayList<Item> getArray(Context context) {
ArrayList<Item> items = new ArrayList<Item>();
Realm realm = Realm.getInstance(context);
RealmResults<Books> bs = realm.where(Books.class).findAll();
for (int i = 0; i < bs.size(); i++) {
Bitmap url = BitmapFactory.decodeFile(bs.get(i).getCover());
String title = bs.get(i).getName();
String description = bs.get(i).getAuthor();
Item item = new Item(url, title, description);
items.add(item);
}
realm.close();
return items;
}
}
public class ItemAdapter extends ArrayAdapter<Item>
{
public ItemAdapter(Context context, List<Item> items) {
super(context, 0, items);
}
public View getView(int position, View convertView, ViewGroup parent) {
ItemView itemView = (ItemView) convertView;
if (null == itemView) {
itemView = ItemView.inflate(parent);
}
itemView.setItem(getItem(position));
return itemView;
}
}
}
Its not the 100% work code, because i dont fully understand all structures (like Realm) and I dont test it, but its the main idea.