Java 再次运行服务,但在其当前执行完成后

Java 再次运行服务,但在其当前执行完成后,java,android,multithreading,concurrency,Java,Android,Multithreading,Concurrency,我会尽量保持简短。我有一个带有广播接收器的前台服务a。有时它会调用服务B两次 我希望服务B首先完成它的执行,如果另一个请求再次运行它,它应该一直等待,直到较早的执行完成。这就是为什么我将服务B创建为IntentService。但由于呼叫日志仍未更新,我正在休眠服务B 2秒钟 但当我在IntentService中实现runnable…,它会保留其原始行为,如果出现另一个请求,两个请求都会同时运行服务B 我的服务广播接收器: Log.d("RECEIVER X: ", "CALL ENDS H

我会尽量保持简短。我有一个带有
广播接收器的
前台服务a
。有时它会调用
服务B
两次


我希望
服务B
首先完成它的执行,如果另一个请求再次运行它,它应该一直等待,直到较早的执行完成。这就是为什么我将服务B创建为
IntentService
。但由于呼叫日志仍未更新,我正在休眠服务B 2秒钟


但当我在IntentService中实现runnable…,它会保留其原始行为,如果出现另一个请求,两个请求都会同时运行服务B


我的服务广播接收器:

Log.d("RECEIVER X: ", "CALL ENDS HERE...");
Intent SendSMS = new Intent(context, SendSMS.class);
startService(SendSMS);

我的意向服务:

    public class SendSMS extends IntentService
    {
    public Boolean IsRunning = false;

    public SendSMS()
    {
    super("SendSMS");
    Log.d("SendSMS : ", "\nOnCreate...");
    }

    @Override
    protected void onHandleIntent(Intent intent)
    {

        new Thread(new Runnable()
        {
            public void run()
            {

                if(IsRunning == false)
                {
                    IsRunning = true;
                    Thread.sleep(2000);
                    // perform operations here...
                }
            }
        }).start();
    }
    }
private BroadcastReceiver mCallBroadcastReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        String action = intent.getAction();

        if (action.equalsIgnoreCase("android.intent.action.PHONE_STATE"))
        {
            if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING))
            {
                Log.d("RECEIVER X: ", "INCOMING CALL...");
            }
            if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE))
            {
                Log.d("RECEIVER X: ", "CALL ENDS HERE...");
                Intent Dispatcher = new Intent(context, CatchNumbers.class);
                startService(Dispatcher);
            }
            if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
            {
                Log.d("RECEIVER X: ", "ACTIVE CALL GOING ON...");
            }
        }
    }
};


我的操作应该执行两次,但在第一次操作完成后,睡眠时间为2秒。任何帮助都将不胜感激。感谢您提供的高级

我的应用程序针对api 17中的api级别26。但在Oreo及以上版本中,不允许实现静态接收器。(很少有像
BOOT\u COMPLETED
这样的意图操作仍然被接受。但是我想实现
PHONE\u STATE
。根据文档,我已经在前台服务中实现了它。如下所示:


前台服务中的运行时接收器:

private BroadcastReceiver mCallBroadcastReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        String action = intent.getAction();

        if (action.equalsIgnoreCase("android.intent.action.PHONE_STATE"))
        {
            if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING))
            {
                Log.d("RECEIVER X: ", "INCOMING CALL...");
            }
            if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE))
            {
                Log.d("RECEIVER X: ", "CALL ENDS HERE...");
                Intent Dispatcher = new Intent(context, CatchNumbers.class);
                startService(Dispatcher);
            }
            if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
            {
                Log.d("RECEIVER X: ", "ACTIVE CALL GOING ON...");
            }
        }
    }
};

在这里你可以看到,我正在调用我的
CatchNumbers
。是的,我只调用了一次,但因为只有在ANDROID 5.0和5.1 GOOGLE BUG中,它会触发
所有状态
两次。
因此在这里发布了上述问题
,即如何禁止两个并发线程运行相同的服务


CatchNumbers
中:

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    new Thread(new Runnable()
    {
        public void run()
        {
            try
            {
                Thread.sleep(2000);
                Log.d("CatchNumbers : ", "\nDispatched Call ...");

                Intent SendSMS = new Intent(CatchNumbers.this, SendSMS.class);
                startService(SendSMS);
            }
            catch (InterruptedException e)
            {
                Log.d("CatchNumbers : ", "Thread : InterruptedException Error in service...\n");
                Log.e("CatchNumbers : ", "Exception is : ", e);
            }
        }
    }).start();

    return super.onStartCommand(intent, flags, startId);
}
在引导对同一
SendSMS
服务的并发调用之前,请在2秒的可运行睡眠时间内执行此操作,然后仅将其分派给运行IntentService工作线程


现在,由于Intent Service不允许运行多个实例…其他请求仍在等待,直到第一次
SendSMS
执行完成。现在,亲爱的XY LOVER..,由于android 5.0和5.1触发了两次相同的事件,调用任何服务都会有问题..,这会导致数据丢失…因此决定从调用中获取它_改为日志。一旦调用状态变为空闲状态。同样的问题是,对该意向服务的并发调用,所以这样解决了它。我也尝试在意向服务中实现runnable,但由于它,意向服务失去了将下一个请求保持在等待状态直到当前执行结束的属性。并且两个请求都在运行IntentService Conc当前导致数据丢失



现在我的Intent服务没有可运行的方法。

我终于得到了它。你不应该使用IntentService,因为它会在你从onHandleIntent.Subclass服务返回后自动调用stopSelf。我的意思是isrunning var被蒸发掉。所以你有
BroadcastReceiver
android.Intent.action.PHONE\u状态触发行动,它被调用两次,对吗?现在想象一下你家的屋顶漏水,当雨水损坏你的房间时,在这种情况下你会怎么做?你真的建立了一个排水管道系统,还是仅仅修复屋顶上的洞?你的解决方案只不过是一个糟糕的解决办法,如果你在g上花了5分钟oogling你会找到简单的解决方案,你知道现在什么是
XY问题吗?@pskink,嗯…,我真的很感激。我正在研究它…让我看看…是的,它对我很有帮助,如果它真的是标准的,如果它在谷歌安卓开发者中被记录…我会要求你把它作为答案写下来,并接受它。一旦我发现这很有帮助。。仔细阅读。@pskink,该链接中的一些要点是:1)谷歌的文档记录非常糟糕。2) 订阅作为一般对象,因为它对于Android 5.0很长,对于Android 5.1很长。3) Android 6 subscription extra不再附带4)我个人发现谷歌文档非常糟糕,即使是api级别为26的文档,它们显示了对服务和广播的限制,但没有描述如何在服务运行时注册。它们只有一行context.register。在这种情况下,如何实现它已经有数千个案例支持4.1到Android P