onReceive异步操作和垃圾收集

use*_*321 4 android garbage-collection broadcastreceiver

onReceive方法中的线程在完成之前是否有资格进行垃圾回收?

@Override
public void onReceive(final Context context, Intent intent) {
    final int alarmId = intent.getExtras().getInt(EXTRA_ALARM_ID);
    Log.i(TAG, "/onReceive with an alarmVo.id of " + alarmId);

    // RUN MY THREAD
    new Thread(new Runnable() {
        @Override
        public void run() {
            AlarmUtil.setNextAlarm(context, alarmId);
        }
    }).start();
}
Run Code Online (Sandbox Code Playgroud)

从我在这里的理解:http: //developer.android.com/reference/android/content/BroadcastReceiver.html它是,但我不太确定.

"任何需要异步操作的东西都不可用,因为您需要从函数返回来处理异步操作,但此时BroadcastReceiver不再处于活动状态,因此系统可以在异步操作完成之前自由终止其进程."

如果它被垃圾收集,那么我该如何解决这个问题呢?我的方法应该是什么?

Mic*_*ims 6

没有.通过start()方法启动的任何尚未完成的Thread对象充当垃圾收集根...它强烈引用的任何内容都没有资格被垃圾收集,直到它的run()方法完成.

另见这些答案:

编辑:既然你已经为你的问题添加了额外的上下文,事情会更加清晰.问题是这种情况与垃圾收集完全不同.对于静态发布的BroadcastReceiver(在带有<receiver>标记的应用程序清单中定义),Android可以在onReceive(Context, Intent)返回后自由终止其进程.您的异步操作不会因GC而停止,因为Android会终止托管它的进程而停止.

至于你的方法,这完全取决于你想要完成的事情.如果要在BroadcastReceiver中执行的代码可以同步运行,那么这将是最简单的方法.我认为这是不可能的.在这种情况下,这部分文档似乎适用(强调我的):

从onReceive()返回后,BroadcastReceiver不再处于活动状态,其托管进程与其中运行的任何其他应用程序组件一样重要.这一点尤其重要,因为如果该进程只托管BroadcastReceiver(用户从未或最近没有与之交互的应用程序的常见情况),那么从onReceive()返回时,系统会认为其进程为空并且积极地杀死它使资源可用于其他更重要的过程.

这意味着对于运行时间较长的操作,您通常会将一个服务与BroadcastReceiver结合使用,以便在整个操作期间保持包含进程处于活动状态.

因此,要么同步运行接收器代码,要么使用服务使您的异步操作保持足够长的时间来完成.

(当然,这一切只有在你的静态在不活泼的应用程序注册您的接收器.如果你被动态地从其他一些活性成分中对其进行注册(比方说,一个Activity),则该组件可以管理自己的异步操作请参见本回答更多信息.)