将“暂停/恢复”按钮的图像与实际状态同步

时间:2016-09-12 13:54:23

标签: android service localbroadcastmanager

在我的Android应用程序中,有一个服务执行长时间运行的任务(例如播放音乐),该任务可以处于以下两种状态之一:运行或暂停。有一个“暂停/恢复”图像按钮可暂停/恢复任务。此外,由于其他原因(不是来自UI),任务可能会暂停。按钮的外观应根据任务的当前状态(运行或暂停)而有所不同。所以我需要将按钮图像与任务的实际状态同步。

现在我想出了以下解决方案: 我的服务具有静态pauseresume方法,可以像这样向自己发送意图:

public static void pause(Context context) {
    Intent intent = new Intent(context, MyService.class);
    intent.putExtra("PAUSE", true);
    context.startService(intent);
}

public static void resume(Context context) {
    Intent intent = new Intent(context, MyService.class);
    intent.putExtra("RESUME", true);
    context.startService(intent);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent.getBooleanExtra("PAUSE", false)) {
        doPause();
    } else if (intent.getBooleanExtra("RESUME", false)) {
        doResume();
    }
    return START_STICKY;
}

由于doPause()doResume()也可以从其他地方调用,因此我无法在调用MyService.pause() / MyService.resume()时将图像设置为ImageButton:按钮图像并且任务的实际状态可能变得不同步。相反,当使用按钮时,我使用LocalBroadcastManager来通知活动:

public void doPause() {
    paused = true;

    ... // Do some stuff to pause the service

    // Notify about state change
    Intent intent = new Intent("SERIVCE_STATE_CHANGED");
    intent.putExtra("PAUSED", true);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

doResume()的代码类似。 因此,我的活动会注册接收器并将图像设置为onReceive()

解决方案似乎有效。但我的问题是,是否有更好/更简单的方法来实现同一目标?任何最佳做法?

1 个答案:

答案 0 :(得分:1)

我认为你的解决方案不好。但是,另一种可以说更好的方法是使用Android数据绑定。

这将起作用的方式是,创建一个表示服务状态的模型对象。例如。 Player.isPlaying,表示服务状态。然后在服务中,您将设置isPlaying状态。

然后在您的布局中,您将使用数据绑定将该模型对象isPlaying状态链接到UI,但是您要设置它,例如:

android:background="@{player.isPlaying ? @drawable/pause : @drawable/play}"

我认为这可能是一个更好的解决方案的原因是,它将UI状态直接与服务1:1连接起来。从概念上讲,我认为广播可以来自多个来源。但是,我没有看到只有一个广播来源的问题,这就是为什么我不认为你当前的解决方案是坏的。

您可以在此处查看有关Google I / O 2016数据绑定的详细视频:https://www.youtube.com/watch?v=DAmMN7m3wLU