The task is to get it from the json server, parse it, and fill it with SQLite data, and then fill it with the ListView from SQLite.

I kind of wrote everything, but when I first start the application, the ListView does not fill up, and if I change the orientation of the screen or restart the application, everything is displayed as it should.

I ask you to tell me how to make sure that when you first start the ListView application, it will be filled with data from SQLite, which is pushed there from json?

import android.database.Cursor; import android.os.Bundle; import android.support.v4.widget.SimpleCursorAdapter; import android.support.v7.app.AppCompatActivity; import android.widget.ListView; import android.os.AsyncTask; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class MainActivity extends AppCompatActivity { private Db mDbAdapter; private Cursor mCursor; private SimpleCursorAdapter mCursorAd; private ListView mLv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); new ParseTask().execute(); simpleCursorAdapter(); } public void simpleCursorAdapter(){ mDbAdapter = new Db(this); mCursor = mDbAdapter.getAllItems(); String[] from = new String[] { KEY_NAME, KEY_EMAIL }; int[] to = new int[] { R.id.tvName, R.id.tvEmail }; mCursorAd = new SimpleCursorAdapter(this, R.layout.item, mCursor, from, to, 0); mLv = (ListView) findViewById(R.id.lv); mLv.setAdapter(mCursorAd); mDbAdapter.close(); } private class ParseTask extends AsyncTask<Void, Void, String> { HttpURLConnection urlConnection = null; BufferedReader reader = null; String resultJson = ""; @Override protected String doInBackground(Void... params) { // получаем данные с внешнего ресурса try { URL url = new URL("http://androiddocs.ru/api/friends.json"); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.connect(); InputStream inputStream = urlConnection.getInputStream(); StringBuffer buffer = new StringBuffer(); reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { buffer.append(line); } resultJson = buffer.toString(); } catch (Exception e) { e.printStackTrace(); } return resultJson; } @Override protected void onPostExecute(String strJson) { super.onPostExecute(strJson); JSONObject dataJsonObj = null; try { dataJsonObj = new JSONObject(strJson); JSONArray friends = dataJsonObj.getJSONArray("friends"); mDbAdapter.deldel(); for (int i = 0; i < friends.length(); i++) { JSONObject friend = friends.getJSONObject(i); JSONObject contacts = friend.getJSONObject("contacts"); String email = contacts.getString("email"); mDbAdapter.insEmail(email); } } catch (JSONException e) { e.printStackTrace(); } } } } 

This class is an assistant:

 import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class Db { public static final String TABLE_NAME = "people"; public static final String KEY_ID = "_id"; public static final String KEY_NAME = "name"; public static final String KEY_EMAIL = "email"; private static final String DATABASE_NAME = "peopleDB"; private static final int DATABASE_VERSION = 1; private DbHelper mDbHelper; private SQLiteDatabase mDb; public Db(Context context) { mDbHelper = new DbHelper(context); } public Cursor getAllItems() { mDb = mDbHelper.getReadableDatabase(); return mDb.query(TABLE_NAME, null, null, null, null, null, null); } public String insEmail(String s){ mDb = mDbHelper.getWritableDatabase(); ContentValues contentValues = new ContentValues(); contentValues.put(KEY_EMAIL, s); mDb.insert(TABLE_NAME, null, contentValues); mDb.close(); return null; } public void deldel(){ mDb = mDbHelper.getWritableDatabase(); mDb.delete(TABLE_NAME, null, null); mDb.close(); } public void close() { if (mDbHelper != null) mDbHelper.close(); if (mDb != null) mDb.close(); } public class DbHelper extends SQLiteOpenHelper { public DbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table " + TABLE_NAME +" (" + KEY_ID + " integer primary key autoincrement," + KEY_NAME + " text," + KEY_EMAIL + " text" + ");"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); this.onCreate(db); } } } 

Just in case, here's the main.xml:

 <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="ListView должен быть ниже" android:id="@+id/textView1" android:layout_gravity="center_horizontal" /> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="wrap_content"> </ListView> </LinearLayout> 

Here is item.xml:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/tvName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="tvName" /> <TextView android:id="@+id/tvEmail" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:text="tvEmail" /> </LinearLayout> 
  • Exactly after restarting, is the ListView application full? I did not succeed (your files were used) - iramm
  • Yes. If you twist the screen or minimize the application, and then run it again, tap on the ListView icon is filled. - Erm
  • Strange, you copied all the files as you are running now? It just doesn't work for me. - iramm
  • Yes, all files (well, except for the package ... line) - Erm
  • After adding permission to the Internet and it worked for me))) - iramm

1 answer 1

The simpleCursorAdapter() method is called right after you start AsyncTask , when the database did not have time to fill.

In order for the specified method to be called when everything is ready, put its call at the very end of your onPostExecute(String strJson) method and open the database in it. Then this method will take the form:

 protected void onPostExecute(String strJson) { super.onPostExecute(strJson); JSONObject dataJsonObj = null; try { dataJsonObj = new JSONObject(strJson); JSONArray friends = dataJsonObj.getJSONArray("friends"); mDbAdapter = new Db(MainActivity.this); // <-- new ---- mDbAdapter.deldel(); for (int i = 0; i < friends.length(); i++) { JSONObject friend = friends.getJSONObject(i); JSONObject contacts = friend.getJSONObject("contacts"); String email = contacts.getString("email"); mDbAdapter.insEmail(email); } } catch (JSONException e) { e.printStackTrace(); } simpleCursorAdapter(); // <-- new --- } 

And from onCreate() call simpleCursorAdapter() remove.

  • Does not work. When I insert at the end of the method, the application crashes with an error. There is no text error, since I am now forced to test not on an emulator, but on a smart. Inserted both after a cycle, and after catch - the result is the same. - Erm
  • @Erm And why is there no error text? So what, what on smart. - iramm
  • So just crashes and that's it. I don’t even know where to look for the error code :( - Erm
  • @Erm In Android Studio, see the Android monitor tab. What will be red is a mistake. True there is a lot of things usually. It is necessary to allocate the main thing. - iramm
  • I have a weak computer here (even the emulator doesn’t pull) and the Chinese smart, which Android Studio doesn’t see :(. I just sit here and upload it to the smart over the wire and launch it on a smart. All testing works / does not work. These are the cakes. - Erm