若是你正在找Android后台定时任务实现,那么你找对了,可是其实若是你正在找Java后台任务实现,你就不会找到个人这个博客了.可是个人实现方式没有使用多少Android相关的东西.确实.可是若是你进来了,Thank you!你仍是会看到一些东西的.java
一:需求: 个人一些数据一开始是从服务端读取出来的,可是随着时间的改变,我本地改变了一些数据.服务器的一些数据也发生了改变.一开始,但用户查看这些数据的时候,我再去服务器上将数据下载下来. 可是每次去下,有些数据变化不太.这个下载操做的的很大一部分就是白下载了.因此我开始探索解决方案:android
二:解决方案:数据库
(1) 下载前先检测服务端数据是否有发生了变化.数据库中的每一行记录都有一个字段标识数据是否发生改变了的时间.缓存
因而先下载数据库记录最后改变时间. 我用前次下载得来的最后改变时间与当前下载得的时间对比.若是下载回来的时间大于我原来存储的时间.那么我便决定去下载数据....就这样它一直工做着.. 我以为这样能够了.服务器
可是,后来出现了数据没有同步的问题.由于有些对于数据记录的操做并无改变那个标识了时间改变的字段.网络
因此方法失效. ide
(2)保证因此操做都改变时间标识字段.线程
这个方法有几点行不通,这个应用自己是从原来已经有的应用移植.因此服务端的后台数据库不能轻易改变.改变了也比较难以保证因此用户得及时更新的服务器中后台数据库.code
最关键的是若是后台数据更新频繁,事实上咱们的应用就是这样的.那么检测更新没有多大意义.由于几乎每次检测的结果都是须要更新. 在更新这个时间里,由于网络不稳定问题.用户等待时间过久.用户体验就明显降低了.这个检测更新也就彻底没有什么意义了.内存
(3) 目前解决办法.
使用一个后台线程以一个比较合理的频率定时更新数据.
针对后台线程,因为作android开发的习惯.咱们可能会想到使用Service.
可是真的须要Service吗?一开始我尝试这样,因而开始找Service的资料.我认可我对Service不熟悉...
我只使用绑定本地Service的方法,每次Activity建立就会从新绑定一次.但那没有关系.由于当时那个LocalService是读取SQLite数据库中的数据了.并且只读取一次放到缓存中(其实就是内存).
可是经过绑定的方法每次Activity启动等都会建立而后销毁服务.因而我就不想要了..
我但愿个人应用启动前开始个人后台线程,结束时取消后台线程..仅此而已.因而我找其它的方式.如startService和stopService等方式,及为了让服务不被Android给杀掉能够把服务设置为前台服务.
可是,后台线程,为何必定要用Service呢?我想,我所要进行的操做根据不须要Service.
还记得没有,想要在应用中全局共享变量,一个方法就是给应用设置一个本身子类化的Application.
可是,我看文档时发现,其实若是没有必要你根本可使用一个静态单例来实现相似Application子类的功能.
我是比较据说的人,因此我就按文档要求的,本身实现静态单例了.须要使用Context的方法传进去就是了.
说了这么多,其实就是说,咱们彻底能够不用理会Service,应用就是在本地应用中使用.在本身的静态单例中实现就能够了.
而我确实也是这样作的.
在应用的主Activity的onCreate()方法中开始后台线程的执行.在此Activity的onDestory()方法中.结束后台线程的执行.
OK,知足需求了.
关键代码以下 :
public static void startSyncTableStauts(int seconds) { TimerTask timerTask = new TableStatusSyncTimerTask(); timer = new Timer(true); timer.scheduleAtFixedRate(timerTask, 100, seconds * 1000); } public static void stopSyncTableStatus() { timer.cancel(); cachedFloors.clear(); cachedTables.clear(); } private static class TableStatusSyncTimerTask extends TimerTask { @Override public void run() { if (cachedFloors.size() < 1) { try { setFloors(FloorDao.findAll()); } catch (TcpException e) { // TODO Auto-generated catch block e.printStackTrace(); } } for (Floor floor : cachedFloors) { try { List<Table> tables = TableDao.findByFloorId(floor.id); statusMap.put(floor.id, false); for (Table table : tables) { String key = floor.id + "#" + table.getTabid(); cachedTables.put(key, table); } statusMap.put(floor.id, true); Log.i("DiApplication", " finish update table in floor:" + floor.id); } catch (TcpException e) { // TODO: handle exception e.printStackTrace(); } } } } public static synchronized void setFloors(List<Floor> floors) { if (hasFloor()) return; cachedFloors.addAll(floors); }
为何要使用同步,由于我执行的是网络操做,若是后台线程尚未取回数据.我在前台程序中,就会本身主动去下载数据.
(为何不等待数据有的时候. 由于若是网络出错.仍是在前台程序中处理比较好.要让用户看到.) 下载好以后就将数据放到缓存中,由于是用List的因此不想出现线程问题因此就用同步了...
整个对于缓存的使用的应用代码也是放在AsyncTask内的doInBackground()内中去的.因此应用体验就比较好的.
暂时写到这里.如什么不正确的地方请各位同窗指出来哈!