0

I need to insert bulk of data to database in my android application. I have a dialog box containing a listview which have rows name, date, frequency where frequency value would be anything like "Daily", "Monthly", "Quarterly", "Yearly". Here after adding rows to the listview I need to click the done button to save these data's to the database. I need to store each row based on its frequency value. That is, if the frequency value is "Daily" I need to store 1095 (i.e., 3*365-->daily records for 3 year) record to the database for that name, similarly for each frequency value ("Monthly"--> 3*12, "Quarterly"--> 3*4,...) so it cause a bulk insertion of rows to database and which results long time to executes so the user may feel bad and he can't do any other operations in the application without completing this.I am using ORMLite for adding data to database.I have done this as below.

for (int i = 0; i < listAdapter.getCount(); i++) {
    Account rowAcct = new Account();
    rowAcct = listAdapter.getItem(i);
    if (rowAcct.getFreq().equals("Daily")) {
        for (int y = 0; y < 1095; y++) {
            Account nwEvt = new Account();
            dueDt = saveController.getNextDay(dueDt);
            nwEvt.setDueDate(dueDt);
            evtId = saveController.createAcc(nwEvt);
        }
    } else if (rowAcct.getFreq().equals("Monthly")) {
        for (int y = 0; y < 35; y++) {
            Account nwEvt = new Account();
            Date dueDt = saveController.getNextMonth(dueDt);
            nwEvt.setDueDate(dueDt);
            saveController.createAcc(nwEvt);
        }
    } else if (rowAcct.getFreq().equals("Quarterly")) {
        for (int y = 0; y < 11; y++) {
            Account nwEvt = new Account();
            dueDt = saveController.getQuarterMonth(dueDt);
            nwEvt.setDueDate(dueDt);
            evtId = saveController.createAcc(nwEvt);
        }
    } else if (rowAcct.getFreq().equals("Half-Yearly")) {
        for (int y = 0; y < 5; y++) {
            Account nwEvt = new Account();
            Date dueDt = saveController.getHalfYear(dueDt);
            nwEvt.setDueDate(dueDt);
            saveController.createAcc(nwEvt);
        }
    } else if (rowAcct.getFreq().equals("Yearly")) {
        for (int y = 0; y < 2; y++) {
            Account nwEvt = new Account();
            Date dueDt = saveController.getNextYear(dueDt);
            nwEvt.setDueDate(dueDt);
            saveController.createAcc(nwEvt);
        }
    }
}
dialog.dismiss();

How can I minimise this insertion time or making this insertion process in background and make the user free to do other things in the application? Please suggest me the best way to perform this by making the user free.

KJEjava48
  • 1,967
  • 7
  • 40
  • 69
  • 1
    Run the insertion on a new thread. Use an `AsyncTask` perhaps. http://developer.android.com/reference/android/os/AsyncTask.html – Breavyn Sep 09 '15 at 08:43
  • I think asynctask is not safe if you don't control the orientation.AsyncTask was not designed for very long processes. – KJEjava48 Sep 09 '15 at 08:55

3 Answers3

1

first one you need to perform all work with DB in worker thread. Just use android build-in AsyncTasks

second check this, this answers to improve insert in db.

Community
  • 1
  • 1
ant
  • 397
  • 1
  • 5
  • 19
  • I think asynctask is not safe if you don't control the orientation.AsyncTask was not designed for very long processes.Number of rows are huge so its not good to use AsyncTask, as its not tied to the Activity lifecycle i.e if your activity which started it dies, it doesnt mean AsyncTask dies as well, so if you try initiate a AsyncTask and somehow if your activity dies e.g screen rotation or back key pressed, upon restarting another AsyncTask will get spawned rather then it getting linked to already executing AsyncTask. hence duplicating same operations. – KJEjava48 Sep 09 '15 at 08:53
  • Use a fragment. `setRetainInstance(true);`. Lock the button that starts this process in `onPreExecute` and re enable in `onPostExecute`. Also you can use the `synchronized` keyword on the method or block that writes to the database. – Breavyn Sep 09 '15 at 09:00
  • you can start Service and run AsyncTask inside Service – ant Sep 09 '15 at 09:01
  • @ant Can you explain it with some codes.It may needs to add more than 3000 rows sometime so is this AsyncTask is suitable to run a long process – KJEjava48 Sep 09 '15 at 09:04
  • @ColinGillespie I don't want to lock this done button in dialog box.if the user click on the done button perform the insertion process in background and at the same time dismis the dialog box and allow user to get controll and perform other things in the app – KJEjava48 Sep 09 '15 at 09:08
  • check the http://developer.android.com/guide/components/services.html this is describe how to start Service. – ant Sep 09 '15 at 09:08
  • @ant how can i pass this listview data to service class and collect that on service class – KJEjava48 Sep 09 '15 at 09:11
0

Ok, use AsyncTaskLoader =) it check current Activity state =)

mlevytskiy
  • 1,555
  • 2
  • 16
  • 26
0

You need to use an IntentService class and its handler for this,which is designed for long running task.Request an IntentService class after clicking the done button and pass necessary data's with that intent like below

Intent intentEv= new Intent(Intent.ACTION_INSERT, null, getApplicationContext(), MyIntentService.class);

                intentEv.putExtra("requestId", 101);
                intentEv.putExtra("listAccounts",arrayList);
                startService(intentEv);

This will request the Intentservice class and then you can perform the database insertion on background using the onHandleIntent(Intent intent) function in your IntentService.

public class MyIntentService extends IntentService{
 public static final int STATUS_RUNNING = 0;
 public static final int STATUS_FINISHED = 1;
 public static final int STATUS_ERROR = 2;
 public MyIntentService() {
    super("BulkInsertionService");
 }

@Override
protected void onHandleIntent(Intent intent) {
    Log.d(TAG, "Service Started!");
    ArrayList<Account>  listAccounts=(ArrayList<Account>) intent.getSerializableExtra("listAccounts");
   /* perform the long running insert operations now.. */
 this.stopSelf();
}
 }

Also initialise your IntentService class in your AndroidManifest.xml file

user2986084
  • 98
  • 4
  • 12