Reputation: 3899
I am calling an AsyncTask
from my activity to download a string from the web. When the string has been downloaded, I want to pass the string into my activity so I can parse it and then populate the ListView
.
I created a method in my activity to be called in onPostExecute()
and this is what the code is:
@Override
protected void onPostExecute(String res) {
IndexPicker index = new IndexPicker();
index.onAsyncFinish(res);
}
This is my onASyncFinish()
method:
public void onAsyncFinish(String json) {
ArrayList<Index> arrayList = parseJSON(json);
populateListView(arrayList);
}
}
In the populateListView
method is where the IllegalStateException, when the constructor for the ArrayAdapter is called.
public IndexItemAdapter(Context context, int layoutResourceId,
ArrayList<Index> data) {
super(context, layoutResourceId, data); // This line.
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
This is the logcat:
E/AndroidRuntime(821): FATAL EXCEPTION: main
E/AndroidRuntime(821): java.lang.IllegalStateException: System services not available to Activities before onCreate()
E/AndroidRuntime(821): at android.app.Activity.getSystemService(Activity.java:4463)
E/AndroidRuntime(821): at android.widget.ArrayAdapter.init(ArrayAdapter.java:310)
E/AndroidRuntime(821): at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:153)
E/AndroidRuntime(821): at com.test.exampleapp.index.IndexItemAdapter.<init>(IndexItemAdapter.java:23)
E/AndroidRuntime(821): at com.test.exampleapp.activity.IndexPicker.populateListView(IndexPicker.java:39)
E/AndroidRuntime(821): at com.test.exampleapp.activity.IndexPicker.onAsyncFinish(IndexPicker.java:56)
E/AndroidRuntime(821): at com.test.exampleapp.async.DownloadIndexJSON.onPostExecute(DownloadIndexJSON.java:45)
E/AndroidRuntime(821): at com.test.exampleapp.async.DownloadIndexJSON.onPostExecute(DownloadIndexJSON.java:1)
E/AndroidRuntime(821): at android.os.AsyncTask.finish(AsyncTask.java:631)
E/AndroidRuntime(821): at android.os.AsyncTask.access$600(AsyncTask.java:177)
E/AndroidRuntime(821): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
E/AndroidRuntime(821): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(821): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(821): at android.app.ActivityThread.main(ActivityThread.java:5039)
E/AndroidRuntime(821): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(821): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(821): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
E/AndroidRuntime(821): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime(821): at dalvik.system.NativeStart.main(Native Method)
After researching, apparently the problem is the way I am calling the onASyncFinish method, using IndexPicker index = new IndexPicker();
. I believe this is correct as when I tried doing the networking on the main thread as a test, the listview would populate correctly.
So my question is, what would be the best way for me to fix this so I can pass the result of my ASyncTask to the activity and then populate my list view.
Upvotes: 0
Views: 309
Reputation: 6201
Here two possible solution:
One :: Send you Listview Reference to the ASyncTask and bind data to listview when ASyncTask is finish.
Two:: you want to bind data in listview in activity then first check the ASyncTask is finish is work then bind data. To take data from ASyncTask , you need create a method in ASyncTask class call it when it finish , this method return type is return your data.
But I think the second method is not good because you need run one thread to continue check the ASyncTask is finish.
Thanks
Upvotes: 0
Reputation: 87064
I'm assuming that IndexPicker
is your Activity
, in which case you're doing a really bad thing instantiating it(as it will not have a valid Context
(exactly what the exception is telling you)). Activities shouldn't be instantiated manually, they are created and handled by the Android system.
Instead, to do what you want, you should pass a reference to the Activity
from where you start that AsyncTask
(in the AsyncTask
's constructor) and use that reference to call onAsyncFinish
in the onPostExecute
callback.
Upvotes: 1