【问题标题】:Check if activity is running from service of same package检查活动是否从同一包的服务运行
【发布时间】:2013-03-13 01:29:22
【问题描述】:

这更像是一个疑问。目前,我的代码运行良好,但我想确保我以正确的方式进行操作。

我有一个服务,它检查活动是否在前台运行。如果是,它会向 Activity 发送广播,因此 Activity 会更新屏幕上的一些内容。

我在服务上创建了一个IntentFilter:

com.harkdev.ServerStatus.SERVER_UPDATED

这里服务需要知道activity是否在前台,所以它使用IsActivityRunning()方法,从ApplicationManager中读取正在运行的任务。这意味着我需要设置GET_TASKS 权限。

既然 SERVICE 和 ACTIVITY 都在同一个包中,有没有更好的方法来获取这些信息?也许尝试避免设置GET_TASKS 权限??

这是我服务中的代码:

if (IsActivityRunning()) {
    Intent localIntent = new Intent(SERVER_UPDATED);
    SendBroadcast(localIntent, null);
}

IsActivityRunning() 方法:

public bool IsActivityRunning() {
    ActivityManager manager = (ActivityManager) GetSystemService(ActivityService);
    IList<ActivityManager.RunningTaskInfo> runningTaskInfo = manager.GetRunningTasks(1); 

    ComponentName componentInfo = runningTaskInfo[0].TopActivity;
    if (componentInfo.PackageName == "com.harkdev.ServerStatus") 
        return true;

    return false;
}

这是我活动中的代码:

protected override void OnCreate (Bundle bundle) {
    base.OnCreate(bundle);
    // Set our view from the "main" layout resource
    SetContentView (Resource.Layout.Main);

    IntentFilter filter = new IntentFilter(ServerStatusCheckService.SERVER_UPDATED);
    _receiver = new ServiceBroadcastReceiver ();
    _receiver.Received += Receiver_Received;

    RegisterReceiver(_receiver, filter);
}

【问题讨论】:

    标签: android service android-activity xamarin.android task


    【解决方案1】:

    首先你用错误的方式比较字符串:

    if (componentInfo.PackageName == "com.harkdev.ServerStatus")
    

    应该是:

    if ("com.harkdev.ServerStatus".equals(componentInfo.PackageName))
    

    其次,如果服务和活动在您的应用程序中,那么我认为检查“相同包”的要求是没有必要的。

    要将信息从服务发送到活动,您可以使用ResultReceiver(在 API 3+ 中可用):

    • 从 Activity 启动服务时,您创建一个 ResultReceiver,将其放入启动服务的意图中。
    • 在服务中,提取ResultReceiver 并保留它。如果您想发送信息,请使用send()。
    • 在活动中,例如在onDestroy() 中,您可以触发命令通知服务ResultReceiver 无效,应将其删除。

    编辑

    例如:

    • 在你的活动中:

      // Global variable.
      private ResultReceiver mResultReceiver = new ResultReceiver() {
      
          @Override
          protected void onReceiveResult(int resultCode, Bundle resultData) {
              // Update the UI here...
          }
      }
      

      当你启动服务时:

      Intent i = new Intent(this, TheService.class);
      // You can use different action names for different commands.
      i.setAction("REGISTER_RECEIVER");
      i.putExtra("ResultReceiver", mResultReceiver);
      i.putExtra("ResultReceiver_ID", hashCode());
      startService(i);
      

      在onDestroy():

      Intent i = new Intent(this, TheService.class);
      i.setAction("UNREGISTER_RECEIVER");
      i.putExtra("ResultReceiver_ID", hashCode());
      startService(i);
      
    • 为您服务:

      import  android.util.SparseArray;
      
      // ...
      
      private SparseArray<ResultReceiver> mReceiverMap = new SparseArray<ResultReceiver>();
      
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          if ("REGISTER_RECEIVER".equals(intent.getAction())) {
              // Extract the ResultReceiver and store it into the map
              ResultReceiver receiver = intent.getParcelableExtra("ResultReceiver");
              int id = intent.getIntExtra("ResultReceiver_ID", 0);
              mReceiverMap.put(id, receiver);
          } else if ("UNREGISTER_RECEIVER".equals(intent.getAction())) {
              // Extract the ResultReceiver ID and remove it from the map
              int id = intent.getIntExtra("ResultReceiver_ID", 0);
              mReceiverMap.remove(id);
          }
      
          // ...
      }
      

    【讨论】:

    • 如果我编写了由AlarmManager 执行的服务怎么办?我将如何处理 ResultReceiver?
    • @JuanuHaedo 如果服务中没有注册ResultReceiver,则没有正在运行的活动。所以你不需要检查。
    • 也许我应该进一步解释一下我的应用程序的行为方式。首先:我的活动创建了一个时间表。第二:这个Schedule是由AlarmManager在Service上执行的 这里有一个棘手的部分:如果Service被执行并且Activity正在运行,我需要更新Activity屏幕上的信息,否则什么都不做。
    • @JuanuHaedo 我的意思是,当你开始活动时,你可以在服务中注册一个ResultReceiver。如果您从警报启动服务,则不会注册任何内容。在服务中,您可以使用List 来保留ResultReceiver 的所有实例。如果列表为空,则没有在前台运行的活动。
    • 我很抱歉打扰,但你能写一些关于这个的例子吗?你说的我明白,就是不知道怎么实现……
    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多