【问题标题】:Best alternative to Stop an Activity started from a Service停止从服务启动的活动的最佳替代方案
【发布时间】:2015-05-11 20:14:30
【问题描述】:

我使用我的服务中的以下代码开始了一项活动:

Intent cmActivityIntent = new Intent(getApplicationContext(), CallManagementActivity.class);
cmActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(cmActivityIntent);

在应用的清单中,活动的启动模式定义为android:launchMode="singleTask"

我一直在寻找停止服务 onDestroy() 上的活动的方法,但我找不到任何可以帮助我的文档。而且我只找到了一种方法。

我已经看到了检查服务的方法,如果活动是使用活动类静态属性 (public static boolean isInstanced) 实例化的,并且如果是,则使用 FINISH_ACTIVITY 额外向活动发送另一个意图。然后,在活动的onNewIntent() 上检查标志,如果包含标志,活动将完成。

我觉得这种方法不合适,因为意图应该用于启动活动而不是停止它们。

有人知道如何完成此任务的任何其他方式吗?

【问题讨论】:

  • 广播可以工作,在活动中有一个接收器。或者,活动可以绑定到服务,向其传递信使,服务将使用信使将命令传递给活动。
  • LocalBroadcastManager 或像Otto 这样的事件总线应该能够做到这一点,然后只需在事件上调用finish()
  • @njzk2 您能否将绑定替代方案发布为带有示例代码的解决方案来尝试它是否有效?
  • 我赞成您在帖子中提到的方法。我一直在做这种事情。 Intents 在 Android 中用于组件之间的通信。它们不仅用于开始活动。恕我直言,这是一个完全合法的目的。另一种选择是发送广播Intent(如@njzk2 建议的那样)。

标签: android android-intent android-activity broadcastreceiver android-service


【解决方案1】:

已经给出了许多替代方案来解决这个问题:

  • 使用Intent 并设置Extra
  • Service 发送广播意图并在Activity 上注册BroadcastReceiver
  • 使用LocalBroadcastManager(类似于以前的替代方法)
  • Activity 绑定到Service 并传递给Messenger,以便Service 可以使用它与Activity 通信。

他们都没有找到好的解决方案,事实上,由于服务只能从包中访问,我坚持的解决方案是Observer Pattern

接下来您将找到我使用的代码。活动实现了 Observer 接口(我自己的),服务实现了抽象类 ObservableService。

ObservableService:

public abstract class ObservableService extends Service {

@Override 
public void onCreate() {
    super.onCreate();
    serviceStarted = true;
    observers = new ArrayList<Observer>();
}

@Override
public void onDestroy() {
    super.onDestroy();
    serviceStarted = false;
}

//---------------------------------------------------------
//
// Singleton methods
//
//---------------------------------------------------------

/**
 * Flag set to <code>true</code> if the service is running and 
 * <code>false</code> if not.
 */
private static boolean serviceStarted;

/**
 * Used to check if the service is started.
 * @return <code>true</code> if the service is running and <code>false</code>
 * if not.
 */
public static boolean isServiceStarted() {
    return serviceStarted;
}

//---------------------------------------------------------
//
// Observable methods an constants
//
//---------------------------------------------------------

/**
 * Used to notify the observers that the service has been stopped.
 */
public static String UPDATE_TYPE_SERVICE_STOPPED = "service_stopped";


protected static ArrayList<Observer> observers;


public static void addObserver(Observer observer) {
    observers.add(observer);
}

public static void removeObserver(Observer observer) {
    observers.remove(observer);
}

protected static void notifyObservers(String updateType) {
    for (Observer observer : observers) {
        observer.onObservableUpdate(updateType);
    }
}

}

观察者:

public interface Observer {

    public void onObservableUpdate(String updateType);

}

活动只是在 onResume() 将自己注册为观察者,并在 onPause() 取消注册。如果服务已经停止,isServiceStarted() 用于完成活动。

@Override
protected void onResume() {
    super.onResume();

    if (InCallService.isServiceStarted()) {
        InCallService.addObserver(this);
    } else {
        this.finish();
    }
}

@Override
protected void onPause() {
    super.onPause();
    InCallService.removeObserver(this);
}

public void onObservableUpdate(String updateType) {
    if (updateType.equals(ObservableService.UPDATE_TYPE_SERVICE_STOPPED)) {
        this.finish();
    }
}

我选择这个是因为我发现它是一个非常简单且高性能的替代方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2023-03-24
    • 2015-11-02
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多