AlarmManager和BroadcastReceiver而不是Service - 那很糟糕吗?(超时)

Hub*_*ert 14 service android broadcastreceiver alarmmanager

背景信息:

我需要大约每小时更新一些来自网络的数据,即使我的应用程序关闭也是如此.更新数据本身大约需要40秒到1分钟.然后将其作为Serializable保存到文件中.我的应用启动时会读取此文件.

这是我为时刻而采取的方法(不使用服务)

像这样使用AlarmManager和BroadcastReceiver:

private void set_REFRESH_DATA_Alarm(){
    mContext = Main.this;
    alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    broadcast_intent = new Intent(mContext, 
            RepeatingAlarmReceiver_REFRESH_DATA.class);
    pendingIntent = PendingIntent.getBroadcast(mContext, 0,  broadcast_intent, 0);
    // do a REFRESH every hour, starting for the first time in 30 minutes from now ...
    Calendar now = Calendar.getInstance();
    long triggerAtTime = now.getTimeInMillis()+ (1 * 30 * 60 * 1000); // starts in 30 minutes
    long repeat_alarm_every = (1 * 60 * 60 * 1000); // repeat every 60 minutes
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, triggerAtTime, 
            repeat_alarm_every, pendingIntent);
}
Run Code Online (Sandbox Code Playgroud)

我的RepeatingAlarmReceiver_REFRESH_DATA.class负责从Web更新数据:

public class RepeatingAlarmReceiver_REFRESH_DATA extends BroadcastReceiver {

    public static Context mContext;
    ConnectivityManager mConnectivity;

    @Override
    public void onReceive(Context context, Intent intent) {
        mContext = context;
        // if Network connection is OK (Wifi or Mobile) then Load data ...
        mConnectivity = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        Log.i("Hub",
                "mConnectivity.getNetworkInfo(0)="
                        + mConnectivity.getNetworkInfo(0));
        Log.i("Hub",
                "mConnectivity.getNetworkInfo(1)="
                        + mConnectivity.getNetworkInfo(1));
        if ((mConnectivity.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED)
                || (mConnectivity.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTED)) {
            Log.i("Hub", "Connectivity OK ...");
            Refresh_HIST_DATA();
        } else {
            // else Show Dialog "No network connection" ...
            Log.i("Hub",
                    "No network connection for the moment... will try again later!");
        }
    }

    // =========================================================================
    private void Refresh_HIST_DATA() {
        Log.i("Hub", "Refresh_HIST_DATA()... Starting ...");
        // etc...
    }
}
Run Code Online (Sandbox Code Playgroud)

在清单中我有:

<receiver android:name="com.cousinHub.myapp.RepeatingAlarmReceiver_REFRESH_DATA" android:process=":remote" />
Run Code Online (Sandbox Code Playgroud)

问题:

警报按时触发并开始更新,但在大约10秒后停止(超时):

11月6日至25日:55:05.278:WARN/ActivityManager(76):广播的超时BroadcastRecord {44bb4348空} - receiver=android.os.BinderProxy@44bcc670

11月6日至25日:55:05.278:WARN/ActivityManager(76):超时期间接收机:ResolveInfo {44bb42c0 com.cousinHub.myapp.RepeatingAlarmReceiver_REFRESH_DATA p值= 0°= 0 M =为0x0}

06-25 11:55:05.278:信息/处理(76):发送信号.PID:819 SIG:9

11月6日至25日:55:05.298:INFO/ActivityManager(76):进程com.cousinHub.myapp:远程(PID 819)已经死亡.

PS:奇怪的是,这个"超时"并不在我的HTC Hero(仍然在Android 1.5 - API等级4)约10秒后发生,但也对我的Nexus One(2.1 UPDATE1)

问题:

  1. 为什么这个超时?有什么简单的方法可以避免这个
  2. 我是否在清单中正确设置了BroadcastReceiver?我需要添加一些东西(以避免此超时)吗?
  3. 我绝对应该为这种"从网上刷新"功能寻求服务吗?(考虑到这篇文章:http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-are-not/)如果是(我应该切换到服务)的代码,任何好的片段/这个教程......

总之,谢谢你的帮助.

H.

Com*_*are 18

为什么这个超时?

您正在主应用程序线程上运行.您无法在主应用程序线程上运行超过几秒钟.此外,在执行此操作时,您正在损害设备的性能(因为您正在以前台优先级运行),例如导致游戏或视频中的帧速率损失.

有什么简单的方法可以避免这个

不要在主应用程序线程上做大量工作(> 100ms).请你的BroadcastReceiver代表IntentService,也许是WakefulIntentService.

我是否在清单中正确设置了BroadcastReceiver?

请请请摆脱android:process=:remote.你不需要它,它没有帮助你,它进一步降低了设备的性能.

我绝对应该为这种"从网上刷新"功能寻求服务吗?(考虑到这篇文章: http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-are-not/)如果是(我应该切换到服务)的代码,任何好的片段/这个教程......

恕我直言,是的.然后,我写了那篇博文.有关示例,请参阅该WakefulIntentService项目.