前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自学HarmonyOS应用开发(61)- 使用异步派发任务后台更新地图数据

自学HarmonyOS应用开发(61)- 使用异步派发任务后台更新地图数据

作者头像
面向对象思考
发布2021-08-06 13:17:15
5330
发布2021-08-06 13:17:15
举报

当第一次表示某地的地图数据时,由于数据需要从网络下载,因此会造成初次表示时间过长而影响响应速度的问题。我们使用异步派发任务解决这个问题。先看显示效果:

我们甚至可以在地图更新过程中拖动地图。

画面更新时记录需要获得的地图数据

以下是描画地图数据的代码:

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);
    }
}

如果需要的数据不在地图数据缓存中,就将该地图瓦片的坐标存储在missingTile中(代码第16行)。等到本轮描画结束后,调用loadMapTile方法启动后台数据获取过程。

异步获取和更新地图数据

代码第5行启动异步派发任务根据missingTile中存储的坐标获取相应的地图数据。需要注意的是第8行到第18行是在UI以外的上下文中执行的。

public void loadMapTile(Map<Pair<Integer,Integer>, Tile> missingTile){
    if(loadMapTileRevocable != null) {
        return;
    }
    loadMapTileRevocable = getContext().getGlobalTaskDispatcher(TaskPriority.HIGH).asyncDispatch(new Runnable() {
        @Override
        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() {
                @Override
                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行发起一个UI线程中的异步任务将获得的地图数据保存到地图缓存中。之所以没有直接在获取时直接存储是因为需要避免多任务同时访问地图存储。

地图数据保存完了之后,再发起一次画面更新即可。如果还有没有获取的数据,继续上面的过程。

参考代码

完整代码可以从以下链接下载:

https://github.com/xueweiguo/Harmony/tree/master/StopWatch

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面向对象思考 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 完整代码可以从以下链接下载:
相关产品与服务
图数据库 KonisGraph
图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档