1

I want to get total income amount from my Income table which have Amount table

 @ColumnInfo(name = "Amount")
    private int amount;

And in my IncomeDao I've

 @Query("SELECT SUM(amount) from income_table")
    Integer getTotalIncomeAmount();

And in my IncomeRepository I've

public Integer getTotalIncomeAmount()
    {

        return incomeDao.getTotalIncomeAmount();
    }

In my IncomeViewModel

public Integer getTotalIncomeAmount()
    {
        return incomeRepository.getTotalIncomeAmount();
    }

And I call this in my Main thread like this

totalIncome = incomeViewModel.getTotalIncomeAmount();

But it gives me the error that 'Cannot access database on the main thread since it may potentially lock the UI for a long period of time.'

I know this error can be remove by creating LiveData<Integer> getTotalIncomeAmount(). But I don't want to do this by LiveData because I've to observe it which is not good in my case.

I want someone to show me how to create AsyncTask of this method in my IncomeRepositoryclass because I know this is the only way to get rid of this error. I'm fairly new in programming. As I created other AsyncTask like this in my IncomeRepository

private static class UpdateIncomeAsyncTask extends AsyncTask<Income, Void, Void>
    {
        private IncomeDao incomeDao;
        private UpdateIncomeAsyncTask(IncomeDao incomeDao)
        {
            this.incomeDao = incomeDao;
        }

        @Override
        protected Void doInBackground(Income... incomes)
        {
            incomeDao.update(incomes[0]);
            return null;
        }
    }

I just need someone to complete private static class TotalIncomeAmountAsyncTask extends AsyncTask<Void, Void, Void> for me. I tried very hard but I could succeed. Thanks in advance

Nabeel Ahmed
  • 223
  • 5
  • 15

1 Answers1

1

Try below code,

You will get amount in doInBackgroud method from database, after geting value you will get call in onPostExecute method. If you have global variable then you can directly set value in doInBackgroud method.

private void getTotalIncomeAmount() {
        class TotalIncomeAmountAsyncTask extends AsyncTask<Void, Void, Integer> {

            @Override
            protected Integer doInBackground(Void... voids) {
             
                Integer value = DatabaseClient.getInstance(getApplicationContext()).getAppDatabase()
                        .taskDao()
                        .getTotalIncomeAmount();
                return value;
            }

            @Override
            protected void onPostExecute(Integer value) {
                super.onPostExecute(value);
                //
            }
        }
        TotalIncomeAmountAsyncTask totalIncome = new TotalIncomeAmountAsyncTask();
        totalIncome.execute();
    }
Prayag Gediya
  • 1,078
  • 2
  • 11
  • 20
  • where should I write this method..? and why this method is void? when I want an integer value in return. – Nabeel Ahmed Oct 17 '19 at 06:41
  • You can write this method in class where you want to get that value, and there is many ways to get result value from `onPostExecute` you can refer this https://stackoverflow.com/a/12575319/9792247 – Prayag Gediya Oct 17 '19 at 06:46
  • And should I change it to `private integer getTotalIncomeAmount()` ? because I want integer value in return.. – Nabeel Ahmed Oct 17 '19 at 06:52
  • No it's not possible in this case. You can define global variable for that, and direclty assign value to this global variable in `doInBackground` method in place of `Integer value` – Prayag Gediya Oct 17 '19 at 06:54
  • `getAppDatabase()` this method gives me error that I'm not able to call it... It shows me to create this method in my Database – Nabeel Ahmed Oct 17 '19 at 07:02
  • You've that method with another name that's why it's giving error. Check your `DatabaseClient` class where you've declare method and returns an instance of `appDatabase`. Use that method name in place. – Prayag Gediya Oct 17 '19 at 07:05
  • I've these methods in my Database and my database name is ExpenseManagerDB `private static ExpenseManagerDB INSTANCE; public abstract CategoryDao categoryDao(); public abstract PaymentModeDao paymentModeDao(); public abstract IncomeDao incomeDao(); public abstract ExpenseDao expenseDao();` which method I should call in that place? – Nabeel Ahmed Oct 17 '19 at 07:13
  • You don't have that method. Refer this link to setup room database https://www.simplifiedcoding.net/android-room-database-example/ – Prayag Gediya Oct 17 '19 at 07:19
  • Give upvote or accept answer if it's solve your problem. So this will be also useful for others in future. – Prayag Gediya Oct 17 '19 at 07:38
  • yes of course and if my question is valid also give vote – Nabeel Ahmed Oct 17 '19 at 07:41