【问题标题】:Pass data to onDestroy() of Service将数据传递给 Service 的 onDestroy()
【发布时间】:2012-12-30 09:50:00
【问题描述】:

我想知道服务是否从特定活动中终止,因此我在调用 stopServivce(service) 时从该活动中传递了一个字符串。

代码如下:

Intent service = new Intent(Activity.this,
                        service.class);
                service.putExtra("terminate", "activity terminated service");
                stopService(service);

但我似乎可以在 onDestroy() 方法中使用 getIntent().getExtras().getString("terminate); 访问此变量。

[编辑]

我找到了绕过这个障碍的方法,但我希望我的问题仍能得到解答。我只是在活动中的onDestroy() 方法中完成了我必须做的任何事情,然后调用了stopService(service)。我很幸运,我的情况不需要更复杂的事情。

【问题讨论】:

    标签: android android-intent service


    【解决方案1】:

    无法访问onDestroy 中的Intent。您必须以其他方式向服务发出信号(Binder、共享首选项、本地广播、全局数据或 Messenger)。 this answer 给出了一个使用广播的好例子。您也可以通过调用startService 而不是stopService 来实现此功能。 startService 仅在新服务尚不存在时才启动新服务,因此对startService 的多次调用是您将Intents 发送到服务的机制。你看BroadcastReceivers 使用了这个技巧。由于您可以访问onStartCommand 中的Intent,因此您可以通过检查Intent 附加功能并在指示终止时调用stopSelf 来实现终止。下面是它的草图——

    public int onStartCommand(Intent intent, int flags, int startId) {
            final String terminate = intent.getStringExtra("terminate");
    
            if(terminate != null) {
                // ... do shutdown stuff
                stopSelf();
            }
            return START_STICKY;
        }
    

    【讨论】:

    • +1 有史以来最好的解决方案
    【解决方案2】:

    只是为了说明 iagreen 的建议;

    活动中

    Intent broadcastIntent = new Intent();
    broadcastIntent.setAction("com.package.yourfilter");
    broadcastIntent.putExtra("activity_name", "your_activity");
    
    sendBroadcast(broadcastIntent);
    

    服务中

     private YourActionReceiver abc;
    
        this.abc = new YourActionReceiver();
    
        registerReceiver(this.abc, new IntentFilter("com.package.yourfilter"));
    
        public class YourActionReceiver extends BroadcastReceiver {
                @Override
                public void onReceive(Context context, Intent intent) {
        // Get the name of activity that sent this message
        }
    }
    

    【讨论】:

      【解决方案3】:

      全局状态

      是你的朋友。 :)
      需要时检查全局字符串(比如在终止之前)。您可能还需要枚举state一个标志来查看状态是否有效。

      配方:

      您遇到的更普遍的问题是如何跨多个活动和应用程序的所有部分保存状态。静态变量(例如,单例)是实现此目的的常见 Java 方法。然而,我发现,在 Android 中更优雅的方式是将您的状态与应用程序上下文相关联。

      如你所知,每个Activity也是一个Context,它是最广义上关于其执行环境的信息。您的应用程序也有一个上下文,Android 保证它将作为单个实例存在于您的应用程序中。

      这样做的方法是创建自己的android.app.Application 子类,然后在清单的应用程序标记中指定该类。现在 Android 将自动创建该类的一个实例,并使其可用于您的整个应用程序。您可以使用 Context.getApplicationContext() 方法从任何上下文访问它(Activity 还提供了一个具有完全相同效果的方法 getApplication()):

      class MyApp extends Application {
      
        private String myState;
      
        public String getState(){
          return myState;
        }
        public void setState(String s){
          myState = s;
        }
      }
      
      class Blah extends Activity {
      
        @Override
        public void onCreate(Bundle b){
          ...
          MyApp appState = ((MyApp)getApplicationContext());
          String state = appState.getState();
          ...
        }
      }
      
      class BlahBlah extends Service {
      
        @Override
        public void onCreate(Bundle b){
          ...
          MyApp appState = ((MyApp)getApplicationContext());
          String state = appState.getState();
          ...
        }
      }
      

      这与使用静态变量或单例的效果基本相同,但可以很好地集成到现有的 Android 框架中。请注意,这不适用于跨进程(如果您的应用是少数具有多个进程的应用之一)。

      致谢@Soonil

      【讨论】:

        猜你喜欢
        • 2015-02-08
        • 2019-01-28
        • 2012-04-14
        • 2016-05-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-16
        相关资源
        最近更新 更多