仅在活动运行时将意图从服务发送到活动

Posted

技术标签:

【中文标题】仅在活动运行时将意图从服务发送到活动【英文标题】:Sending intents from service to activity only when activity is running 【发布时间】:2013-09-30 10:39:28 【问题描述】:

我有一个服务和应用程序。它们之间通过在特定情况下发送意图来进行通信。在活动中,我注册和注销广播接收器以收集此意图。当执行特定的回调方法时,来自服务的意图正在发送。是否有可能仅在活动处于前台时才发送此意图?因为当这是隐藏时,不需要收集这个意图(它只有助于实时显示一些情况)?我发现在活动中可能是指示这种情况的静态字段,但我不知道如何从服务中访问活动,另外我发现这是不同的不良设计实践的信息。感谢您的任何建议!

【问题讨论】:

您的服务(应该)是否一直在运行? 是的服务一直在运行。 【参考方案1】:

在您的Activity 中声明:

public static boolean isRunning;

然后在你的onPause 中设置isRunning = false;

onResume 中将其设置为isRunning = true;

然后从您的Service 拨打ActivityName.isRunning 即可知道它是否在前台!

【讨论】:

“我发现在活动中可能是指示这种情况的静态字段..”我在不同的项目中有服务和应用程序,这更难以访问其他类,另外并询问如何尽可能避免在它们之间的代码中创建依赖关系。 他们在不同的项目中,但这并不重要。只需使用整个路径“packagename.class.isRunning”即可获得相同的结果。 好的,我明白了,但它迫使我添加到服务的构建路径、应用程序项目的路径,并且在我的情况下,我已经依赖于应用程序到服务。 Eclipse 显示具有循环依赖的错误,我设法改变显示该消息,如警告而不是错误。是否可以通过不同的方法来管理?【参考方案2】:

您可以在活动中使用静态变量。

class MyActivity extends Activity 
     static boolean active = false;

      @Override
      public void onStart() 
         super.onStart();
         active = true;
       

      @Override
      public void onStop() 
         super.onStop();
         active = false;
      

添加just check in service为

if(MyActivity.active)

//send broadcast.

或 用这个来检查活动的状态是否处于活动状态

public boolean isRunning(Context ctx) 
        ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
        List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);

        for (RunningTaskInfo task : tasks) 
            if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName())) 
                return true;                                  
        

        return false;
    

【讨论】:

“我发现在活动中可能是指示这种情况的静态字段..”我在不同的项目中有服务和应用程序,这更难以访问其他类,另外并询问如何尽可能避免在它们之间的代码中创建依赖关系。 或者您可以使用它的包名称以及(packagename.activityClass.active)检查指定应用程序中的活动 请看我对 Carnal 评论的回答,答案是一样的 :)【参考方案3】:

我会在服务中有一个本地布尔变量:

protected boolean mIsAppRunning;

当应用程序恢复/停止时,使用 true/false 额外调用 startService()

@Override
protected void onResume() 
    super.onResume();
    Intent service = new Intent("my.service.ACTION");
    service.putExtra("IS_MY_ACTIVITY_RUNNING", true);
    startService(service);


@Override
protected void onPause() 
    Intent service = new Intent("my.service.ACTION");
    service.putExtra("IS_MY_ACTIVITY_RUNNING", false);
    startService(service);

在服务的onStartCommand() 中检查该额外内容并将其值分配给mIsAppRunning

@Override
public int onStartCommand(Intent intent, int flags, int startId) 
    if (intent != null) 
        mIsAppRunning = intent.getBooleanExtra("IS_MY_ACTIVITY_RUNNING", false);
    

    return START_STICKY;

如果稍微仔细设计服务中的逻辑,甚至可以去掉局部变量mIsAppRunning,根据intent extra value调用需要的方法。

希望这会有所帮助。

【讨论】:

以上是关于仅在活动运行时将意图从服务发送到活动的主要内容,如果未能解决你的问题,请参考以下文章

将意图从服务发送到活动

单击通知时将数据发送到活动?

如何将数据从活动传递到正在运行的服务

将数据从通知发送到活动类而不重新启动意图

发现 Android 活动是不是正在运行

如何在 FAB 按钮单击时将数据从多个片段发送到单个活动