How to loop a service?

2019-03-24 15:15发布

My service needs to check for something every minute and

while(true)
{
   Thread.sleep(60000) 
   //REST OF CODE HERE//
}

is not working. Making the application freeze and asking me to forcefully stop it.

I am sure the problem is with the while loop but I thought it was the only way to infinitely repeat the service whenever the onStart() method executes.

Any suggestions are appreciated.

EDIT

I fixed it and in case you were wondering how the code looks like well there you go:

@Override
public void onStart(Intent intent, int startId) {
    // TODO Auto-generated method stub
    super.onStart(intent, startId);
    Toast.makeText(this, "Service running", Toast.LENGTH_SHORT).show();

    handler = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            Toast.makeText(protectionService.this, "5 secs has passed", Toast.LENGTH_SHORT).show();
        }

    };



    new Thread(new Runnable(){
        public void run() {
        // TODO Auto-generated method stub
        while(true)
        {
           try {
            Thread.sleep(5000);
            handler.sendEmptyMessage(0);

        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

        }

                        }
    }).start();
}

Basically the service is been called and the tasks of that service will be repeated every 5 secs in that case.

I would like to thank vineetska, Janusz and inazaruk for suggesting to use Handlers. I would like to thank everyone who answered as well, your help was very much appreciated.

5条回答
霸刀☆藐视天下
2楼-- · 2019-03-24 15:33

create a thread in your service and put while loop there like this:

 new Thread(new Runnable(){
    public void run() {
    // TODO Auto-generated method stub
    while(true)
    {
       Thread.sleep(60000) 
       //REST OF CODE HERE//
    }

                    }
}).start();
查看更多
别忘想泡老子
3楼-- · 2019-03-24 15:36

As Janusz wrote, you can use handler to post delayed. Here is a sample:

final Handler handler = new Handler();
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // Do repeatable stuff
        handler.postDelayed(this, DELAYED_TIME);
    }
};
handler.post(runnable);

It will post runnable and then post it again and again after DELAYED_TIME.

查看更多
Root(大扎)
4楼-- · 2019-03-24 15:39

Each of lifecycle method of service is called from UI thread. If you need background task to be running all the time, you can crate new thread for this. This is actually very well described in documentation.

In your case however, you should consider using AlarmManager instead. It handles recurring events very well and was specifically designed for similar scenarios.

Another solution would be to use Handler and its postDelayed() function. This can be used when your operation (that should be executed every 60s) is not time-consuming (or otherwise you should still run it in background thread).

Overall, creating a thread that sleeps all the time is not a good solution for mobile devices. This consumes resources that could've been spent for something more useful. Especially considering a rich set of capabilities of Android for recurring events.

查看更多
在下西门庆
5楼-- · 2019-03-24 15:48

Services run on the main thread. If you want to offload processing, you have to start a separate thread. Have a look at IntentService, it does this by default. On another note, having an infinitely running service with sleep() might not a good idea. For scheduled processing, you might want to use AlarmManager.

查看更多
Explosion°爆炸
6楼-- · 2019-03-24 15:55

A service itself is not a subthread. This means that every code that is run in your service will be run on the main UI Thread. You need to start a Thread, or use an AsyncTask in your service to move the computation to the background.

Have a look at the documentation of service for more information.

If you want to repeat some code every minute you can use a handler.

A handler has a method called postDelayed this allows you to specify a time after which a runnable will be run. Just call the method again at the end of your runnable to rerun the code after a minute.

查看更多
登录 后发表回答