专栏首页C++核心准则原文翻译自学HarmonyOS应用开发(55)- 使用对象关系映射数据库保存地图数据

自学HarmonyOS应用开发(55)- 使用对象关系映射数据库保存地图数据

前一篇文章实现了地图数据的正确表示,但是由于每次执行都需要至少一次从网上获取地图数据,不可避免地产生显示延迟。本文介绍利用对象数据库储存已经获取的地图数据,从而避免重复下载相同数据并大幅度提高初次显示速度的方法。

还是先看疗效:

配置“build.gradle”文件

修改对应HAP中的build.gradle文件,在ohos字段中增加compleOptions配置。

ohos {
    signingConfigs {
       ...
    }
    compileSdkVersion 5
    defaultConfig {
        compatibleSdkVersion 4
    }
    buildTypes {
        release {
            proguardOpt {
                proguardEnabled false
                rulesFiles 'proguard-rules.pro'
            }
        }
    }
    compileOptions{
        annotationEnabled true
    }
}

构建应用数据库

基本上不需要做什么,主要是在@Database宣言中声明两个数据表,这里我们只需要关注用来存储地图数据的TileDtata类。

@Database(entities = {TimeRecord.class, TileData.class}, version = 1)
public abstract class StopWatchDB extends OrmDatabase {
}

定义地图数据表类

首先在Entiry宣言中声明的表名和索引的构成。然后是字段的声明和每个字段的set和get方法。这些get和set方法都有固定的命名规则,不过不知道也没关系,编译出错时照着错误信息改就行了。

@Entity(tableName = "tile_data",
        indices = {@Index(value = {"type", "zoom", "tileX", "tileY"}, name = "tile_index", unique = true)})
public class TileData extends OrmObject {
    @PrimaryKey(autoGenerate = true)
    private Integer tileId;
    private Integer type;
    private Integer zoom;
    private Integer tileX;
    private Integer tileY;
    private Blob data;

    Integer getTileId(){
        return tileId;
    }

    void setTileId(Integer id){
        tileId = id;
    }

    Integer getType(){
        return type;
    }

    void setType(Integer t){
        type = t;
    }

    Integer getZoom(){
        return zoom;
    }

    void setZoom(int z){
        zoom = z;
    }

    Integer getTileX(){
        return tileX;
    }

    void setTileX(Integer x){
        tileX = x;
    }

    Integer getTileY(){
        return tileY;
    }

    void setTileY(Integer y){
        tileY = y;
    }

    Blob getData(){
        return data;
    }

    void setData(Blob _data){
        data = _data;
    }
}

本例中我们使用Blob类型保存地图数据,需要进行PixelMap和Blob之间的转换,为此我们准备了两个辅助方法:

void setPixelMap(PixelMap image){
    ImagePacker imagePacker = ImagePacker.create();
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
    packingOptions.quality = 100;
    imagePacker.initializePacking(os, packingOptions);
    imagePacker.addImage(image);
    imagePacker.finalizePacking();
    Blob blob = new Blob(os.toByteArray());
    setData(blob);
}

PixelMap getPixelMap(){
    InputStream is = getData().getBinaryStream();
    ImageSource source = ImageSource.create(is, new ImageSource.SourceOptions());
    ImageSource.DecodingOptions options = new ImageSource.DecodingOptions();
    options.desiredSize = new Size(512,512);
    return source.createPixelmap(options);
}

使用对象关系映射数据库

在应用启动时构建数据库:

DatabaseHelper helper = new DatabaseHelper(this);
OrmContext dbContext = helper.getOrmContext("StopWatch", "StopWatch.db", StopWatchDB.class);

使用数据库:

我们为地图数据设计了一个2级缓存类:一级是内存中的Map对象,二级是数据库:

