0

My ListView is not showing anything.

I'm downloading the top stories API from Hacker-News and putting them in my app. I want to put the titles of those stories in my list view (they are over 100).

I download them and store them in a database for permanent storage and then add them to my list view, but NOTHING is showing up in my app. Can anyone explain to me why?

UPDATE: I get a CursorIndexOutOfBoundException problem. ( index 350 out of 350)

public class MainActivity extends AppCompatActivity {

    ListView listView;
    private SQLiteDatabase myDatabase;
    private Cursor cursor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = (ListView) findViewById(R.id.listView);

        DownloadIDs ids = new DownloadIDs();
        String URL = "https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty";
        ids.execute(URL);

        try {

            ArrayList<String> titles = new ArrayList<String>();
            ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, titles);
            listView.setAdapter(arrayAdapter);

            myDatabase = this.openOrCreateDatabase("HackerNews", MODE_PRIVATE, null);

            Cursor cursor1 = myDatabase.rawQuery("SELECT * FROM ids", null);
            int index = cursor1.getColumnIndex("urlID");
            cursor1.moveToFirst();
            while (cursor1 != null) {
                String newUrl = "https://hacker-news.firebaseio.com/v0/item/" + cursor1.getString(index) + ".json?print=pretty";
                new DownloadContent().execute(newUrl);
                cursor1.moveToNext();
            }

            Cursor cursor2 = myDatabase.rawQuery("SELECT * FROM content", null);
            int titleIndex = cursor2.getColumnIndex("title");
            cursor2.moveToFirst();
            titles.add("Hello");
            while(cursor2 != null){
                titles.add(cursor2.getString(titleIndex));
                arrayAdapter.notifyDataSetChanged();
                cursor2.moveToNext();
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public class DownloadIDs extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {

            String result = "";
            URL url;
            HttpURLConnection urlConnection = null;
            try {
                url = new URL(params[0]);
                urlConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = urlConnection.getInputStream();
                InputStreamReader reader = new InputStreamReader(inputStream);
                int data = reader.read();

                while (data >= 0) {
                    char current = (char) data;
                    result += current;
                    data = reader.read();
                }

                return result;

            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);

            try {
                myDatabase.execSQL("CREATE TABLE IF NOT EXISTS ids (id INTEGER PRIMARY KEY, urlID VARCHAR)");
                cursor = myDatabase.rawQuery("SELECT COUNT(*) FROM ids", null);
                cursor.moveToFirst();
                int count = cursor.getInt(0);

                if (!(count > 0)) {

                    JSONArray ids = new JSONArray(s);
                    for (int i = 0; i < ids.length(); i++) {
                        myDatabase.execSQL("INSERT INTO ids (urlID) VALUES ('" + ids.getString(i) + "')");
                    }
                }

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public class DownloadContent extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            String result = "";
            URL url;
            HttpURLConnection urlConnection = null;
            try {
                url = new URL(params[0]);
                urlConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = urlConnection.getInputStream();
                InputStreamReader reader = new InputStreamReader(inputStream);
                int data = reader.read();

                while (data >= 0) {
                    char current = (char) data;
                    result += current;
                    data = reader.read();
                }

                return result;

            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);

            try {
                myDatabase.execSQL("CREATE TABLE IF NOT EXISTS content(id INTEGER PRIMARY KEY, title VARCHAR, url VARCHAR)");
                cursor = myDatabase.rawQuery("SELECT COUNT(*) FROM content", null);
                cursor.moveToFirst();
                int count = cursor.getInt(0);

                if (!(count > 0)) {

                    JSONObject jsonObject = new JSONObject(s);
                    String title = jsonObject.getString("title");
                    Log.i("title", title);
                    String url = jsonObject.getString("url");
                    Log.i("url", url);

                    myDatabase.execSQL("INSERT INTO content (title, url) VALUES('" + title + "','" + url + "')");

                }

            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}

2 Answers2

1

Got it! I fixed it. I just had to reduce the amount of news (I decided to choose the top 20 ones), and I decided to run only one ASyncTask on my app.

Here is the edited code:

PD: Thanks to @cafebabe1991 as he gave me tips on how to fix it. Thanks!

public class MainActivity extends AppCompatActivity {

    ListView listView;
    private SQLiteDatabase myDatabase;
    ArrayList<String> titles;
    ArrayList<String> urls;
    ArrayAdapter arrayAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = (ListView) findViewById(R.id.listView);
        titles = new ArrayList<>();
        urls = new ArrayList<>();
        arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, titles);
        listView.setAdapter(arrayAdapter);

        try {
            myDatabase = this.openOrCreateDatabase("HackerNews", MODE_PRIVATE, null);
            DownloadTask downloadTask = new DownloadTask();
            String URL = "https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty";
            downloadTask.execute(URL);

            Cursor cursor = myDatabase.rawQuery("SELECT * FROM content", null);
            int titleIndex = cursor.getColumnIndex("title");
            int urlIndex = cursor.getColumnIndex("url");
            cursor.moveToFirst();
            while(cursor!=null){
                titles.add(cursor.getString(titleIndex));
                urls.add(cursor.getString(urlIndex));
                cursor.moveToNext();
            }
            arrayAdapter.notifyDataSetChanged();

        } catch (Exception e) {
            e.printStackTrace();
        }

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                Intent intent = new Intent(getApplicationContext(), MainActivity2.class);
                MainActivity2.url = urls.get(position);
                startActivity(intent);
            }
        });
    }

    public class DownloadTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {

            String articleInfo = "";
            URL url;
            HttpURLConnection urlConnection = null;
            try {
                url = new URL(params[0]);
                urlConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = urlConnection.getInputStream();
                InputStreamReader reader = new InputStreamReader(inputStream);
                int data = reader.read();

                while (data >= 0) {
                    char current = (char) data;
                    articleInfo += current;
                    data = reader.read();
                }

                //myDatabase.execSQL("CREATE TABLE IF NOT EXISTS ids (id INTEGER PRIMARY KEY, urlID VARCHAR)");
                myDatabase.execSQL("CREATE TABLE IF NOT EXISTS content (id INTEGER PRIMARY KEY, title VARCHAR, url VARCHAR)");
                myDatabase.delete("content", null, null);
                JSONArray ids = new JSONArray(articleInfo);

                for (int i = 0; i < 20; i++) {
                    //myDatabase.execSQL("INSERT INTO ids (urlID) VALUES ('" + ids.getString(i) + "')");

                    String articleInfo2 = "";
                    URL url2 = new URL("https://hacker-news.firebaseio.com/v0/item/" + ids.getString(i) + ".json?print=pretty");
                    HttpURLConnection urlConnection2 = (HttpURLConnection) url2.openConnection();
                    InputStream inputStream2 = urlConnection2.getInputStream();
                    InputStreamReader reader2 = new InputStreamReader(inputStream2);
                    int data2 = reader2.read();

                    while (data2 >= 0) {
                        char current2 = (char) data2;
                        articleInfo2 += current2;
                        data2 = reader2.read();
                    }

                    JSONObject jsonObject = new JSONObject(articleInfo2);

                    String title = "'" + jsonObject.getString("title").replaceAll("'", "") + "'";
                    String articleURL = "'" + jsonObject.getString("url") + "'";

                    myDatabase.execSQL("INSERT INTO content (title, url) VALUES (" + title + "," + articleURL + ")");

                }

                return null;

            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);

        }
    }
}
0

