Reputation: 634
I got the following problem and hope someone could give me a hint.
I have an activity that executes an AsyncTask< String, Void, ArrayList<Custom object >>
.
In the doInBackground()
function, I set up a new ArrayList
of custom objects which is also the return value.
In the onPostExecute()
method that ArrayList
is used in a newly created ArrayAdapter<Custom object>
, which is also set to a ListView
with lv.setAdapter(adapter).
so far so good!
now the thing is: back in the MainActivity I will need that adapter again, cause I wanna add new items to it by calling adapter.add(items).
for now I had the AsyncTask
as an inner class of my MainActivity and could use the same ListView
& the same ArrayAdapter,
that worked very well!
but because I have another class which needs to execute that AsyncTask
too, I changed that inner class AsyncTask
to a standalone .java
file (CustomAsyncTask.java
)
-> now when I try to add new items to the ArrayAdapter
it throws a NullPointerException!
of course that is, cause the ArrayAdapter
belongs to the AsyncTask
and is created there
so I tried to give the ListView
and the ArrayAdapter
from the MainActivity as a parameter for the CustomAsyncTask
constructor to use it in there
but that did not work, the ArrayAdapter
in MainActivity is always null causing the Exception
any ideas how to solve that? I would really appreciate it.
here the code of the MainActivity.java:
// global variables
ArrayAdapter<Custom object> arrayadapter;
ListView listview;
ProgressBar progressbar;
...
protected void myMethod() {
CustomAsyncTask hTask = new CustomAsyncTask(this, listview, progressbar, arrayadapter);
hTaskPlaylist.execute(String sth);
}
...
protected void anotherMethod() {
arrayadapter.add(item);
}
and the code of CustomAsyncTask.java:
package com.mypackage.test;
import java.util.ArrayList;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
public class CustomAsyncTask extends AsyncTask<String, Void, ArrayList<Custom object>>{
Context context;
ListView listview;
ProgressBar progressbar;
ArrayAdapter<Custom object> arrayadapter;
public CustomAsyncTask(Context con, ListView lv, ProgressBar pb, ArrayAdapter<Custom object> aa) {
this.context = con;
this.listview = lv;
this.progressbar = pb;
this.arrayadapter = aa;
}
@Override
protected void onPreExecute() {
listview.setVisibility(ListView.GONE);
progressbar.setVisibility(ProgressBar.VISIBLE);
super.onPreExecute();
}
@Override
protected ArrayList<Custom object> doInBackground(String... params) {
ArrayList<Custom object> list = new ArrayList<Custom object>();
... doing something and populating list
return list;
}
@Override
protected void onPostExecute(ArrayList<Custom object> list) {
super.onPostExecute(list);
arrayadapter = new ArrayAdapter<Custom object>(context, android.R.layout.simple_list_item_1, list);
listview.setAdapter(arrayadapter);
progressbar.setVisibility(ProgressBar.GONE);
listview.setVisibility(ListView.VISIBLE);
}
}
}
Upvotes: 1
Views: 2711
Reputation: 634
Now I tried that and pass the MainActivity
as a parameter instead of the Context
,
here is what I changed:
public class CustomAsyncTask extends AsyncTask<String, Void, ArrayList<Custom object>>{
**MainActivity activity**;
ListView listview;
ProgressBar progressbar;
ArrayAdapter<Custom object> arrayadapter;
public CustomAsyncTask(**MainActivity act**, ListView lv, ProgressBar pb, ArrayAdapter<Custom object> aa) {
**this.activity = act;**
this.listview = lv;
this.progressbar = pb;
this.arrayadapter = aa;
}
...
@Override
protected void onPostExecute(ArrayList<Custom object> list) {
super.onPostExecute(list);
arrayadapter = new ArrayAdapter<Custom object>(context, android.R.layout.simple_list_item_1, list);
listview.setAdapter(arrayadapter);
**activity.arrayadapter = arrayadapter;**
progressbar.setVisibility(ProgressBar.GONE);
listview.setVisibility(ListView.VISIBLE);
}
}
Yeah, it worked!
Thank you Joel,
but I'm still wondering why I can pass listview
from MainActivity
, call a function on that listview in AsyncTask
and normally work with that listview back in MainActivity
, any ideas?
And another question: is it right, that the only difference in passing an Activity
object instead of a Context
object, is you're having access to the available variables and methods you defined in your Activity
?
Upvotes: 0
Reputation: 4772
You could make your ArrayAdapter static.. Then anytime you want to access it you can simply say CustomAsyncTask.arrayadapter.add(items); You are also allowed to add your own functions to your custom asynctask class. You could create something like public ArrayAdapter<> getAdapter(). But careful, you are going to have multiple threads accessing/changing that object regardless, so it would be a good idea to synchronize access.
You could try something like this...
ArrayAdapter globalAdapter;
globalAdapter = new CustomAsyncTask().execute(/*your parameters here*/).get();
Upvotes: 1