public class TileDataStorage {
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00207, "TileMapData");
    Map<Tile.MapSource, Integer> typeMap = new HashMap<Tile.MapSource, Integer>(){{
        put(Tile.MapSource.GAODE_ROAD, 0);
        put(Tile.MapSource.GAODE_SATELLITE,1);
        put(Tile.MapSource.GAODE_VECTOR, 2);
    }};

    Map<String, Tile> mapData = new HashMap<String, Tile>();
    OrmContext db;

    void setDbContext(OrmContext context){
        db = context;
    }

    void setData(Tile.MapSource source, int zoom, int tile_x, int tile_y, Tile tile){
        HiLog.info(LABEL, "TileMapData.setData Start x=%{public}d, y=%{public}d, z=%{public}d!",
                                tile_x, tile_y, zoom);
        int type = typeMap.get(source);
        mapData.put(getKey(type, zoom, tile_x, tile_y), tile);
        TileData td = new TileData();
        td.setType(type);
        td.setZoom(zoom);
        td.setTileX(tile_x);
        td.setTileY(tile_y);
        td.setPixelMap(tile.getPixelMap());
        HiLog.info(LABEL, "TileMapData.setData1!");
        boolean isSuccessed = db.insert(td);
        HiLog.info(LABEL, "TileMapData.setData2!");
        try {
            isSuccessed = db.flush();
        } catch (RdbConstraintException e) {
            HiLog.info(LABEL, "TileMapData.setData Exception!!!");
            db.update(td);
            db.flush();
            HiLog.info(LABEL, "TileMapData.insert->update!!!");
        }
        HiLog.info(LABEL, "TileMapData.setData End!");
    }

    Tile getData(Tile.MapSource source, int zoom, int tile_x, int tile_y){
        HiLog.info(LABEL, "TileMapData.getData!");
        int type = typeMap.get(source);
        Tile tile = mapData.get(getKey(type, zoom, tile_x, tile_y));
        if(tile != null) return tile;
        OrmPredicates query = db.where(TileData.class).equalTo("type", type).and().equalTo("zoom", zoom).and().equalTo("tileX", tile_x).and().equalTo("tileY", tile_y);
        List<TileData> tds = db.query(query);
        if (tds.size() > 0) {
            TileData td = (TileData) tds.get(0);
            tile = new Tile(td.getPixelMap());
            tile.setTileInfo(td.getTileX(), td.getTileY(), td.getZoom());
            mapData.put(getKey(type, zoom, tile_x, tile_y), tile);
            HiLog.info(LABEL, "TileMapData.getData success!");
            return tile;
        } else {
            HiLog.info(LABEL, "TileMapData.getData null!");
            return null;
        }
    }

    private String getKey(int type, int zoom, int tile_x, int tile_y){
        String key = String.format("%d.%d.%d.%d", type, zoom, tile_x, tile_y);
        return key;
    }
}

两次缓存的处理是通过setData和getData进行的。

参考代码

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

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

参考资料

开发-对象关系映射数据库概述 (harmonyos.com)

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-orm-overview-0000000000030070

开发-对象关系映射数据库开发指导 (harmonyos.com)

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/database-orm-guidelines-0000000000030063

