AsyncTask onBackground() 抛出错误 - 由以下原因引起:java.lang.IllegalStateException:必须在主线程上调用方法 addObserver

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

提问人:Adam Varhegyi 提问时间:7/16/2023 更新时间:7/16/2023 访问量:48

问:

今天我打开了我的项目,这个项目已经有大约 6 个月没有更新了,我决定更新所有库以使其与最新的 Android 开发环境保持同步。

在更新了几个库后,我的应用程序在非常简单的 AsyncTask 的 onBackground() 部分中抛出异常。

这是我的 AsyncTask,非常简单的代码,在后台创建数据库,然后开始一个新活动。

        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();

这是崩溃:

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) 

我试图将异步任务更改为不同的后台解决方案,如线程和执行程序,但它抛出了完全相同的错误。

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

这是怎么回事?我只是更新了一些库,没有编写新代码。我觉得 Android 开发就像站在火车前放下铁轨一样。

有什么见解吗?

java android-asynctask android-background

评论

0赞 darshan 7/16/2023
您是否在内部执行任何相关任务,也许是通过回调或事件总线之类的逻辑?似乎初始化了一些 Fragment,导致此崩溃。使用应该严格在主线程上完成,在这种情况下不会发生。UIMyDatabase.initalize()doInBackgroundaddObserver
0赞 Kozmotronik 7/18/2023
但是,AsyncTask 并不是一个最新的 API。
0赞 Adam Varhegyi 7/18/2023
@Kozmotronik 在进行后台操作时显示加载屏幕的更好解决方案是什么?请注意,这是一个使用 Java 而不是 Kotlin 的遗留项目。
0赞 Kozmotronik 7/18/2023
您在加载屏幕中显示什么?请注意,这是一个使用 Java 而不是 Kotlin 的遗留项目。- 这不应该是替换项目中已弃用的 API 的问题。但是,如果您确定您的项目不会在 SDK 30 及更高版本上使用,那么没关系,您可以将其保留为 AsyncTask。
0赞 Adam Varhegyi 7/18/2023
@Kozmotronik我找到了。有一个代码部分创建了新的片段。

答:

1赞 Gabe Sechan 7/16/2023 #1

MyDatabase 的 init 函数正在创建一个 Fragment。该 Fragment 正在尝试观察其 Activity 的生命周期,这不允许在除主线程以外的任何线程上完成。重构代码,使任何数据库代码都不进行任何 UI 调用。无论如何,这两个子系统不应该这样组合