Reputation: 213
In my android app, I have one Activity and more java class which is not an activity. So there is a get method in this other java class, which returns an Object. This method starts a new thread to gets the data and attaches it with the object
Now I am calling this get method in my Activity to get that object. I am doing something like this -
mNewsList = new ArrayList<NewsContentManager.NewsPojo>();
mNewsList = manager.getNewsList();
and the method is this -
public ArrayList<NewsPojo> getNewsList() {
Log.v("TAG", ""+newsList);
if(newsList == null)
{
Thread t = new Thread(){
public void run(){
Log.v("TAG", "Inside run");
np1 = new NewsPojo();
np1.setTitle("A");
np1.setDescription("dhghfdklsa");
np2 = new NewsPojo();
np2.setTitle("B");
np2.setDescription("dhghfdklsa");
np3 = new NewsPojo();
np3.setTitle("c");
np3.setDescription("dhghfdklsa");
newsList = new ArrayList<NewsPojo>();
Log.v("in run",""+newsList);
newsList.add(np1);
newsList.add(np2);
newsList.add(np3);
Log.v("in run",""+newsList.size());
setNewsList(newsList);
handler.sendEmptyMessage(0);
}// end of run
};// end of thread
t.start();
}//end of if
return newsList;
}
But I am getting nullPointer Exception in my Activity. If I remove Thread from this method then it works correctly. What should I do ?
Thanks
Upvotes: 0
Views: 246
Reputation: 77
If you have to kill the Activity before the AsyncTask finish the job , you can recover the it in another Activity using:
class code: private class DownloadImageTask extends AsyncTask { .... }
instance of the class:
dtdodo = new DownloadImageTask( this, p , codacaovalue);
dtdodo.execute("wwwkjhdijdh");
Kill the Activity (event like rotate the screen).
recovering the AsyncTask :
onCreate(){
Object retained = getLastNonConfigurationInstance();
if ( retained instanceof DownloadImageTask ) {
dtdodo = (DownloadImageTask) retained;
dtdodo.setActivity(this);
} else {
dtdodo = new DownloadImageTask(this , 1 , codacaovalue);
dtdodo.execute();
}
}
I found this in a blog of a anonymous guy, I am just sharing.
Upvotes: 0
Reputation: 114757
The method will always return null
, because newsList
gets initialized after you return it. So mNewsList
will be null
and will not be updated by the thread (which will update newsList
but not mNewsList
).
For testing/demonstration: add a Thread.sleep(500)
right before your return statement - then it works as expected.
Here's a quick solution to your problem:
public ArrayList<NewsPojo> getNewsList() {
Log.v("TAG", ""+newsList);
if(newsList == null)
{
newsList = new ArrayList<NewsPojo>(); // <-- new statement!
Thread t = new Thread(){
// same lines of code EXCEPT "newsList = new ArrayList<NewsPojo>();" !!
};
t.start();
}
return newsList;
}
But keep in mind - the newList will be created in time but populated later, in parallel to the main thread. When you look at mNewsList
, then it may show an empty or partially filled list. That's the usual behaviour if you do things asynchronously. If you don't want that: don't use a thread to create/populate the list.
Upvotes: 1
Reputation: 1778
You get NullPointerException, because you initialise newsList in different thread:
newsList = new ArrayList<NewsPojo>();
But this code is executed probably AFTER you return newsList, that equals null
if(newsList == null)
{
Thread t = new Thread(){
....
};// end of thread
t.start(); // << this only starts thread and continues executing
}//end of if
return newsList; // this is executed before newsList is initialized in t.run()
Upvotes: 0
Reputation: 18107
Additionally to my comment to your question.
First, try to avoid using Threads in such a way. Use AsyncTask instead. On it's preExecute show some dialog to the user, that you are loading a list, on it's doInBackground put your logic that will return new list, and in postExecute just dismiss the dialog and proceed.
Upvotes: 0
Reputation: 2073
Because your thread finishes its work later than expected. you should synchronize the thread and ui thread.
Have a look at AsyncTask of Android.
Upvotes: 3