本文分享自微信公众号 - 面向对象思考(OOThinkingDalian),作者:面向对象思考

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-08-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 自学HarmonyOS应用开发(62)- 使用对象关系映射数据库保存设定信息

    除了地图数据,秒表应用还有一些其他希望保存的数据,例如上次定位的位置,地图画面的缩放比例等。本文介绍通过对象关系映射数据库技术保存这些信息的方法。

    面向对象思考
  • 自学HarmonyOS应用开发(63)- 对象关系映射数据库升级

    随着应用开发的不断深入,或早或晚都会产生升级数据库结构的需求。这种升级可以是为特定的数据表添加字段,也可以是增加新表等。

    面向对象思考
  • 自学HarmonyOS应用开发(52)- 地图数据拼接和缓存

    上一篇文章中我们获取了当前位置所处的地图瓦片并表示,本文介绍获取更多的瓦片数据并进行拼接的方法。

    面向对象思考
  • 自学HarmonyOS应用开发(61)- 使用异步派发任务后台更新地图数据

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

    面向对象思考
  • 配置鸿蒙Windows烧录环境 && 用Hiburn烧录第一个程序

    如果已安装Visual Studio Code,打开命令行工具,输入code --version命令,检查版本号是否为1.45.1及以上版本;可以正常返回版本号...

    跋扈洋
  • HarmonyOS简介

    前两天,华为发布了HarmonyOS 2.0,俺也赶个时髦,给大家简单介绍下HarmonyOS。

    xiangzhihong
  • 芋道 Spring Boot 对象转换 MapStruct 入门

    为了让应用的代码更易维护,我们往往会将项目进行分层。在《阿里巴巴 Java 开发手册》中,推荐分层如下图:

    芋道源码
  • 丢弃掉那些 BeanUtils 工具类吧,MapStruct 是真香!!!

    为了让应用的代码更易维护,我们往往会将项目进行分层。在《阿里巴巴 Java 开发手册》中,推荐分层如下图:

    芋道源码
  • 【第22期】HarmonyOS应用开发(基础篇)

    这不就是说,以后华为手机都是鸿蒙系统了嘛?鸿蒙还发出了一条视频,视频中显示2021年6月2号将开启鸿蒙操作系统及华为全场景新品发布会。预计现在支持EMUI11升...

    siberiawolf
  • 程序员看华为HarmonyOS首发

    HarmonyOS代码正式开源,9月10日下午朋友圈散布着这条消息,科技圈炸锅了。各种声音的都有,我也挺好奇的,目前Android、iOS一统江湖,Harmon...

    马上就说
  • 技术分析 | HarmonyOS到底是不是Android套皮?

    最近鸿蒙系统关注度好高,支持与反对、看好和看衰、「自主的全场景分布式系统」和「Android套壳」各执一词,吵的不可开交。

    刘盼
  • 《鸿蒙理论知识04》HarmonyOS概述之系统定义

    【摘要】 系统定位 HarmonyOS 是一款“面向未来”、面向全场景(移动办公、运动健康、社交通信、媒体 娱乐等)的分布式操作系统。在传统的单设备系统能力的基...

    玖柒的小窝
  • 鸿蒙(HarmonyOS)API的源代码去哪了?竟然全抛出异常,原来使用的是虚拟API!

    不管是鸿蒙(HarmonyOS),或是Android、还是其他系统。理解其工作原理最好的方式就是阅读源代码。不过HarmonyOS的所有系统类,跟踪进去,全部是...

    蒙娜丽宁
  • HarmonyOS与Android的全面对比

    第二是我个人非常看好鸿蒙系统的未来,清楚明白华为和一些民族企业担负的责任和国人的期待,虽然带着一些民族感情;鸿蒙刚发布的时候自己是非常激动的,但是后来项目太忙一...

    肉眼品世界
  • HarmonyOS 生态,投入还是继续观望?

    HarmonyOS 2.0 从首次亮相至今快满一年,回顾过去一年里的关键节点:2020 年 9 月在华为开发者大会上,HarmonyOS 2.0 首次亮相;20...

    深度学习与Python
  • 《鸿蒙理论知识03》HarmonyOS概述之系统安全

    在搭载 HarmonyOS 的分布式终端上,可以保证“正确的人,通过正确的设备,正确地使 用数据”。 通过“分布式多端协同身份认证”来保证“正确的人”。

    玖柒的小窝
  • Hibernate之集合映射的使用(Set集合映射,list集合映射,Map集合映射)

    a:数据库的相关知识:   (1):一个表能否有多个主键:不能;   (2):为什么要设置主键:数据库存储的数据都是有效的,必须保持唯一性;   (3)...

    别先生
  • 基于 Hi3861 平台的 HarmonyOS Device 开发体验

    编程界有个传承了几十年的”规矩“--入门先从环境搭建开始,有的时候环境搭建比较简单,比如学习 HTML 编程,有浏览器就行;有时候又比较繁琐,比如 React ...

    胡琦
  • 【框架】[Hibernate]构架知识点详解入门与测试实例

    Hibernate是一个开放源码的、非常优秀、成熟的O/R Mapping框架。它提供了强大、高性能的Java对象和关系数据的持久化和查询功能。

    谙忆

扫码关注云+社区

领取腾讯云代金券