The problem lies in this code

1.)

Cursor cursor1 = myDatabase.rawQuery("SELECT * FROM ids", null);
        int index = cursor1.getColumnIndex("urlID");
        cursor1.moveToFirst();
        while (cursor1 != null) {
            String newUrl = "https://hacker-news.firebaseio.com/v0/item/" + cursor1.getString(index) + ".json?print=pretty";
            new DownloadContent().execute(newUrl);
            cursor1.moveToNext();
        }

How ?

You say to to cursor to get you the column index and from that you fetch the item id, but when database is empty the value will be null. Hence the api will not return a response. Additionally you do the same mistake with the cursor as mentioned in the point below.

2.)

int titleIndex = cursor2.getColumnIndex("title");
        cursor2.moveToFirst();
        titles.add("Hello");
        while(cursor2 != null){
            titles.add(cursor2.getString(titleIndex));
            arrayAdapter.notifyDataSetChanged();
            cursor2.moveToNext();
        }

How ?

You said to the cursor to move to the first record (moveToFirst()) , what if the currently no record exist. This method returns false if the cursor is empty. So make sure that this method returns true and then proceed.

OR

Do this(Better approach)...

while(cursor.moveToNext()) {
    //If inside , that means you are on the next record.Fetch the column values here
}

References : Cursor methods

Discussion about best ways to iterate a cursor

For loading data into the listview from the database

Community
  • 1
  • 1
cafebabe1991
  • 4,928
  • 2
  • 34
  • 42
  • Plus, you are using cursor2 to fetch the title, and after that you are seeing if its not null. That is bad... The null check is redundant. – cafebabe1991 Jun 13 '16 at 02:52
  • I'm pretty sure if it were null, my error would say index 0 out of 0, and not 350 out of 350. I tried what you said and it's still the same. Nothing is showing up on my listview – Guillermo Herrera Jun 13 '16 at 03:37
  • Try to debug it one by one....First see if the request to the api is successful. Print the response and see if that is working fine and then we move to second step which verifying your logic – cafebabe1991 Jun 13 '16 at 03:41
  • I tried everything. I still don;t know what the problem is. I do know it gets the info from the API as I tried putting on the console the values of title and urls. I still don't know why it stays blank all the time :/ – Guillermo Herrera Jun 13 '16 at 03:58
  • Can you add a dummy string when the app starts in the title. And if the notifydatasetchanged is being called in your program, it should again become empty. Can you try this ? – cafebabe1991 Jun 13 '16 at 04:09
  • I will restart my whole app. I think my app may be doing to much downloading in the main task, and besides, putting 300+ items on a listview may be too much too. I think that's the problem. – Guillermo Herrera Jun 13 '16 at 04:30
  • That is indeed but your app might hang for a second or so but would show the items i think. – cafebabe1991 Jun 13 '16 at 04:31