浅谈Android游戏开发之详解SQLite存储

时间:2011-09-03

  先介绍几个基本概念知识:

  Android是基于Linux内核的操作系统,是Google公司在2007年11月5日公布的手机操作系统。早期由原名为"Android"的公司开发,谷歌在2005年收购"Android.Inc"后,继续进行对Android系统开发运营,它采用了软件堆层(software stack,又名以软件叠层)的架构,主要分为三部分。底层Linux内核只提供基本功能,其他的应用软件则由各公司自行开发,部分程序以Java编写。

  什么是SQLite:

  SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界着名的数据库管理系统来讲,它的处理速度比他们都快。

  SQLite的特性:

  1. ACID事务

  2. 零配置 - 无需安装和管理配置

  3. 储存在单一磁盘文件中的一个完整的数据库

  4. 数据库文件可以在不同字节顺序的机器间自由的共享

  5. 支持数据库大小至2TB

  6. 足够小, 大致3万行C代码, 250K

  7. 比一些流行的数据库在大部分普通数据库操作要快

  8. 简单, 轻松的API

  9. 包含TCL绑定, 同时通过Wrapper支持其他语言的绑定

  10. 良好注释的源代码, 并且有着90%以上的测试覆盖率

  11. 独立: 没有额外依赖

  12. Source完全的Open, 你可以用于任何用途, 包括出售它

  13. 支持多种开发语言,

  C, PHP, Perl, Java, ASP .NET,Python

  优点:

  1.能存储较多的数据。

  2.能将数据库文件存放到SD卡中!

  如何连接SQLite?

  用PHP操作sqlite数据库

  a、 如何连接sqlite数据库?

  if ($db = sqlite_open('mysqlitedb', 0666, $sqliteerror)) {

  select * from sqlite_master;

  echo "数据库连接成功!n

  ";

  } else {

  die($sqliteerror);

  }

  b、 如何列出数据库中所有的表?

  if ($db = sqlite_open('mysqlitedb', 0666, $sqliteerror)) {

  $result = sqlite_array_query($db, 'select * from sqlite_master;');

  foreach ($result as $entry) {

  echo 'talbe name='.$entry['name']."

  n";

  echo 'sql='.$entry['sql']."

  n";

  echo "

  --------------------------------------------------------------------------------

  }

  sqlite_close($db);

  } else {

  die($sqliteerror);

  }}

  c、 对sqlite数据库的查询,以及结果集的显示

  if ($db = sqlite_open('mysqlitedb', 0666, $sqliteerror)) {   $result = sqlite_array_query($db, 'select name, email from user ', SQLITE_ASSOC);

  echo "user表查询结果:

  n";

  echo " n name email

  n";

  foreach ($result as $entry) {

  echo ' '.$entry['name']." " $entry['email']."

  n";

  }

  echo ' ';

  sqlite_close($db);

  } else {

  die($sqliteerror);

  }

  d、 数据库对象记录的增加、删除、修改

  sqlite_query($db, "INSERT INTO user VALUES('user".$i."'" ",'user".$i."@ hichina. com')");   sqlite_query($db, "delete from user where user=’user99’");

  sqlite_query($db, 'UPDATE user SET email="lilz@ hichina .com" where name="user1"');

  什么是 SQLiteDatabase?

  一个 SQLiteDatabase 的实例代表了一个SQLite 的数据库,通过SQLiteDatabase 实例的一些方法,我们可以执行SQL 语句,对数 据库进行增、删、查、改的操作。需要注意的是,数据库对于一个应用来说是私有的,并且在一个应用当中,数据库的名字也是惟一的。

  什么是 Cursor ?

  Cursor是网页制作CSS中的光标类型,与图标文件Icon一样,是特殊类型的小位图。

  顺便来张项目截图:

  

  先给出xml:

  view plaincopy to clipboardprint?

  ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

  《?xml version=“1.0” encoding=“utf-8”?》

  《LinearLayout xmlns:android=“https://schemas.android.com/apk/res/android”

  android:orientation=“vertical” android:layout_width=“fill_parent”

  android:layout_height=“fill_parent”》

  《TextView android:layout_width=“fill_parent”

  android:layout_height=“wrap_content” android:text=“SQL 练习!”

  android:textSize=“20sp” android:textColor=“#ff0000” android:id=“@+id/tv_title” /》

  《Button android:id=“@+id/sql_addOne” android:layout_width=“fill_parent”

  android:layout_height=“wrap_content” android:text=“插入一条记录”》《/Button》

  《Button android:id=“@+id/sql_check” android:layout_width=“fill_parent”

  android:layout_height=“wrap_content” android:text=“查询数据库”》《/Button》

  《Button android:id=“@+id/sql_edit” android:layout_width=“fill_parent”

  android:layout_height=“wrap_content” android:text=“修改一条记录”》《/Button》

  《Button android:id=“@+id/sql_deleteOne” android:layout_width=“fill_parent”

  android:layout_height=“wrap_content” android:text=“删除一条记录”》《/Button》

  《Button android:id=“@+id/sql_deleteTable” android:layout_width=“fill_parent”

  android:layout_height=“wrap_content” android:text=“删除数据表单”》《/Button》

  《Button android:id=“@+id/sql_newTable” android:layout_width=“fill_parent”

  android:layout_height=“wrap_content” android:text=“新建数据表单”》《/Button》

  《/LinearLayout》

  xml中定义了我们需要练习用到的几个操作按钮,这里不多解释了,下面看java源码:先看我们继承的 SQLiteOpenHelper 类

  Java平台由Java虚拟机(Java Virtual Machine)和Java 应用编程接口(Application Programming Interface、简称API)构成。Java 应用编程接口为Java应用提供了一个独立于操作系统的标准接口,可分为基本部分和扩展部分。在硬件或操作系统平台上安装一个Java平台之后,Java应用程序就可运行。现在Java平台已经嵌入了几乎所有的操作系统。这样Java程序可以只编译,就可以在各种系统中运行。

  view plaincopy to clipboardprint?

  ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

  package com.himi;

  import android.content.Context;

  import android.util.Log;

  /**

  *

  * @author Himi

  // 在数据库次生成的时候会调用这个方法,一般我们在这个方法里边生成数据库表;

  public void onCreate(SQLiteDatabase db) {

  String str_sql = “CREATE TABLE ” + TABLE_NAME + “(” + ID

  + “ INTEGER PRIMARY KEY AUTOINCREMENT,” + TEXT + “ text );”;

  // CREATE TABLE 创建一张表 然后后面是我们的表名

  // 然后表的列,个是id 方便操作数据,int类型

  // ----------注意:这里str_sql是sql语句,类似dos命令,要注意空格!

  db.execSQL(str_sql);

  // execSQL()方法是执行一句sql语句

  // 虽然此句我们生成了一张数据库表和包含该表的sql.himi文件,

  // 但是要注意 不是方法是创建,是传入的一句str_sql这句sql语句表示创建!!

  }

  @Override

  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

  // 一般默认情况下,当我们插入 数据库就立即更新

  // 当数据库需要升级的时候,Android 系统会主动的调用这个方法。

  // 一般我们在这个方法里边删除数据表,并建立新的数据表,

  // 当然是否还需要做其他的操作,完全取决于游戏需求。

  Log.v(“Himi”, “onUpgrade”);

  }

  }

  我喜欢代码中立即附上解释,感觉这样代码比较让大家更容易理解和寻找,当然如果童鞋们不喜欢,可以告诉我,我改~嘿嘿~

  下面看重要的MainActivity中的代码:

  view plaincopy to clipboardprint?

  ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

  package com.himi;

  import java.io.File;

  import java.io.IOException;

  import android.app.Activity;

  import android.content.ContentValues;

  import android.database.Cursor;

  import android.database.sqlite.SQLiteDatabase;

  import android.os.Bundle;

  import android.view.View;

  import android.view.Window;

  import android.view.WindowManager;

  import android.view.View.OnClickListener;

  import android.widget.Button;

  import android.widget.TextView;

  // ------------第三种保存方式--------《SQLite》---------

  /**

  * @author Himi

  * @保存方式:SQLite 轻量级数据库、

  * @优点: 可以将自己的数据存储到文件系统或者数据库当中, 也可以将自己的数据存

  * 储到SQLite数据库当中,还可以存到SD卡中

  * @注意1:数据库对于一个游戏(一个应用)来说是私有的,并且在一个游戏当中,

  * 数据库的名字也是的。

  * @注意2 apk中创建的数据库外部的进程是没有权限去读/写的,

  * 我们需要把数据库文件创建到sdcard上可以解决类似问题。

  * @注意3 当你删除id靠前的数据或者全部删除数据的时候,SQLite不会自动排序,

  * 也就是说再添加数据的时候你不指定id那么SQLite默认还是在原有id添加一条新数据

  * @注意4 android 中 的SQLite 语法区分大小写的!!!!!这点要注意!

  * String UPDATA_DATA = “UPDATE himi SET text=‘通过SQL语句来修改数据’ WHERE id=1”;

  * 千万 不能可以写成

  * String UPDATA_DATA = “updata himi set text=‘通过SQL语句来修改数据’ where id=1”;

  */

  public class MainActivity extends Activity implements OnClickListener {

  private Button btn_addOne, btn_deleteone, btn_check, btn_deleteTable,

  btn_edit, btn_newTable;

  private TextView tv;

  private MySQLiteOpenHelper myOpenHelper;// 创建一个继承SQLiteOpenHelper类实例

  private SQLiteDatabase mysql ;

  //---------------以下两个成员变量是针对在SD卡中存储数据库文件使用

  // private File path = new File(“/sdcard/himi”);// 创建目录

  // private File f = new File(“/sdcard/himi/himi.db”);// 创建文件

  @Override

  public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  getWindow()。setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

  WindowManager.LayoutParams.FLAG_FULLSCREEN);

  this.requestWindowFeature(Window.FEATURE_NO_TITLE);

  setContentView(R.layout.main);

  tv = (TextView) findViewById(R.id.tv_title);

  btn_addOne = (Button) findViewById(R.id.sql_addOne);

  btn_check = (Button) findViewById(R.id.sql_check);

  btn_deleteone = (Button) findViewById(R.id.sql_deleteOne);

  btn_deleteTable = (Button) findViewById(R.id.sql_deleteTable);

  btn_newTable = (Button) findViewById(R.id.sql_newTable);

  btn_deleteTable.setOnClickListener(this);

  btn_newTable.setOnClickListener(this);

  myOpenHelper = new MySQLiteOpenHelper(this);// 实例一个数据库辅助器

  //备注1 ----如果你使用的是将数据库的文件创建在SD卡中,那么创建数据库mysql如下操作:

  // if (!path.exists()) {// 目录存在返回false

  // path.mkdirs();// 创建一个目录

  // }

  // if (!f.exists()) {// 文件存在返回false

  // try {

  // f.createNewFile();//创建文件

  // } catch (IOException e) {

  // // TODO Auto-generated catch block

  // e.printStackTrace();

  // }

  // }

  }

  @Override

  public void onClick(View v) {

  try {

  //备注2----如果你使用的是将数据库的文件创建在SD卡中,那么创建数据库mysql如下操作:

  // mysql = SQLiteDatabase.openOrCreateDatabase(f, null);

  //备注3--- 如果想把数据库文件默认放在系统中,那么创建数据库mysql如下操作:

  mysql = myOpenHelper.getWritableDatabase(); // 实例数据库

  if (v == btn_addOne) {// 添加数据

  // ---------------------- 读写句柄来插入---------

  // ContentValues 其实就是一个哈希表HashMap, key值是字段名称,

  //Value值是字段的值。然后 通过 ContentValues 的 put 方法就可以

  //把数据放到ContentValues中,然后插入到表中去!

  ContentValues cv = new ContentValues();

  cv.put(MySQLiteOpenHelper.TEXT, “测试新的数据”);

  mysql.insert(MySQLiteOpenHelper.TABLE_NAME, null, cv);

  // inser() 个参数 标识需要插入操作的表名

  // 第二个参数 :默认传null即可

  // 第三个是插入的数据

  // ---------------------- SQL语句插入--------------

  // String INSERT_DATA =

  // “INSERT INTO himi (id,text) values (1, ‘通过SQL语句插入’)”;

  // db.execSQL(INSERT_DATA);

  tv.setText(“添加数据成功!点击查看数据库查询”);

  } else if (v == btn_deleteone) {// 删除数据

  // ---------------------- 读写句柄来删除

  mysql.delete(“himi”, MySQLiteOpenHelper.ID + “=1”, null);

  // 个参数 需要操作的表名

  // 第二个参数为 id+操作的下标 如果这里我们传入null,表示全部删除

  // 第三个参数默认传null即可

  // ----------------------- SQL语句来删除

  // String DELETE_DATA = “DELETE FROM himi WHERE id=1”;

  // db.execSQL(DELETE_DATA);

  tv.setText(“删除数据成功!点击查看数据库查询”);

  } else if (v == btn_check) {// 遍历数据

  //备注4------

  Cursor cur = mysql.rawQuery(“SELECT * FROM ”

  + MySQLiteOpenHelper.TABLE_NAME, null);

  if (cur != null) {

  String temp = “”;

  int i = 0;

  while (cur.moveToNext()) {//直到返回false说明表中到了数据末尾

  temp += cur.getString(0);

  // 参数0 指的是列的下标,这里的0指的是id列

  temp += cur.getString(1);

  // 这里的0相对于当前应该是咱们的text列了

  i++;

  temp += “ ”; // 这里是我整理显示格式 ,呵呵~

  if (i % 3 == 0) // 这里是我整理显示格式 ,呵呵~

  temp += “\n”;// 这里是我整理显示格式 ,呵呵~

  }

  tv.setText(temp);

  }

  } else if (v == btn_edit) {// 修改数据

  // ------------------------句柄方式来修改 -------------

  ContentValues cv = new ContentValues();

  cv.put(MySQLiteOpenHelper.TEXT, “修改后的数据”);

  mysql.update(“himi”, cv, “id ” + “=” + Integer.toString(3), null);

  // ------------------------SQL语句来修改 -------------

  // String UPDATA_DATA =

  // “UPDATE himi SET text=‘通过SQL语句来修改数据’ WHERE id=1”;

  // db.execSQL(UPDATA_DATA);

  tv.setText(“修改数据成功!点击查看数据库查询”);

  } else if (v == btn_deleteTable) {// 删除表

  mysql.execSQL(“DROP TABLE himi”);

  tv.setText(“删除表成功!点击查看数据库查询”);

  } else if (v == btn_newTable) {// 新建表

  String TABLE_NAME = “himi”;

  String ID = “id”;

  String TEXT = “text”;

  String str_sql2 = “CREATE TABLE ” + TABLE_NAME + “(” + ID

  + “ INTEGER PRIMARY KEY AUTOINCREMENT,” + TEXT

  + “ text );”;

  mysql.execSQL(str_sql2);

  tv.setText(“新建表成功!点击查看数据库查询”);

  }

  // 删除数据库:

  // this.deleteDatabase(“himi.db”);

  } catch (Exception e) {

  tv.setText(“操作失败!”);

  } finally {// 如果try中异常,也要对数据库进行关闭

  mysql.close();

  }

  }

  }

  以上代码中我们实现了两种存储方式:

  一种存储默认系统路径/data-data-com.himi-databases下,另外一种则是保存在了/sdcard-himi下,生成数据库文件himi.db

  那么这里两种实现方式大概步骤和区别说下:

  -----------如果我们使用默认系统路径存储数据库文件:

  步:新建一个类继承SQLiteOpenHelper;写一个构造,重写两个函数!

  第二步:在新建的类中的onCreate(SQLiteDatabase db) 方法中创建一个表;

  第三步:在进行删除数据、添加数据等操作的之前我们要得到数据库读写句柄得到一个数据库实例;

  注意: 继承写这个辅助类,是为了在我们没有数据库的时候自动为我们生成一个数据库,并且生成数据库文件,这里也同时创建了一张表,因为我们在onCreate里是在数据库中创建一张表的操作;这里还要注意在我们new 这个我们这个MySQLiteOpenHelper 类实例对象的时候并没有创建数据库哟~!而是在我们调用 (备注3)MySQLiteOpenHelper ……getWritableDatabase() 这个方法得到数据库读写句柄的时候,android 会分析是否已经有了数据库,如果没有会默认为我们创建一个数据库并且在系统路径data-data-com.himi-databases下生成himi.db 文件!

  (如果我们使用sd卡存储数据库文件,就没有必要写这个类了,而是我们自己Open自己的文件得到一个数据库,西西,反而方便~ )

  -----------如果我们需要把数据库文件存储到SD卡中:

  步:确认模拟器存在SD卡,关于SD卡的两种创建方法见我的博文:【Android 2D游戏开发之十】

  第二步:(备注1)先创建SD卡目录和路径已经我们的数据库文件!这里不像上面默认路径中的那样,如果没有数据库会默认系统路径生成一个数据库和一个数据库文件!我们必须手动创建数据库文件!

  第三步:在进行删除数据、添加数据等操作的之前我们要得到数据库读写句柄得到一个数据库实例;(备注2)此时的创建也不是像系统默认创建,而是我们通过打开步创建好的文件得到数据库实例。这里仅仅是创建一个数据库!!!!

  第四步:在进行删除数据、添加数据等操作的之前我们还要创建一个表!

  第五步:在配置文件AndroidMainfest.xml 声明写入SD卡的权限,上一篇已经介绍权限了,不知道的自己去看下吧。

  有些童鞋不理解什么默认路径方式中就有表?那是因为我们在它默认给我们创建数据库的时候我们有创建表的操作,就是MySQLiteOpenHelper类中的onCreate()方法里的操作!所以我们如果要在进行删除数据、添加数据等操作的之前还要创建一个表,创建表的方法都是一样的。

  总结:不管哪种方式我们都要-创建数据库-创建表-然后进行操作!

  在Android中查询数据是通过Cursor类来实现的,当我们使用SQLiteDatabase.query()方法时,会得到一个Cursor对象,Cursor指向的就是每一条数据。它提供了很多有关查询的方法,具体方法如下:

  以下是方法和说明:

  move 以当前的位置为参考,将Cursor移动到指定的位置,成功返回true, 失败返回false

  moveToPosition 将Cursor移动到指定的位置,成功返回true,失败返回false

  moveToNext 将Cursor向前移动一个位置,成功返回true,失败返回false

  moveToLast 将Cursor向后移动一个位置,成功返回true,失败返回 false。

  movetoFirst 将Cursor移动到行,成功返回true,失败返回false

  isBeforeFirst 返回Cursor是否指向项数据之前

  isAfterLast 返回Cursor是否指向一项数据之后

  isClosed 返回Cursor是否关闭

  isFirst 返回Cursor是否指向项数据

  isLast 返回Cursor是否指向一项数据

  isNull 返回指定位置的值是否为null

  getCount 返回总的数据项数

  getInt 返回当前行中指定的索引数据

  对于SQLite的很多童鞋有接触过,但是就不知道怎么存储在SD中,所以我也研究了下,这篇也写了把sd卡中的方式也提供给大家,希望大家能用的上。

 


  
上一篇:关于视频压缩技术的系统考虑
下一篇:基于TMS320LF2407A和NRF903的工程机械遥控器设计

免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

相关技术资料