Reputation: 744
I have this in my onCreate
method:
String[] myStringArray = {"a","b","c","a","b","c","a","b","c","a","b","c","a","b","c","a","b","c"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_top_jokes);
new loadJson().execute();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, myStringArray);
ListView listView = (ListView) findViewById(R.id.topJokesList);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(),
((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}
});
}
The above code populates a listView with the content of myStringArray
, for now everything is ok. The problem comes when I call new loadJson().execute();
it executes fine and here is the method's code:
public class loadJson extends AsyncTask<Void, Integer, String>{
@Override
protected String doInBackground(Void... params) {
URL u;
StringBuffer buffer = new StringBuffer();
try {
u = new URL("https://website.com/content/showContent.php");
URLConnection conn = u.openConnection();
BufferedReader in = new BufferedReader(
new InputStreamReader(
conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
buffer.append(inputLine);
in.close();
}catch(Exception e){
e.printStackTrace();
}
return buffer.toString();
}
protected void onPostExecute(String buffer) {
JSONArray jsonArray = new JSONArray();
try {
jsonArray = new JSONArray(buffer);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("JSONarray: " + jsonArray);
String[] newArray = null;
for (int i = 0; i < jsonArray.length(); i++) {
try {
newArray[i] = jsonArray.getJSONObject(i).toString();
} catch (JSONException e) {
e.printStackTrace();
}
}
myStringArray = newArray;
}
}
As you can see I'm updating the hardcoded content of myStringArray
with the new values fetched into newArray
. Now I'm unable to see the new content. I know it's there, but how can I tell to the current activity: "Hey, I updated your array, please show it!" ?
I know that I'm missing something really small, but as a beginner, I'm not able to spot it.
Upvotes: 4
Views: 4001
Reputation: 6702
Just add a reference of Adapter into your AsyncTask:
public class loadJson extends AsyncTask<Void, Integer, String>{
ArrayAdapter<String> adapter;
public loadJson(ArrayAdapter<String> adapter) {
this.adapter = adapter;
}
//...
protected void onPostExecute(String buffer) {
if (this.adapter != null) {
// update adapter
}
}
}
Then
new loadJson(adapter).execute();
And now your can update your Adapter
in onPostExecute
Upvotes: 0
Reputation: 9077
I found the answer to this question because I was searching for the answer myself. There are a few close answers here, but they leave out pieces which will never get you to the answer.
First of all add two member variables to your AsyncTask class:
private ListView listView;
private Activity activity;
Next, add a constructor to you AsyncTask class which takes an Activity:
public loadJson(Activity activity) {
this.activity = activity;
}
Now, when you new up your AsyncTask class and call execute() you will add the reference to the Activity which called it (the this value passed in when you construct your AsyncTask class).
new loadJson(this).execute(param);
Finally, back in your AsyncTask you will write the code for your postExecute() which looks like the following:
protected void onPostExecute(String output) {
listView = (ListView) activity.findViewById(R.id.targetListView);
ArrayAdapter<String> adapter = (ArrayAdapter<String>)listView.getAdapter();
adapter.add(output);
adapter.notifyDataSetChanged();
}
You have to have a reference to your Activity so you can call the findViewById. Note that the targetListView is the id of your ListView which is on your original Activity.
We've sent that Activity into the AsyncTask's constructor so it is available. Now you can get the Adapter and add your value to you and call notifyDataSetChanged() so it will update on your UI.
I'm using this code in my solution and it works great.
Upvotes: 3
Reputation: 1401
Put the "loadJson" class as a subclass of your ListActivity class (or Activity or whatever activity you use)
Upvotes: 0
Reputation: 19695
you can add your adapter in the asynctask constructor :
In your activity :
LoadJson lj = new Json(adapter);
lj.execute();
You can declare in LoadJson:
private ArrayAdapter<String> mAdapter;
In the constructor, you get the adapter from activity :
public LoadJson(ArrayAdapter<String> adapter){
mAdapter = adapter;
}
So In your postExecute, you can update the adapter. Hope it helps!
Upvotes: 0
Reputation: 658
protected void onPostExecute(String buffer) {
JSONArray jsonArray = new JSONArray();
try {
jsonArray = new JSONArray(buffer);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("JSONarray: " + jsonArray);
String[] newArray = null;
for (int i = 0; i < jsonArray.length(); i++) {
try {
newArray[i] = jsonArray.getJSONObject(i).toString();
} catch (JSONException e) {
e.printStackTrace();
}
}
myStringArray = newArray;
}
In your above code you are using some peace of code which is actually reside in worker thread(doInBackgroud()) method so cut this code and paste into doInBackgound method. then keep this code in onPostExecute method and declare listview and arrayadapter before oncreate method i.e., Global
listView = (ListView) findViewById(R.id.topJokesList);
listView.getAdapter().notifyDataSetChanged();
I hope this will help you...
Upvotes: 2
Reputation: 113
inside your onPostExecute you can try following :
ListView listView = (ListView) findViewById(R.id.topJokesList);
listView.getAdapter().notifyDataSetChanged();
Upvotes: 2
Reputation: 49986
You can switch from array to ArrayList and call adapter.notifyDataSetChanged, after updating array list content (but dont create new ArrayList instance, update must be on the same reference as was provided to ArrayAdapter).
Or repeat following code (from onCreate) in your AsyncTask.onPostExecute:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, newArray);
listView.setAdapter(adapter);
Upvotes: 1
Reputation: 4712
You switched the reference of the array, what you should do is to use clear
and addAll
on the adapter instance (pass the adapter instance to your AsyncTask to access it).
Upvotes: 2
Reputation: 77
You need to: A. Use the Strings.xml file B. Change the string from one to another - e.g.
<string name="example1">hi</string>
<string name="example2">hello</string>
in the strings.xml file and then in the Main class:
label.setText("@string/example2");
when the string is example1. If this didn't help, I don't know what will...
Upvotes: 0