Search code examples
progress-barormliteandroid-anr-dialogunresponsive-progressbar

ORMLite callBatchTasks and responsive error from Android


I have a problem when I use callBatchTasks and I try to save over 30000 of entries in database. I'm doing the method in an async task to not block the main thread. When I don't use callBatchTaks it takes over 30 minutes to save the data but when I use it the time goes down to 6-10 minutes. The only problem is that after 1-2 minute it blocks my progress bar (it's displaying when the data is saved) and displays the wait/on message like the application is not responding. My question is, how can I avoid the anr block. Here is my code:

new AsyncTask() {
            @Override
            protected String doInBackground(Object... params) {
                String response = "";

                Log.e(LOG_TAG, "Update started");

                try {
                    getAMISCardRuntimeDao().callBatchTasks(new Callable<Object> (){
                        @Override
                        public Object call() throws Exception {
                            for (int i = 0; i < data.getCardListSize(); i++) {
                                createOrUpdateCard(doTransactions, data.getCard(i));
                            }
                            return null;
                        }

                    });
                } catch (Exception e) {
                    Log.d(LOG_TAG, "updateListOfObjects. Exception " + e.toString());
                    return null;
                }

                return response;
            }

            @Override
            protected void onPostExecute(Object msg) {
                if (msg != null) {
                }

            }
        }.execute(null, null, null);

Thank you.


Solution

  • Solved the problem. Made an objects that manages threads and by splitting my array I was able to make the loop async and don't block the UIThread

    try {
                        getCardRuntimeDao().callBatchTasks(new Callable<Object>() {
                            @Override
                            public Object call() throws Exception {
                                int numberOfThreads = Runtime.getRuntime().availableProcessors();
                                int chunk = data.getCardListSize() / numberOfThreads;
                                ArrayList<Thread> threadArrayList = new ArrayList<>();
    
                                for (int i = 0; i < numberOfThreads; i ++){
                                    Thread updateMultiThread;
                                    if (i == numberOfThreads - 1)
                                        updateMultiThread = new Thread(new UpdateMultiThread(data.getCardList(), DatabaseHelper.this, doTransactions, i * chunk, data.getCardListSize()));
                                    else
                                        updateMultiThread = new Thread(new UpdateMultiThread(data.getCardList(), DatabaseHelper.this, doTransactions, i * chunk, (i + 1) * chunk));
    
                                    threadArrayList.add(updateMultiThread);
                                    updateMultiThread.start();
                                }
    
                                for (Thread thread : threadArrayList){
                                    try {
                                        thread.join();
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
    
                                        retryDatabaseUpdate();
                                    }
                                }
    
                                return null;
                            }
                        });
                    } catch (Exception e) {
                        Log.d(LOG_TAG, "updateListOfObjects. Exception " + e.toString());
                    }