如何创建一个Java函数,该函数一旦被调用,除非有延迟,否则不能再次被调用?

如何创建一个Java函数,该函数一旦被调用,除非有延迟,否则不能再次被调用?,java,android,Java,Android,我正在尝试创建一个函数,该函数只能在两次调用之间有一定的时间延迟(例如5秒)后才能再次调用 我需要为我正在创建的android应用程序提供此功能。 由于用户可能会在几秒钟内过于频繁地调用该函数,这将破坏他的体验。因此,我在拼命寻找答案 public void doSomethin(){ //code here which makes sure that this function has not been called twice within the specified delay of 5

我正在尝试创建一个函数,该函数只能在两次调用之间有一定的时间延迟(例如5秒)后才能再次调用

我需要为我正在创建的android应用程序提供此功能。 由于用户可能会在几秒钟内过于频繁地调用该函数,这将破坏他的体验。因此,我在拼命寻找答案

public void doSomethin(){
//code here which makes sure that this function has not been called twice within the specified delay of 5 seconds
//Some code here
}
任何帮助都会很棒!
Adit

您可以以毫秒为单位保留时间,并检查当前时间是否大于或等于前一时间+5秒。如果是,则执行该方法并用当前时间替换上一个时间


使用一个静态字段,它保存上次执行的日期时间,并在执行之前根据此时间戳检查当前日期时间。

我不会为您编写代码,但如果您仔细考虑一下,这并不难。您要确保在上次函数调用后5秒之前未调用它。让我们把它分成几个部分

1) 获取当前时间 2) 与在两次调用之间保持其值的存储时间进行比较。 3) 如果少于5秒,不要做任何事情
4) 否则,请存储新值并执行操作。

一个问题是,您必须为每个用户设置会话级计时器。这可能是相当大的开销,具体取决于您同时拥有多少用户

对于一个用户来说很容易:根据请求启动计时器。问题在于区分不同的用户。您的服务现在是有状态的,这通常是一件坏事。你在放弃幂等性

您还可以维护数据库中的状态。不要担心电话;检查持久性操作以确保它们不会发生得太频繁

我不清楚您是想在任何人调用该方法后五秒钟内排除所有用户,还是在第一次调用该方法后五秒钟内阻止每个用户再次调用该方法


这听起来像一个吞吐量杀手。我会重新考虑这个设计。

我从来没有用安卓系统编码过。但如果Android有线程(很可能是这样)。然后在这个函数中,让线程休眠5秒钟,这意味着即使调用了它,它也不会继续执行,直到5秒钟过去

public void doSomething()
{
  Thread.sleep(5000);  // Please find the corresponding Android method
}
doSomethin()
作为私有方法

Expose另一个函数,比如exposedDoSomething()


在一个单独的线程中,每5分钟读取一次队列,然后调用
doSomethin()

也许一个TimerTask可以帮助您,更多详细信息如下:

例如:

    private TimerTask tiemrTast= new TimerTask() {

    @Override
    public void run() {


    }
};

然后使用此方法:
public void scheduleAtFixedRate(TimerTask任务,长延迟,长周期)
如果代码在主线程上运行,
thread.sleep(5000)
不是选项。最简单的方法是:

private long previous = 0;
public void doSomething() {
    long now = Calendar.getInstance().getTimeInMillis();
    if (now - previous < 5000)
        return;

    previous = now;
    // do something
}
private long-previous=0;
公共无效剂量测定法(){
long now=Calendar.getInstance().getTimeInMillis();
如果(现在-以前<5000)
返回;
以前=现在;
//做点什么
}

您可以使用hander.postDalayed方法调用方法在特定延迟后运行 你可以用这样的方法

int delay=5000;
int k;
int iDelayTimeInMiliSeconds=2000;
                    for( k=0;k<arrBatch.size();k++)
                    {           
                        delay=delay+iDelayTimeInMiliSeconds;
                        callAllDocumentList(arrBatch.get(k),k,delay);                               
                    }   


public void callAllDocumentList(final String strInvoiceId,final int count,int delay) 
{
    mHandler.postDelayed(new Runnable() 
    {

        @Override
        public void run() 
        {   
               // call your function here that you want to call after specific delay
            //getOrderDetails(strInvoiceId,count,true);

        }
    }, delay);
}
int延迟=5000;
int k;
int-idelaytimein毫秒=2000;

对于(k=0;kdo)你想要一个java程序每5秒执行一次吗?公共同步的void doSomethin()@PC不只是为了线程安全而同步吗?是的,但它可能实现了他所需要的。如果计时器还没有过期,那么创建一个单例就不难了。但是如果你想要无法调用的东西,那就更难了(而且可能不必要地复杂,这取决于您试图做什么).我认为在提出任何具体建议之前,我们需要更多的细节。除非该方法是同步的,否则多个线程可以调用此并行。在Android上,你需要小心,因为你不应该让主线程睡眠,让你的应用程序没有响应。你是对的,但对于这么简单的答案,几行Js将有助于新手对语言的理解不止于此link@Basic:你是对的,我添加了一个小示例来展示我所说的内容。你的答案也是对的,我唯一需要更改的是
previous=now
行需要处于if条件下!@AditGupta我怀疑,这意味着如果你每隔一秒调用一次函数nd,
do something
从未执行过。不!这意味着只要if条件的内部部分运行,我就把它算作上一次调用。在你的代码中,如果这个人每隔一秒调用一次函数,它将永远不会运行。在我的代码中,它将每五次运行一次(因为>5000毫秒)!!假设我们从时间0开始,每秒调用一次此函数。在我的代码中:调用1:previous==0,now==1000=>return(previous not updated)。调用2:previous==0,now==2000=>return(previous not updated)…调用5:previous==0,now==5000=>previous=5000;做点什么。在你的版本中:调用1:previous==0,now==1000=>previous=1000;return。调用2:previous==1000,now==2000=>previous=2000;return…调用5:previous==4000,now==5000=>previous=5000;return。那么我的代码怎么错了?糟糕!!!我看到了(现在previous>5000)而不是您所写的内容。然后我//在if条件内执行一些操作!抱歉,Heuster!无论如何,谢谢!:)
private long previous = 0;
public void doSomething() {
    long now = Calendar.getInstance().getTimeInMillis();
    if (now - previous < 5000)
        return;

    previous = now;
    // do something
}
int delay=5000;
int k;
int iDelayTimeInMiliSeconds=2000;
                    for( k=0;k<arrBatch.size();k++)
                    {           
                        delay=delay+iDelayTimeInMiliSeconds;
                        callAllDocumentList(arrBatch.get(k),k,delay);                               
                    }   


public void callAllDocumentList(final String strInvoiceId,final int count,int delay) 
{
    mHandler.postDelayed(new Runnable() 
    {

        @Override
        public void run() 
        {   
               // call your function here that you want to call after specific delay
            //getOrderDetails(strInvoiceId,count,true);

        }
    }, delay);
}