自學(xué)HarmonyOS應(yīng)用開發(fā)(61)- 使用異步派發(fā)任務(wù)后臺(tái)更新地圖數(shù)據(jù)

當(dāng)?shù)谝淮伪硎灸车氐牡貓D數(shù)據(jù)時(shí),由于數(shù)據(jù)需要從網(wǎng)絡(luò)下載,因此會(huì)造成初次表示時(shí)間過長而影響響應(yīng)速度的問題。我們使用異步派發(fā)任務(wù)解決這個(gè)問題。先看顯示效果:
我們甚至可以在地圖更新過程中拖動(dòng)地圖。
畫面更新時(shí)記錄需要獲得的地圖數(shù)據(jù)
以下是描畫地圖數(shù)據(jù)的代碼:
private void drawTiles(Canvas canvas){int tileCol = Tile.getTileX(location.lon, zoom);int tileRow = Tile.getTileY(location.lat, zoom);Map<Pair<Integer,Integer>, Tile> missingTile = new HashMap<Pair<Integer,Integer>, Tile>();Paint paint = new Paint();for (int col = tileCol - 1; col <= tileCol + 1; col++) {for (int row = tileRow - 1; row <= tileRow + 1; row++) {Tile tile = mapData.getData(mapSource, zoom, col, row);if (tile != null) {Size offset = tile.calculateOffset(location);canvas.drawPixelMapHolder(tile,getWidth() / 2 + offset.width,getHeight() / 2 + offset.height,paint);} else {missingTile.put(new Pair<Integer, Integer>(row, col), null);}}}if (missingTile.size() > 0) {loadMapTile(missingTile);}}
如果需要的數(shù)據(jù)不在地圖數(shù)據(jù)緩存中,就將該地圖瓦片的坐標(biāo)存儲(chǔ)在missingTile中(代碼第16行)。等到本輪描畫結(jié)束后,調(diào)用loadMapTile方法啟動(dòng)后臺(tái)數(shù)據(jù)獲取過程。
異步獲取和更新地圖數(shù)據(jù)
代碼第5行啟動(dòng)異步派發(fā)任務(wù)根據(jù)missingTile中存儲(chǔ)的坐標(biāo)獲取相應(yīng)的地圖數(shù)據(jù)。需要注意的是第8行到第18行是在UI以外的上下文中執(zhí)行的。
public void loadMapTile(Map<Pair<Integer,Integer>, Tile> missingTile){????if(loadMapTileRevocable?!=?null)?{return;}loadMapTileRevocable = getContext().getGlobalTaskDispatcher(TaskPriority.HIGH).asyncDispatch(new Runnable() {public void run() {int tileCol = Tile.getTileX(location.lon, zoom);int tileRow = Tile.getTileY(location.lat, zoom);boolean need_update = false;for(Pair<Integer, Integer> pair : missingTile.keySet()){Tile tile = Tile.createTile(mapSource, pair.s, pair.f, zoom);if(tile != null) {missingTile.put(pair, tile);need_update = true;}}getContext().getUITaskDispatcher().asyncDispatch(new Runnable() {public void run() {for(Pair<Integer, Integer> pair : missingTile.keySet()){Tile tile = missingTile.get(pair);if(tile != null){mapData.setData(mapSource, zoom, pair.s, pair.f, tile);}}TileMap.this.invalidate();loadMapTileRevocable = null;}});}});}
代碼18行發(fā)起一個(gè)UI線程中的異步任務(wù)將獲得的地圖數(shù)據(jù)保存到地圖緩存中。之所以沒有直接在獲取時(shí)直接存儲(chǔ)是因?yàn)樾枰苊舛嗳蝿?wù)同時(shí)訪問地圖存儲(chǔ)。
地圖數(shù)據(jù)保存完了之后,再發(fā)起一次畫面更新即可。如果還有沒有獲取的數(shù)據(jù),繼續(xù)上面的過程。
參考代碼
https://github.com/xueweiguo/Harmony/tree/master/StopWatch
作者著作介紹
《實(shí)戰(zhàn)Python設(shè)計(jì)模式》是作者去年3月份出版的技術(shù)書籍,該書利用Python 的標(biāo)準(zhǔn)GUI 工具包tkinter,通過可執(zhí)行的示例對23 個(gè)設(shè)計(jì)模式逐個(gè)進(jìn)行說明。這樣一方面可以使讀者了解真實(shí)的軟件開發(fā)工作中每個(gè)設(shè)計(jì)模式的運(yùn)用場景和想要解決的問題;另一方面通過對這些問題的解決過程進(jìn)行說明,讓讀者明白在編寫代碼時(shí)如何判斷使用設(shè)計(jì)模式的利弊,并合理運(yùn)用設(shè)計(jì)模式。

對設(shè)計(jì)模式感興趣而且希望隨學(xué)隨用的讀者通過本書可以快速跨越從理解到運(yùn)用的門檻;希望學(xué)習(xí)Python GUI 編程的讀者可以將本書中的示例作為設(shè)計(jì)和開發(fā)的參考;使用Python 語言進(jìn)行圖像分析、數(shù)據(jù)處理工作的讀者可以直接以本書中的示例為基礎(chǔ),迅速構(gòu)建自己的系統(tǒng)架構(gòu)。
覺得本文有幫助?請分享給更多人。
關(guān)注微信公眾號(hào)【面向?qū)ο笏伎肌枯p松學(xué)習(xí)每一天!
面向?qū)ο箝_發(fā),面向?qū)ο笏伎迹?/span>
