Stefan
Stefan

Reputation: 311

Wait for Database to finish inserting data before continuing to next activity Android

I have an activity that calls JSON data from a foreign database. Below is my ideal case for my app:

What actually happens:

How do I force Android to wait until database insertion is completed before starting the next activity?

EDIT

My doInBackground looks as follows:

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

        StringRequest strReq = new StringRequest(Request.Method.GET,
                str, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    // Check for error node in json
                    if (!error) {
                        JSONArray jObjInside = jObj.getJSONArray("service_prov_services");
                        for (int i = 0; i < jObjInside.length(); i++) {
                            // Now store the user in SQLite
                            try {
                                //  JSONObject user = jObj.getJSONObject("user");

                                String service_prov_type = jObj.getString("service_prov_type");
                                String service_prov_name = jObj.getString("service_prov_name");
                                String addr_street = jObj.getString("addr_street");
                                String addr_num = jObj.getString("addr_number");
                                String addr_plz = jObj.getString("addr_plz");
                                String addr_city = jObj.getString("addr_city");
                                JSONObject elem = jObjInside.getJSONObject(i);

                                if(elem != null){

                                    String service_id = elem.getString("service_id");
                                    String service_type = elem.getString("service_type");
                                    String service_measure = elem.getString("service_measure");


                                    // Inserting row in userServiceProvServices table
                                        db.addUserServiceProvServices(service_id, service_prov_type,
                                       service_prov_name, addr_street, addr_num, addr_plz, addr_city, service_type, service_measure);
                                    Log.d("post_url for service", addr_plz );
                                }

                            } catch (JSONException e) {
                                // JSON error
                                e.printStackTrace();
                                Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
                             e.getMessage(), Toast.LENGTH_LONG).show();
                            }
                        }

                    } else {
                        // Error in login. Get the error message
                        String errorMsg = jObj.getString("error_msg");
                        Toast.makeText(getActivity().getApplicationContext(),
                                errorMsg, Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    // JSON error
                    e.printStackTrace();
                    Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
                                   e.getMessage(), Toast.LENGTH_LONG).show();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Login Error: " + error.getMessage());
                Toast.makeText(getActivity().getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_LONG).show();

            }
        });

        Log.d("test string to appcntr",strReq.toString());
        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);




        return params[0];

    }

onPostExecute looks as follows:

    @Override
    protected void onPostExecute(String Result) {
        //super.onPostExecute(Result);
        pdLoading.dismiss();
        //this method will be running on UI thread

        Log.d(TAG, "Stamp: " + Result);
        Bundle args = new Bundle();
        args.putString("stampID", Result);

        ProviderServiceListFragment frag = new ProviderServiceListFragment();
        frag.setArguments(args);
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.content_frame,
                        frag)
                .commit();



    }

With the way I am doing it now, my next Fragment is already called, although the data has not finished being entered into the database. This means the ListArray in the follwoing Fragment is empty because of the missing database data.

Upvotes: 3

Views: 7165

Answers (3)

Angoranator777
Angoranator777

Reputation: 374

I worked on this for a month and finally figured it out for myself (stupid nube I am..) So here is a piece of code inserting a record to sqlite.

On the chosen event ("onClick actionbutton1") a new AsyncTask is created with doInBackground, onPreExecute and onPostExecute.

onPreExecute will setMessage() and show() the progressDialog which will start spinning

onPostExecute will handle the new/next Activity

READ BELOW FOR doInBackground!!

actionButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                final ProgressDialog progressDialog = new ProgressDialog(AddUpdateEvf.this);

                new AsyncTask<Void, Void, Boolean>() {

                    protected Boolean doInBackground(Void... params) {
                        doOneThing();
                        return null;
                    }

                    @Override
                    protected void onPreExecute() {
                        progressDialog.setMessage("Processing...");
                        progressDialog.show();

                    }

                    protected void onPostExecute(Boolean result) {

                        evaluationFormOps.close();
                        progressDialog.dismiss();
                                        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(AddUpdateEvf.this);
                                        alertDialogBuilder.setMessage("Added to Database...")
                                                .setCancelable(false)
                                                .setPositiveButton("Continue", new DialogInterface.OnClickListener() {
                                                    public void onClick(DialogInterface dialog, int id) {
                                                        i = new Intent(AddUpdateEvf.this, ViewProduct.class);
                                                        i.putExtra(EXTRA_ADD_UPDATE, "View");
                                                        i.putExtra(EXTRA_PRODUCT_ID, hiddenTextId.getText().toString());
                                                        i.putExtra(EXTRA_PRODUCT_NO, productNo_tv.toString());
                                                        startActivity(i);
                                                        dialog.dismiss();
                                                        finish();
                                                    }
                                                });

                                        AlertDialog alert = alertDialogBuilder.create();
                                        alert.show();

        }
                    private void doOneThing() {

                        makeDbRequest();
                        do {
                            evfId = newEvf.getEvfId();
                        }
                        while (evfId<1);
                    }

                }.execute();




            }
        });

