Android中後臺定時任務實現,即時數據同步問題思考!

若是你正在找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()內中去的.因此應用體驗就比較好的.

 

暫時寫到這裏.如什麼不正確的地方請各位同窗指出來哈!

相關文章
相關標籤/搜索