Reputation: 870
So many hours trying to figure this out, I have read so many questions, forums, answers.. but it still will not update the UI.
My end goal is to take a search term from user, and send a httprequest to PHP scrip that replies with JSON. This works fine so I will not delve into it.
My problem is then updating the UI after this is done. I can get the HTTP results, but for now, I am just trying to update the UI with a basic string before implementing the big changes such as buttons with listeners etc with all the results. For now, just simple String addition to the UI.
The onPreExecute() adds a string to the UI and this works fine somehow, as implemented below.
The problem is in onPostExecute.. like I said, for now, just a String, to test (it will be a list or something eventually). It doesn't work at all, always throwing exception.
public class DisplaySearchActivity extends ListActivity {
ArrayList<String> listItems=new ArrayList<String>();
ArrayAdapter<String> adapter = null;
private class updateUI extends AsyncTask<String, Void, String>{
@Override
protected void onPreExecute() {
listItems.add("Retrieving Results...");
// This actually works just like that
}
@Override
protected String doInBackground(String... message) {
final List<HashMap<String,String>> blist = httpSearch.search(message[0]);
return "It has done";
}
@Override
protected void onPostExecute(String b){
Log.v("ok", "shane - "+ b);
listItems.add("Business: "+ b);
adapter.notifyDataSetChanged();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_search);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems);
setListAdapter(adapter);
// final String message = getIntent().getStringExtra("input");
final String message = "third+level";
new updateUI().execute(message);
} // end onCreate
}
Here is the exception
03-15 13:38:41.190: V/ok(15732): shane - It has done
03-15 13:38:41.190: D/AndroidRuntime(15732): Shutting down VM
03-15 13:38:41.190: W/dalvikvm(15732): threadid=1: thread exiting with uncaught exception (group=0x4142a2a0)
03-15 13:38:41.200: E/AndroidRuntime(15732): FATAL EXCEPTION: main
03-15 13:38:41.200: E/AndroidRuntime(15732): java.lang.NullPointerException
03-15 13:38:41.200: E/AndroidRuntime(15732): at ie.whereis.DisplaySearchActivity$updateUI.onPostExecute(DisplaySearchActivity.java:34)
03-15 13:38:41.200: E/AndroidRuntime(15732): at ie.whereis.DisplaySearchActivity$updateUI.onPostExecute(DisplaySearchActivity.java:1)
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.os.AsyncTask.finish(AsyncTask.java:631)
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.os.AsyncTask.access$600(AsyncTask.java:177)
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.os.Handler.dispatchMessage(Handler.java:99)
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.os.Looper.loop(Looper.java:137)
03-15 13:38:41.200: E/AndroidRuntime(15732): at android.app.ActivityThread.main(ActivityThread.java:4898)
03-15 13:38:41.200: E/AndroidRuntime(15732): at java.lang.reflect.Method.invokeNative(Native Method)
03-15 13:38:41.200: E/AndroidRuntime(15732): at java.lang.reflect.Method.invoke(Method.java:511)
03-15 13:38:41.200: E/AndroidRuntime(15732): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
03-15 13:38:41.200: E/AndroidRuntime(15732): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
03-15 13:38:41.200: E/AndroidRuntime(15732): at dalvik.system.NativeStart.main(Native Method)
I think it is being thrown by the line:
adapter.notifyDataSetChanged();
But I just don't really understand what the adapter does, even after much reading. I don't know why the
listItems.add("Retrieving Results...");
in pre Execute works :S but the one in post does not.
Any help is so greatly appreciated.
Thank you, I have commented the solution. Apologies for not being able to deal out up votes. <15 karma
Upvotes: 1
Views: 3990
Reputation: 8242
your adapter is null . the one you set to list is bounded till oncreate() only . don't define again inside oncreate() . simply assing by
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems);
Upvotes: 1
Reputation: 6159
Firsty of all, why do you have your adapter declared as final? It looks like you are trying to modify the view when the activity is not visible. You should instantiate the asynctask to a member variable, and stop it in the onStop method of your Activity: myAsyncTask.cancel(true);
Upvotes: 0
Reputation: 23952
You are hiding instance field adapter
in onCreate
method.
Instead of
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems);
use
this.adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems);
Upvotes: 1
Reputation: 2023
IN your Oncreate replace
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems);
with
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,listItems);
remove the final ArrayAdapter
Upvotes: 1
Reputation: 15973
When you call adapter.notifyDataSetChanged();
the adapter will use the old data, you need to repass the modified list data before calling adapter.notifyDataSetChanged();
Upvotes: 0
Reputation: 132972
use
DisplaySearchActivity.this.adapter.notifyDataSetChanged();
instead of
adapter.notifyDataSetChanged();
to access adapter instance from onPostExecute
method of updateUI
class because you have declared adapter=null
Upvotes: 1