Note this snippet in the above code called in doInBackground():

 private void doOneThing() {

                        makeDbRequest();
                        do {
                            evfId = newEvf.getEvfId();
                        }
                        while (evfId<1);
                    }

Note: The makeDbRequest() handles the insert to sqlite by setting the values and then passing it to another class which handles the cursor and puts the values etc.

Heres a small snippet of relevant code in that class (which you should already have mastered...):

 public Evf addEvf(Evf evf, String dBsuccess){

    ContentValues values  = new ContentValues();
    values.put(TableHelper.PRODUCT_IDE,evf.getPRODUCTId());
    values.put(TableHelper.CSCORE,evf.getcScore());
    values.put(TableHelper.FSCORE,evf.getfScore());
    values.put(TableHelper.TSCORE,evf.gettScore());
    values.put(TableHelper.WEIGHT,evf.getWeight());
    values.put(TableHelper.TEMP,evf.getTemp());
    values.put(TableHelper.STATUS,evf.getStatus());
    values.put(TableHelper.TIMESTAMP, String.valueOf(evf.getTimeStamp()));
    values.put(TableHelper.LOADED, dBsuccess);
    long insertid = database.insert(TableHelper.TABLE_EVFS,null,values);
    evf.setEvfId((int) insertid);
    return evf;

}

So above you can see the Id of, in my case evaluationform(Evf), being set to the insert id. This happens after the insert and you can set any value in your object class (the one with getters and setters...Evf())

Finally, use the do...while statement above to "listen" for the value being set in the object class

This can obviously only happen if the insert was finished and the onPosteExecute takes care of the rest

Hope it helps, crit is welcome, PEACHES!!

Upvotes: 2

SanthoshN
SanthoshN

Reputation: 629

The StringRequest is an Asynchronous request, so upon the executing the those lines onPostExecute will called immediately, so there is no guarantee that the sql update will complete before the next activity is launched.

Call the nextActivity at the end of the onResponse callback method of the StringRequest which way you can guarantee to insert the data to db first and then call the nextActivity.

     private void makeJsonRequest(String str) {
        StringRequest strReq = new StringRequest(Request.Method.GET,
                str, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    // Check for error node in json
                    if (!error) {
                        JSONArray jObjInside = jObj.getJSONArray("service_prov_services");
                        for (int i = 0; i < jObjInside.length(); i++) {
                            // Now store the user in SQLite
                            try {
                                //  JSONObject user = jObj.getJSONObject("user");

                                String service_prov_type = jObj.getString("service_prov_type");
                                String service_prov_name = jObj.getString("service_prov_name");
                                String addr_street = jObj.getString("addr_street");
                                String addr_num = jObj.getString("addr_number");
                                String addr_plz = jObj.getString("addr_plz");
                                String addr_city = jObj.getString("addr_city");
                                JSONObject elem = jObjInside.getJSONObject(i);

                                if (elem != null) {

                                    String service_id = elem.getString("service_id");
                                    String service_type = elem.getString("service_type");
                                    String service_measure = elem.getString("service_measure");


                                    // Inserting row in userServiceProvServices table
                                    db.addUserServiceProvServices(service_id, service_prov_type,
                                            service_prov_name, addr_street, addr_num, addr_plz, addr_city, service_type, service_measure);
                                    Log.d("post_url for service", addr_plz);
                                }

                            } catch (JSONException e) {
                                // JSON error
                                e.printStackTrace();
                                Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
                                        e.getMessage(), Toast.LENGTH_LONG).show();
                            }
                        }
                        goNextActivity();

                    } else {
                        // Error in login. Get the error message
                        String errorMsg = jObj.getString("error_msg");
                        Toast.makeText(getActivity().getApplicationContext(),
                                errorMsg, Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    // JSON error
                    e.printStackTrace();
                    Toast.makeText(getActivity().getApplicationContext(), "Json error: " +
                            e.getMessage(), Toast.LENGTH_LONG).show();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Login Error: " + error.getMessage());
                Toast.makeText(getActivity().getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_LONG).show();

            }
        });

        Log.d("test string to appcntr", strReq.toString());
        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void goNextActivity(){
        //this method will be running on UI thread
        ProviderServiceListFragment frag = new ProviderServiceListFragment();
        frag.setArguments(args);
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.content_frame,
                        frag)
                .commit();
    }

Upvotes: 0

Jay
Jay

Reputation: 5084

Use AsyncTask to process the Database insertion process & then use the onPostExecute method to move away from the current activity.

private class ProcessDatabase extends AsyncTask<String, String, String> {

        String sampleData;

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

            //Call your Database Insert method here.
            //In this example, I am inserting sampleData to the DB

            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            //This gets triggered when the process is complete
        }
    }

You can start the AsyncTask by adding the following code in your onCreate or where ever you want to start the DB Insertion process:

//in this case I am just passing a string, You can create your own
//custom class & send that as well
ProcessDatabase.execute(myData);

Refer this link for more information. Good luck!

Upvotes: 0

Related Questions