db4o Developer Community

db4o open source object database, native to Java and .NET
Welcome to db4o Developer Community Sign in | Join
in Search
More Search Options

db4o in Chinese

使用db4o实现超强的Android地图应用

 原作者:German Viscuso    译者:Rosen

简介

本项目基于DavanumSrinivas开发的BrowseMapBrowseMap是一个为Android开发的Google Maps浏览器,能提供:

  • 在Android上浏览Google Maps
  • 地图的放大和缩小
  • 跟随鼠标移动(在真实设备上应该是触摸屏)
  • 交通和卫星视图之间转换
  • 定位
(这些地图应用程序基础功能实际上已经在Android上实现了)

但由于增加了db4o对象持久化引擎,MapMe在这些基础功能之上提供了不少新特性: 
  • 把重要的位置信息作为书签保存到db4o(包括缩放级别、卫星交通视图的所有地图持久化内容)
  • 浏览书签列表
  • 编辑书签
  • 从书签中导航到地图上某个位置
  • 根据当前GPS所报告的位置居中显示地图

屏幕截图

想看应用程序是如何运作的,你可以观看在YouTube上的MapMe视频、从一个外部服务器下载高分辨率视频(30 Mb)或下面的屏幕截图:

db4o总部(卫星+交通视图)



MapMe主菜单:



建立书签/导航点(navpoint):



保存的书签/导航点(navpoint)列表:



MapMe如何利用db4o?

如果你查看源代码(下面有下载),你会发现DB helper类处理了所有的持久化操作(数据库的开启、存储、查询、计数),而这一切都不超过80行代码!

而且这一切都很简单,不会损失性能。好吧,现在就让我们来看一下项目中用到的持久化方法。

开启数据库

开启数据库的确很简单,并且在必要的时候还能自动生成数据库文件。一旦打开,db4o将锁定数据库文件。

public  ObjectContainer db(){

      
try  {

            
if (oc  ==   null   ||  oc.ext().isClosed())

                  oc 
=  Db4o.openFile(dbConfig(), db4oDBFullPath(context));

            
return  oc;

      } 
catch  (Exception e) {

            Log.e(Db4oHelper.
class .getName(), e.toString());

            
return   null ;

      }

}

 

private  String db4oDBFullPath(Context ctx) {

      
return  ctx.getDataDir()  +   " / "   +   " browsemap.db4o " ;

}

注意我们所存放的数据库文件路径是和上下文数据目录相关的。

配置数据库

这里我们提供一个配置对象,以便在打开数据库的时候把它传递进去(代码如下)。

private Configuration dbConfig(){

      Configuration c 
= Db4o.newConfiguration();

      c.objectClass(MapBookmark.
class).objectField("name").indexed(true);

      c.objectClass(MapBookmark.
class).updateDepth(2);

      c.objectClass(MapBookmark.
class).minimumActivationDepth(3);

      c.objectClass(MapBookmark.
class).cascadeOnDelete(true);

      
return c;

注意,为MapBookmark对象建立的索引字段是“name”,并设置激活和更新级别。

保存书签

在这里我们调用一系列的操作,无论对象是否存在于数据库,对象都会被更新或插入。

public void setBookmark(

                        String name,

                        String description,

                        
int latitude,

                        
int longitude,

                        
int zoomLevel,

                        
boolean satellite,

                        
boolean traffic){

     

      MapBookmark bkm 
= getBookmark(name);

      
if(bkm == null)

            bkm 
= new MapBookmark(name);

      bkm.setDescription(description);

      bkm.setLatitude(latitude);

      bkm.setLongitude(longitude);

      bkm.setZoomLevel(zoomLevel);

      bkm.setSatellite(satellite);

      bkm.setTraffic(traffic);

      db().set(bkm);

      db().commit();

}

由此可见,在保存到数据库之前,我们已经设置好所有字段。

根据name查询书签

我们通过Query by Example(QBE)传入一个原型来取回符合name条件的书签。

public MapBookmark getBookmark(String name){

      MapBookmark proto 
= new MapBookmark(name);

      ObjectSet result 
= db().get(proto);

      
if(result.hasNext()){

            
return (MapBookmark)result.next();

      }

      
return null;

}

QBE利用反射来检查原型对象的字段。

查询所有书签

这里,我们把SODA查询结果拷贝到ArrayList中。但要注意,当使用Native Queries时你不必这样做(在这种情况下将直接返回List<MapBookmark>)。

public List<MapBookmark> getBookmarkList(){

      ArrayList
<MapBookmark> ret = new ArrayList<MapBookmark>();

        ObjectSet result 
= getBookmarks();

        
while (result.hasNext())

            ret.add((MapBookmark)result.next());

        
return ret;

}

   

private ObjectSet getBookmarks(){

      Query query 
= db().query();

      query.constrain(MapBookmark.
class);

      query.descend(
"name").orderAscending();

      
return query.execute();

}

删除书签

public void deleteBookmark(String name) {

      MapBookmark bkm 
= getBookmark(name);

      
if(bkm != null){

            db().delete(bkm);

            db().commit();

      }

如果在db4o参考系统中存在符合条件的对象,你便可以轻松地调用delete()操作删除它。

书签计数

public int bookamrkCount(){

      
return getBookmarks().size();

}

   

private ObjectSet getBookmarks(){

      Query query 
= db().query();

      query.constrain(MapBookmark.
class);

      query.descend(
"name").orderAscending();

      
return query.execute();

}


要通过查询来进行对象计数,你只要获得查询结果的数量即可。

待完成

  • 基于书签的查询功能(通过db4o查询)
  • 支持手势识别(gesture recognition)(链接
  • 当前位置声音提示(Tweet current location)(链接
  • 在屏幕上动态跟踪GPS定位并把GPS路线存储到数据库上(以便今后查看)
  • 把定位信息发送给联系人(短消息、e-mail等)
下载

MapMe.Zip
YouTube上的MapMe视频
高分辨率视频(30 Mb)
Published Friday, December 14, 2007 10:49 AM by cleverpig

Comments

No Comments
Anonymous comments are disabled

About cleverpig

cleverpig is a member of Beijing Java User Group,Chief Editor of Matrix.org.cn,OpenJFX project Chinese Content Editor,GlassFish? project contributor,db4o Chinese Document Project organizer,Restlet Document Project organizer.He loves and focuses on any opensource technology and promotion.