【Android 开发教程】在服务中执行重复任务

时间:2022-02-23 04:40:24

本章节翻译自《Beginning-Android-4-Application-Development》,如有翻译不当的地方,敬请指出。

原书购买地址http://www.amazon.com/Beginning-Android-4-Application-Development/dp/1118199545/


除了在service中执行耗时的操作,也可能需要在service中执行重复的任务。举个例子,你想要编写一个闹钟程序,定时地在后台执行一个任务。在这种情况下,你的service就需要判断循环周期是否已经到达。可以使用Timer类去实现。

1. 使用之前的Services工程,做一点修改。

public class MyService extends Service {    int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();

@Override
public IBinder onBind(Intent arg0) {
return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
new DoBackgroundTask().execute(urls);
return START_STICKY;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.

// Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();

doSomethingRepeatedly();

try {
new DoBackgroundTask().execute(
new URL("http://www.amazon.com/somefiles.pdf"),
new URL("http://www.wrox.com/somefiles.pdf"),
new URL("http://www.google.com/somefiles.pdf"),
new URL("http://www.learn2develop.net/somefiles.pdf"));

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

return START_STICKY;
}

private void doSomethingRepeatedly() {
timer.scheduleAtFixedRate( new TimerTask() {
public void run() {
Log.d("MyService", String.valueOf(++counter));
}
}, 0, UPDATE_INTERVAL);
}

private int DownloadFile(URL url) {
try {
//---simulate taking some time to download a file---
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//---return an arbitrary number representing
// the size of the file downloaded---
return 100;
}

private class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalBytesDownloaded = 0;
for (int i = 0; i < count; i++) {
totalBytesDownloaded += DownloadFile(urls[i]);
//---calculate percentage downloaded and
// report its progress---
publishProgress((int) (((i+1) / (float) count) * 100));
}
return totalBytesDownloaded;
}

protected void onProgressUpdate(Integer... progress) {
Log.d("Downloading files",
String.valueOf(progress[0]) + "% downloaded");
Toast.makeText(getBaseContext(),
String.valueOf(progress[0]) + "% downloaded",
Toast.LENGTH_LONG).show();
}

protected void onPostExecute(Long result) {
Toast.makeText(getBaseContext(),
"Downloaded " + result + " bytes",
Toast.LENGTH_LONG).show();
stopSelf();
}
}

@Override
public void onDestroy() {
super.onDestroy();

if (timer != null){
timer.cancel();
}

Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}

2. 调试。查看系统的日志。

【Android 开发教程】在服务中执行重复任务


在这个例子中,首先创建一个Timer对象,然后调用scheduleAtFixedRate()方法:

    private void doSomethingRepeatedly() {        timer.scheduleAtFixedRate( new TimerTask() {            public void run() {                Log.d("MyService", String.valueOf(++counter));            }        }, 0, UPDATE_INTERVAL);    }

传入一个TimerTast对象,这样在run()方法就可以执行重复任务了。同事可以设置两次执行任务的间隔。

最后,在onDestroy()里面调用timer对象的cancel()方法。

@Overridepublic void onDestroy() {super.onDestroy();        if (timer != null){            timer.cancel();        }Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();}