从后台线程调用 startActivity 并且主线程被阻塞时,Activity 延迟启动
Posted
技术标签:
【中文标题】从后台线程调用 startActivity 并且主线程被阻塞时,Activity 延迟启动【英文标题】:Activity starts with delay when calling startActivity from background thread and the main thread being blocked 【发布时间】:2019-08-25 00:06:51 【问题描述】:我正在尝试阻止主线程并向用户显示对话活动(在另一个 android:process
中运行)以做出是/否决定。用户单击是或否后,对话活动结束,主线程恢复。请注意,我的项目需要阻塞主线程。
开始对话:
private boolean getUserDecision()
DialogRunnable dialogRunnable = new DialogRunnable();
Thread thread = new Thread(dialogRunnable);
thread.start();
while (thread.isAlive())
try
// block the thread until user enters his decision
thread.join();
catch (InterruptedException e)
e.printStackTrace();
return dialogRunnable.decision;
还有DialogRunnable
:
class DialogRunnable extends Runnable
public boolean decision;
@Override
public void run()
Looper.prepare();
Intent intent = /* intent for launching the dialog */
intent.setResultMessenger(new Messenger(new Handler()
@Override
public void handleMessage(Message msg)
Looper.myLooper().quit();
decision = msg.arg1 == 1;
));
startActivity(intent);
Looper.loop();
意外行为
如果在主线程上调用getUserDecision
,对话框会在明显延迟(~ 1 秒)后启动,但从后台线程调用该方法会立即启动对话框。为什么?
【问题讨论】:
“请注意,我的项目需要阻塞主线程”——你为什么这么认为? @CommonsWare 我实际上正在为 AOSP 开发一个系统框架,它挂钩某些绑定器调用。这不是一个普通的应用程序。 你可以试试developer.android.com/reference/android/os/AsyncTask 如果阻塞主线程,Android 会抛出 ANR。 @DavidWasser 没有 ANR,一切正常。唯一的问题是前面提到的延迟。 【参考方案1】:这是因为应用程序的onPause
的活动管理器服务waiting 完成。并且由于主线程被阻塞,ActivityManagerService 等待500ms 并放弃,然后启动下一个活动。
【讨论】:
以上是关于从后台线程调用 startActivity 并且主线程被阻塞时,Activity 延迟启动的主要内容,如果未能解决你的问题,请参考以下文章