【问题标题】:Start a Service from another Service and pass-by-value从另一个服务启动一个服务并按值传递
【发布时间】:2014-04-16 09:53:28
【问题描述】:

我的 Android 应用程序中有一个服务。在 onStartCommand 期间,我将 Service 对象传递给另一个类。然后,从那里,有一个线程在 30 秒后启动另一个服务。是这样的:

public class FooService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        MyClass mc = new MyClass(this);
        mc.testMethod();
        stopSelf();
        return START_NOT_STICKY;
    }
}

这是我的班级:

public class MyClass {

    private Service service;

    public MyClass(Service service) {
        this.service = service;
    }

    public void testMethod() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(20*1000);
                    Intent intent = new Intent(service, BarService.class);
                    service.startService(intent);
                }
                catch (Exception e) {
                    // CATCH!
                }
            }
        }).start();
    }
}

现在,如您所见,在 FooService 中,我调用 stopSelf() 来破坏该 Service 对象。顺便说一句,MyClass 获得了按值传递的该服务的副本。 20 秒后,我们可以从 MyClass 启动 BarService。我已经测试过它并且它有效,但我不明白为什么!我编写代码的方式很脏(对我来说)。从被破坏的服务启动另一项服务是否正确?感谢您的帮助。

【问题讨论】:

  • 参考保存。只是正常。您应该为此使用 AlarmManager。
  • @SoothSayer 它不是引用(或指针,或其他)。 Java 是按值传递的,这意味着对象本身已被销毁,但即使它未处于启动状态,我也有该服务的 副本。这是一个理论问题:从我使用 stopSelf() 销毁的服务启动另一个服务是否正确?我已经实现了一个 AlarmManager,但是现在,我每次都在更新 MyClass 中的 Service 对象。
  • 使用 Handler 和 Messenger 并通过活动不断更新您的服务。
  • Java 不是价值传递,我的意思是,是的,但它不是那么简单。并且 stopSelf() != 被破坏的对象。 IMO,从停止的服务启动另一个服务不是一个好主意。有效,因为您的服务已停止但仍然存在。

标签: android service pass-by-value


【解决方案1】:

我已经测试过了,它可以工作,但我不明白为什么

它今天可以在您测试的环境中运行。它可能无法在所有环境中运行(例如,ROM 模组),并且明天可能无法运行(例如,Android 操作系统更新)。一个被破坏的Context,比如你停止的服务,不应该用于任何事情。 碰巧目前您以后仍然可以使用它来调用startService(),但不能保证这种行为。

从一个被破坏的服务启动另一个服务是否正确?

没有。在这种情况下,我不明白为什么您首先需要两个服务。

我有一份该服务的副本

不,你没有。

【讨论】:

  • 所以,在这一点上,我想我要回去混淆按引用传递,按值传递......
  • @Angelo: stackoverflow.com/questions/40480/is-java-pass-by-reference 简而言之,MyClass 构造函数中的service 是指向Service 对象的指针。该 pointer 是从其原始位置(您的服务中的this)复制(按值传递)。底层的objectnot复制的。
  • 我多次阅读那个该死的链接 :D 所以,按值传递意味着指针被复制,而不是对象本身。好的!因此,即使我调用 stopSelf()(如 SoothSayer 所指出的那样)Service 对象没有被破坏,我仍然在 MyClass 中有一个引用并且 GC 不会破坏它......但它在 Android 环境中不可用。它仍然有效,只是因为该对象在我的堆栈中,对吧?
  • @Angelo:您仍然可以使用服务。在onStartCommand() 中使用if 语句,基于Intent 中的额外内容进行分支。
  • @Angelo:如果MyClass 的实例仅由一个Service 使用,请使用Service。如果MyClass 的实例可能被多个组件使用(例如,它是一个单例),请使用getApplication() 检索Application 并使用它,以避免内存泄漏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多