onReceive异步操作和垃圾收集

时间:2011-07-24 20:37:31

标签: 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();
}

据我所知: http://developer.android.com/reference/android/content/BroadcastReceiver.html它是,但我不太确定。

  

“任何需要异步操作的东西都不可用,因为你需要从函数返回来处理异步操作,但是那时BroadcastReceiver不再处于活动状态,因此系统可以自由地杀死它的进程。异步操作完成。“

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

1 个答案:

答案 0 :(得分:6)

没有。通过尚未完成的start()方法启动的任何Thread对象都充当垃圾收集根...在它的run()方法完成之前,它或它强烈引用的任何东西都不能被垃圾收集。 / p>

另见这些答案:

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

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

  

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

     

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

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

(当然这一切都适用于你在一个非活动的应用程序中静态注册你的接收器。如果你从一些其他活动组件(比如一个Activity)动态注册它,那么该组件可以管理你的异步操作。有关详细信息,请参阅this answer。)