I'm making a basic news reader app using hacker news API. I'm successfully able to get the titles and the url's of the news articles as JSON objects and add them to their respective arraylists as strings, but I'm unable to display the titles on the list view. I plan to add a webview later, but I can't really do that without the list view displaying the titles. Don't really know what's going on.
Here's the code
public class MainActivity extends AppCompatActivity {
ListView listView;
ArrayList<String> titles;
ArrayList<String> siteUrls;
ArrayAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
titles = new ArrayList<>();
siteUrls = new ArrayList<>();
listView = (ListView) findViewById(R.id.view);
DownloadAsyncTask download = new DownloadAsyncTask();
download.execute("https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty");
adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, titles);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
public class DownloadAsyncTask extends AsyncTask<String, Void, String>{
JSONArray codes;
URL url;
HttpURLConnection connection;
InputStream stream;
InputStreamReader reader;
@Override
protected String doInBackground(String... urls) {
try {
url = new URL(urls[0]);
connection = (HttpURLConnection) url.openConnection();
stream = connection.getInputStream();
reader = new InputStreamReader(stream);
int data = reader.read();
String feed = "";
while(data != -1) {
char character = (char) data;
feed = character;
data = reader.read();
}
Log.i("feed: ", feed);
codes = new JSONArray(feed);
Log.i("Length: ", String.valueOf(codes.length()));
for(int i = 0; i < 20; i ){
String id = codes.getString(i);
Log.i("id: ", id);
url = new URL("https://hacker-news.firebaseio.com/v0/item/" id ".json?print=pretty");
connection = (HttpURLConnection) url.openConnection();
stream = connection.getInputStream();
reader = new InputStreamReader(stream);
int data1 = reader.read();
String jsonFeed = "";
while(data1 != -1){
char c = (char) data1;
jsonFeed = c;
data1 = reader.read();
}
JSONObject part = new JSONObject(jsonFeed);
if(!part.isNull("title") && !part.isNull("url")) {
titles.add(part.getString("title"));
siteUrls.add(part.getString("url"));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
CodePudding user response:
You have to notify adapter after DownloadAsyncTask execution complete and ArrayList has new data. like this
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
adapter.notifyDataSetChanged(); //add this line
}
CodePudding user response:
This is a classic case of out of sync condition. What is happening in your project is when you are opening an Async task to get the data its opening on a seperate thread due to which when the control is in the line with notifyDataSetChanged the data has not been recieved yet .
on using
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
adapter.notifyDataSetChanged(); //add this line
}
you ensure that this block runs when the async task is complete hence stops the out of sync error