Search code examples
javaandroidandroid-asynctaskandroid-background

AsyncTask onBackground() throws error - Caused by: java.lang.IllegalStateException: Method addObserver must be called on the main thread


Today I opened my project which haven't been updated for about 6 months now and I decided to update all the libraries to make it up to date with recent Android development environment.

After updating a couple of libraries my app throws an exception inside a very simple AsyncTask's onBackground() part.

Here is my AsyncTask, very simple code, creates database in the background, then starts a new activity.

        new AsyncTask() {
              
            @Override
            protected Object doInBackground(Object[] objects) {
                     
                //Creates database while showing a simple loading screen.
                MyDatabase.initalize();
                return null;
            }
    
            @Override
            protected void onPostExecute(Object o) {
                super.onPostExecute(o);

                //When the database has been created, starts a new activity

                if (isInForeground) {
                    Intent intent= new Intent(StartAppActivity.this, GameAppActivity.class);
                    startActivity(intent);
                    finish();
                }
            }
        }.execute();

This is the crash:

hu.myname.test.app        E  FATAL EXCEPTION: AsyncTask #1
Process: hu.myname.test.app, PID: 15536
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$4.done(AsyncTask.java:415)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
    at java.util.concurrent.FutureTask.run(FutureTask.java:271)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:923)
Caused by: java.lang.ExceptionInInitializerError
    at hu.myname.test.game.dbs.lexicon.MyDatabase.initalize(MyDatabase.java:49)
    at hu.myname.test.activity.StartAppActivity$1.doInBackground(StartAppActivity.java:121)
    at android.os.AsyncTask$3.call(AsyncTask.java:394)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
    at java.lang.Thread.run(Thread.java:923) 
Caused by: java.lang.IllegalStateException: Method addObserver must be called on the main thread
    at androidx.lifecycle.LifecycleRegistry.enforceMainThreadIfNeeded(LifecycleRegistry.java:317)
    at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:172)
    at androidx.fragment.app.Fragment.initLifecycle(Fragment.java:471)
    at androidx.fragment.app.Fragment.<init>(Fragment.java:451)
    at hu.myname.test.fragment.base.BaseFragment.<init>(BaseFragment.java:30)
    at hu.myname.test.fragment.lexicon.base.LexiconAbstractFragment.<init>(LexiconAbstractFragment.java:30)
    at hu.myname.test.fragment.lexicon.TabsLexiconFragment.<init>(TabsLexiconFragment.java:11)
    at hu.myname.test.game.dbs.lexicon.MyDatabase.<clinit>(MyDatabase.java:27)
    at hu.myname.test.game.dbs.lexicon.MyDatabase.runStatic(MyDatabase.java:49) 
    at hu.myname.test.activity.StartAppActivity$1.doInBackground(StartAppActivity.java:121) 
    at android.os.AsyncTask$3.call(AsyncTask.java:394) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
    at java.lang.Thread.run(Thread.java:923) 

I tried to change the async task to different background solutions like threads and executors but it throws the very same error.

Caused by: java.lang.IllegalStateException: Method addObserver must be called on the main thread

What is going on? I simple updated a few libraries, didn't write new code. I feel like Android development is putting down the rails while standing in front of a train.

Any insights?


Solution

  • Your init function of MyDatabase is creating a Fragment. That Fragment is trying to observe it's Activity's lifecycle, which is not allowed to be done on any thread but the main. Refactor your code so that none of your database code makes any UI calls. Those two subsystems shouldn't be combined like that anyway