Android onHandleIntent IntentService 等待 UI 线程
Posted
技术标签:
【中文标题】Android onHandleIntent IntentService 等待 UI 线程【英文标题】:Android onHandleIntent IntentService waits for UI Thread 【发布时间】:2016-08-24 14:25:50 【问题描述】:我注意到如果我从 UI 线程调用 startService,直到 UI 线程被释放后才会调用 onHandleIntent。即 onHandleIntent 被 UI 线程阻止。我尝试在 AsyncTask 中调用 startService,但在 UI 线程被释放之前,onHandleIntent 调用仍然被阻塞。 这是 Android 中的一种行为(或错误??)?或者我做错了什么?我正在 android 6.0 中对其进行测试。
这是我的意图服务
public class TestIntentService extends IntentService
private static final String TAG = TestIntentService.class.getSimpleName();
public TestIntentService()
super(TAG);
@Override
protected void onHandleIntent(Intent intent)
Log.d(TAG, "onHandleIntent Called");
try
for (int i = 1; i <= 10; i++)
Thread.sleep(1000);
Log.d(TAG, "onHandleIntent After " + i + " seconds");
synchronized (MainActivity.handle)
MainActivity.handle.notify();
catch (Exception e)
Log.e(TAG, "Exception", e);
这是我的 Activity 中的方法,单击我正在调用 start Service 的按钮时将调用该方法
protected void onStartServiceButtonClicked(View view)
Log.d(TAG, "startServiceClicked");
Intent intent = new Intent(context, TestIntentService.class);
startService(intent);
Log.d(TAG, "After calling startService");
synchronized (handle)
try
Log.d(TAG, "Before waiting");
handle.wait(4000);
Log.d(TAG, "After handler Wait");
catch (InterruptedException e)
e.printStackTrace();
而handle
只是一个活动类成员变量public static Object handle = new Object();
这是 adb 日志
08-24 10:06:27.777 13564-13564/com.kl.testintentservice D/MainActivity: startServiceClicked
08-24 10:06:27.778 13564-13564/com.kl.testintentservice D/MainActivity: After calling startService
08-24 10:06:27.778 13564-13564/com.kl.testintentservice D/MainActivity: Before waiting
08-24 10:06:31.778 13564-13564/com.kl.testintentservice D/MainActivity: After handler Wait
08-24 10:06:31.782 13564-13564/com.kl.testintentservice I/Choreographer: Skipped 252 frames! The application may be doing too much work on its main thread.
08-24 10:06:31.783 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent Called
08-24 10:06:32.784 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent After 1 seconds
08-24 10:06:33.784 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent After 2 seconds
08-24 10:06:34.785 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent After 3 seconds
08-24 10:06:35.786 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent After 4 seconds
08-24 10:06:36.786 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent After 5 seconds
08-24 10:06:37.786 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent After 6 seconds
08-24 10:06:38.786 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent After 7 seconds
08-24 10:06:39.787 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent After 8 seconds
08-24 10:06:40.787 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent After 9 seconds
08-24 10:06:41.787 13564-16520/com.kl.testintentservice D/TestIntentService: onHandleIntent After 10 seconds
08-24 10:06:41.787 13564-16520/com.kl.testintentservice D/TestIntentService: handle notified
【问题讨论】:
它不是一个错误,它是一个特性,你没有做错任何事情 【参考方案1】:这种行为是完全正常的。它不是 IntentService
独有的。任何 startActivity()
、startService()
、bindService()
或 sendBroadcast()
调用甚至都不会开始工作,直到您从您所在的任何主应用程序线程回调返回。
由于在回调中占用主应用程序线程超过 1 毫秒是不好的做法,因此这种行为应该不会影响很多开发人员。
【讨论】:
谢谢。我绝对不想阻塞 UI 线程。我的意图是从异步 Intent 服务同步数据。我拥有的服务通过 BLE 获取数据,它是异步的,通常我会在 500 毫秒内取回数据。所以我想看看我是否可以在 UI 线程中最多等待一分钟,这样 UI 组件就不必担心回调,只需在同步调用中获取数据。 UI组件会调用一个facade,facade会等待1秒,如果无法获取数据就会抛出异常。 UI 组件只需要处理异常 @KannanLoganathan:“所以我想看看我是否可以在 UI 线程中最多等待一分钟,这样 UI 组件就不必担心回调,只需在同步调用中获取数据” - 不。首先,您遇到了您在问题中引用的问题。其次,您的 UI 在此期间将完全冻结。第三,如果您将主应用程序线程占用几秒钟,Android 会终止您的应用程序,因为它假定您的应用程序已严重损坏。以上是关于Android onHandleIntent IntentService 等待 UI 线程的主要内容,如果未能解决你的问题,请参考以下文章
android 四大组件之ServiceIntentService
使用 IntentService 进行位置监听,但在 onHandleIntent 之后立即调用 onDestroy
handler.postDelayed 在 IntentService 的 onHandleIntent 方法中不起作用