android客户端需要定时调用服务器端的URI Rest获取数据,以往用while+sleep控制起来很麻烦,指不定的各种异常,所以想用个轻量级的任务调度框架去实现,看到了Cron4j,拿来试试,可以发博客或者写成文档作为组织过程资产。
1 资源
下载地址: http://www.sauronsoftware.it/projects/cron4j/download.php
manual: http://www.sauronsoftware.it/projects/cron4j/manual.php
2 scheduling pattern
5 * * * *
This pattern causes a task to be launched once every hour, at the begin of the fifth minute (00:05, 01:05, 02:05 etc.).
This pattern causes a task to be launched every minute.
This pattern causes a task to be launched every minute during the 12th hour of Monday.
This pattern causes a task to be launched every minute during the 12th hour of Monday, 16th, but only if the day is the 16th of the month.
This pattern causes a task to be launched at 11:59AM on Monday, Tuesday, Wednesday, Thursday and Friday.
This pattern is equivalent to the previous one.
This pattern causes a task to be launched every 5 minutes (0:00, 0:05, 0:10, 0:15 and so on).
This pattern causes a task to be launched every 5 minutes starting from the third minute of the hour, up to the 18th (0:03, 0:08, 0:13, 0:18, 1:03, 1:08 and so on).
This pattern causes a task to be launched every 15 minutes between the 9th and 17th hour of the day (9:00, 9:15, 9:30, 9:45 and so on... note that the last execution will be at 17:45).
This pattern causes a task to be launched every minute during the 12th hour of the day, but only if the day is the 10th, the 12th, the 14th or the 16th of the month.
This pattern causes a task to be launched every minute during the 12th hour of the day, but the day of the month must be between the 1st and the 15th, the 20th and the 25, or at least it must be the 17th.
This pattern causes a task to be launched every day at 05:00, 10:08 and 17:22.
* * * * *
* 12 * * Mon
* 12 16 * Mon
Every sub-pattern can contain two or more comma separated values.
59 11 * * 1,2,3,4,5
Values intervals are admitted and defined using the minus character.
59 11 * * 1-5
The slash character can be used to identify step values within a range. It can be used both in the form */c and a-b/c. The subpattern is matched every c values of the range 0,maxvalue or a-b.
*/5 * * * *
3-18/5 * * * *
*/15 9-17 * * *
All the fresh described syntax rules can be used together.
* 12 10-16/2 * *
* 12 1-15,17,20-25 * *
Finally cron4j lets you combine more scheduling patterns into one, with the pipe character:
0 5 * * *|8 10 * * *|22 17 * * *
This pattern causes a task to be launched once every hour, at the begin of the fifth minute (00:05, 01:05, 02:05 etc.).
This pattern causes a task to be launched every minute.
This pattern causes a task to be launched every minute during the 12th hour of Monday.
This pattern causes a task to be launched every minute during the 12th hour of Monday, 16th, but only if the day is the 16th of the month.
This pattern causes a task to be launched at 11:59AM on Monday, Tuesday, Wednesday, Thursday and Friday.
This pattern is equivalent to the previous one.
This pattern causes a task to be launched every 5 minutes (0:00, 0:05, 0:10, 0:15 and so on).
This pattern causes a task to be launched every 5 minutes starting from the third minute of the hour, up to the 18th (0:03, 0:08, 0:13, 0:18, 1:03, 1:08 and so on).
This pattern causes a task to be launched every 15 minutes between the 9th and 17th hour of the day (9:00, 9:15, 9:30, 9:45 and so on... note that the last execution will be at 17:45).
This pattern causes a task to be launched every minute during the 12th hour of the day, but only if the day is the 10th, the 12th, the 14th or the 16th of the month.
This pattern causes a task to be launched every minute during the 12th hour of the day, but the day of the month must be between the 1st and the 15th, the 20th and the 25, or at least it must be the 17th.
This pattern causes a task to be launched every day at 05:00, 10:08 and 17:22.
* * * * *
* 12 * * Mon
* 12 16 * Mon
Every sub-pattern can contain two or more comma separated values.
59 11 * * 1,2,3,4,5
Values intervals are admitted and defined using the minus character.
59 11 * * 1-5
The slash character can be used to identify step values within a range. It can be used both in the form */c and a-b/c. The subpattern is matched every c values of the range 0,maxvalue or a-b.
*/5 * * * *
3-18/5 * * * *
*/15 9-17 * * *
All the fresh described syntax rules can be used together.
* 12 10-16/2 * *
* 12 1-15,17,20-25 * *
Finally cron4j lets you combine more scheduling patterns into one, with the pipe character:
0 5 * * *|8 10 * * *|22 17 * * *
3 与android项目集成
3.1 加入支持jar包:
将cron4j-2.2.5.jar和commons-httpclient.jar放入libs文件夹,注意不用去手动“Add to Build Path”.
3.2 创建android项目,代码结构如下:
3.2.1 入口类 MainActivity.java
package com.zf.cron4j;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import com.zf.cron4j.service.AppService;
/**
* @author 曾凡
* @time 2014年6月11日 上午9:12:13
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setContentView(R.layout.activity_main);
startService(new Intent(this, AppService.class));
}
}<span style="font-weight: bold;">
</span>
3.2.2 后台服务类,用来定时访问服务器 AppService.java
package com.zf.cron4j.service;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import com.zf.cron4j.schedule.RequestServerSchedule;
/**
* 一个APP尽量只创建一个Service,越少越好
*
* @author 曾凡
* @time 2014年6月11日 下午12:48:52
*/
public class AppService extends Service {
@Override
public IBinder onBind(Intent arg0) {
return null;
}
/**
* 避免出现主线程调用网络连接的错误
*/
public Handler requestServerHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
new RequestServerThread().start();
}
};
@Override
public void onCreate() {
super.onCreate();
requestServerHandler.sendMessage(new Message());
}
private class RequestServerThread extends Thread {
@Override
public void run() {
new RequestServerSchedule();
}
}
}<span style="font-weight: bold;">
</span>
3.2.3 任务调度 RequestServerSchedule.java
package com.zf.cron4j.schedule;
import it.sauronsoftware.cron4j.Scheduler;
/**
* 请求服务器的任务调度
*
* @author 曾凡
* @time 2014年6月11日 下午12:50:13
*/
public class RequestServerSchedule {
public RequestServerSchedule() {
/* 实例化任务 */
ServerRequestTask task = new ServerRequestTask();
/* 启动任务调度 */
Scheduler scheduler = new Scheduler();
/* 一分钟请求一次服务器 */
scheduler.schedule("* * * * *", task);
scheduler.start();
}
}
3.2.4 需要执行的任务 ServerRequestTask
package com.zf.cron4j.schedule;
import it.sauronsoftware.cron4j.Task;
import it.sauronsoftware.cron4j.TaskExecutionContext;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.util.Log;
public class ServerRequestTask extends Task {
/** 公交的一个测试地址 */
private String URI_PATH = "http://218.28.136.21:8081/gps.asp?xl=126%E8%B7%AF&ud=0&fx=%E4%BA%AC%E5%B9%BF%E8%B7%AF%E5%8D%97%E7%8E%AF%E8%B7%AF%E7%AB%99&sno=1&hczd=%E4%BA%94%E9%BE%99%E5%8F%A3&ref=4";
public static final int CONNECT_TIMEOUT = 6 * 10000;
public boolean canBePaused() {
return true;
}
public boolean canBeStopped() {
return true;
}
public boolean supportsCompletenessTracking() {
return true;
}
public boolean supportsStatusTracking() {
return true;
}
/**
* 执行的任务
*
* @author 曾凡
* @param context
* @throws RuntimeException
* @time 2014年6月11日 下午12:35:54
*/
public void execute(TaskExecutionContext context)
throws RuntimeException {
try {
URL url = new URL(URI_PATH);// :获取的路径
// :http协议连接对象
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(6 * CONNECT_TIMEOUT);
if (conn.getResponseCode() < CONNECT_TIMEOUT) {
InputStream inputStream = conn.getInputStream();
byte[] b = new byte[1024];
int length = inputStream.read(b);
Log.i("cron4j", "页面输出:");
Log.i("cron4j", new String(b, 0, length));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
4 输出结果
5 注意事项
5.1 解析html
可以用jsoup-1.7.3.jar,<span style="color:#ff0000;">高版本jsoup不兼容低版本android</span>。5.2 Service是后台线程
可以用来接受报警信息,注意测试完了要手动关闭,否则浪费流量:源代码如下