《OpenGL ES 3.x游戏开发(上卷)》一2.3 手机自带数据库——SQLite

2.3 手机自带数据库——SQLite

上一节介绍了如何使用Preferences存储简单数据,而复杂的数据就需要存储到文件或数据库中了。Android自带了一款轻量级的关系数据库——SQLite,其具有体积小,功能强大等特点,成为嵌入式设备首选的数据库系统。本节将带领读者走进SQLite的世界,学习如何应用SQLite数据库进行数据的增、删、改、查等基本操作。

2.3.1 初识SQLite

SQLite是一款满足ACID特性的具有完备功能的关系数据库系统,由于其设计目标为轻量级、开源、支持嵌入式使用,因此,目前已经在嵌入式设备领域被广泛采用。其运行需要的系统资源非常少,在嵌入式设备中可能只需要几百KB的内存就够了。

SQLite对主流编程语言的支持也非常全面,如C#、PHP、Java等,同时还支持ODBC接口。另外,SQLite的性能也是一流的,在一般应用情况下,其处理速度比MySQL、PostgreSQL这两款著名的开源数据库管理系统都快。

提示

SQLite的最新版本为3.8.11.1,发布时间是2015年7月29日。其官方网站为:http://www.sqlite. org或者http://www.sqlite .com .cn,读者可以在该网站上获取SQLite的源代码和相关文档。

虽然SQLite占用的资源非常少,但是其功能、特性与服务器级数据库相比却丝毫不差,这也是SQLite能够受到Android系统青睐的主要原因,其部分特性如下所列。

  • 最大可以支持2TB的数据库文件。
  • 占用资源少,一般占用250KB左右。
  • API非常简单,易于使用。
  • 没有任何额外的依赖,是独立的。
  • 源代码完全开放,可以用于任何用途。
  • Android系统中很多的用户数据都存储在SQLite数据库中,如联系人信息、通话记录、短信等,由此可见SQLite对于Android的重要性。

提示

读者要想很好地使用SQLite数据库,必须熟练掌握SQL语言。这是由于SQL已经事实上成为关系数据库操作的标准语言,市面上的关系数据库几乎无一例外都支持SQL。因此,在数据库领域,有这样一句话“学好SQL,走遍天下都不怕”。

2.3.2 SQLite数据库的基本操作

一般学习数据库相关课程的时候,首先介绍的就是数据库的一些基本操作,如数据的增、删、改、查等。按照惯例,本书也首先简单介绍SQLite数据库的创建、关闭及数据的增加、删除、修改、查询等基本操作,具体如下所列。

提示

想在Android下通过Java编程对SQLite数据库进行操作,就必须要用到android.database.sqlite包下的SQLiteDatabase类,该类提供了对SQLite数据库进行基本操作的所有重要方法。

创建数据库。
创建数据库需要用到的是openDatabase方法,此方法签名为“public static SQLiteDatabase openDatabase (String path, SQLiteDatabase.CursorFactory factory, int flags)”。其中path为数据库所在的路径;factory为游标工厂;flags为标志,可以用来控制数据库的访问模式。

关闭数据库。
关闭数据库需要用到的是close方法,此方法签名为“public void close()”。在实际开发中数据库使用完毕后,一定不要忘记使用该方法关闭数据库,以防止资源的浪费。

插入数据。
插入数据可以使用insert方法,此方法签名为“public long insert (String table, String nullColumnHack, ContentValues values)”。其中table为待插入的表名,nullColumnHack通常设置为null,values为待插入的数据。

更新数据。
更新数据可以使用update方法,其签名为“public int update(String table, ContentValues values, String whereClause, String[] whereArgs)”。其中table为待更新的表名;values为待更新内容;whereClause为where子句的内容,用来进行记录筛选;whereArgs为where子句的参数。

删除数据。
删除数据可以使用delete方法,其签名为“public int delete (String table, String whereClause, String[] whereArgs)”。其中table为要操作的表名;whereClause为where子句的内容,用来进行记录筛选;whereArgs为where子句的参数。

查询数据。
查询数据可以使用query方法,其方法签名为“public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)”。其中table为要查询的表,columns为要查询的列,selection为过滤记录的子句,selectionArgs为过滤的参数值,groupBy为分组子句,having为过滤分组的子句,orderBy为记录排序子句。

提示

Android中被重载了的query方法有多个变体。这里由于篇幅所限,不再赘述,有需要的读者可以自行查阅API或其他相关资料。

执行非查询SQL。
对于不太熟悉SQL语言的初学者而言,插入、更新、删除数据可以用前面介绍的insert、update、delete方法。但对于熟练掌握SQL的开发人员而言,使用execSQL方法直接执行相应的SQL语句十分方便。

此方法签名为“public void execSQL (String sql)”或“public void execSQL (String sql, Object[] bindArgs)”。其中sql为需要执行的SQL语句,bindArgs为带参数SQL语句的参数值数组。

提示

需要注意的是,此方法仅支持执行非查询的SQL语句,如CREATE TABLE、 DELETE、 INSERT、UPDATE等,不能用于执行SELECT语句。

执行查询SQL。
对于熟练掌握SQL的开发人员而言,会觉得前面介绍的query方法使用过于繁琐。Android的设计人员也考虑到了这个问题,提供了支持执行SQL查询语句的rawQuery方法,其方法签名为“public Cursor rawQuery (String sql, String[] selectionArgs)”。其中sql为要执行的SQL查询语句(可以带参数),selectionArgs为查询参数的值。

提示

SQLiteDatabase类中用于数据库操作的方法还有很多,本书只是介绍了其中一些常用的,若读者有需要可以查阅API或其他相关资料进一步学习。

2.3.3 SQLite数据库的简单案例

上一小节介绍了SQLite数据库的基本操作方法,本小节将详细介绍一个使用SQLite数据库的简单案例,以使读者可以更加快速地掌握SQLite数据库的使用方法,从而在开发中进行合理地使用。本案例运行效果分别如图2-10、图2-11和图2-12所示。


介绍完本案例的运行效果后,接下来将开发本案例中唯一的一个类——Sample2_4_Activity,其代码如下。

1    package com.bn.pp4;
2    ……//此处省略了部分类的引入代码,读者可自行查看随书的源代码
3    public class Sample2_4_Activity extends Activity {
4        SQLiteDatabase sld; // 声明SQLiteDatabase引用
5        @Override
6        public void onCreate(Bundle savedInstanceState) {    // onCreate方法
7            super.onCreate(savedInstanceState);
8            setContentView(R.layout.main);                      //跳转到主界面
9            Button b = (Button) this.findViewById(R.id.Button01);
                                             //获取打开/创建数据库按钮的引用
10            b.setOnClickListener(                 //为打开/创建按钮添加监听器
11            new OnClickListener() {
12                @Override
13                public void onClick(View v) {
14                    createOrOpenDatabase();     //调用方法打开或创建数据库
15            }});
16            b = (Button) this.findViewById(R.id.Button02);//获取关闭数据库按钮的引用
17            b.setOnClickListener(                 //为关闭按钮添加监听器
18            new OnClickListener() {
19                @Override
20                public void onClick(View v) {
21                    closeDatabase();             //调用方法关闭数据库
22            }});
23            b = (Button) this.findViewById(R.id.Button03);     //获取添加记录按钮的引用
24            b.setOnClickListener(                 //为添加按钮添加监听器
25            new OnClickListener() {
26                @Override
27                public void onClick(View v) {
28                    insert();                     //调用方法插入记录
29            }});
30            b = (Button) this.findViewById(R.id.Button04);    //获取删除记录按钮的引用
31            b.setOnClickListener(                 //为删除按钮添加监听器
32            new OnClickListener() {
33                @Override
34                public void onClick(View v) {
35                    delete();                     //调用方法删除记录
36            }});
37            b = (Button) this.findViewById(R.id.Button05);     //获取查询记录按钮的引用
38            b.setOnClickListener(                 //为查询按钮添加监听器
39            new OnClickListener() {
40                @Override
41                public void onClick(View v) {
42                    query();                     //调用方法查询记录
43        }});}
44        public void createOrOpenDatabase() {            //创建或打开数据库的方法
45            try {
46                sld = SQLiteDatabase.openDatabase(
47                        "/data/data/com.bn.pp4/mydb",         //数据库所在路径
48                        null,                 //游标工厂,默认为null
49                        SQLiteDatabase.OPEN_READWRITE |
50                        SQLiteDatabase.CREATE_IF_NECESSARY //模式为读写,若不存在则创建
51                );                            //生成创建数据库的SQL语句
52                String sql = "create table if not exists student" +
53                        "(sno char(5),stuname varchar(20)," +
54                        "sage integer,sclass char(5))";
55                sld.execSQL(sql);                 //执行SQL语句
56                Toast.makeText(getBaseContext(), "成功创建数据库。",
57                        Toast.LENGTH_LONG).show();
58            } catch (Exception e) {
59                e.printStackTrace();
60        }}
61        public void closeDatabase() {                //关闭数据库的方法
62            try {
63                sld.close();                     //关闭数据库
64                Toast.makeText(getBaseContext(), "成功关闭数据库。",
65                        Toast.LENGTH_LONG).show();
66            } catch (Exception e) {
67                e.printStackTrace();
68        }}
69        public void insert() {                    //插入记录的方法
70            try  {                            //生成插入记录的SQL语句
71                String sql = "insert into student values" +
72                        "('001','Android',22,'283')";
73                sld.execSQL(sql);                 //执行SQL语句
74                Toast.makeText(getBaseContext(), "成功插入一条记录。",
75                         Toast.LENGTH_LONG).show();
76            } catch (Exception e) {
77                e.printStackTrace();
78        }}
79        public void delete() {                    //删除记录的方法
80            try  {                            //生成删除所有记录的SQL语句
81                String sql = "delete from student;";
82                sld.execSQL(sql);                 //执行SQL语句
83                Toast.makeText(getBaseContext(), "成功删除所有记录。",
84                        Toast.LENGTH_LONG).show();
85            } catch (Exception e) {
86                e.printStackTrace();
87        }}
88        public void query(){                        //查询的方法
89            try {                                //生成查询记录的SQL语句
90                String sql = "select * from student where sage>?";
91                Cursor cur = sld.rawQuery(sql, new String[] { "20" });
                                             //获取Cursor对象引用
92                while (cur.moveToNext()) {            //若存在记录
93                    String sno = cur.getString(0);        //获取第一列信息
94                    String sname = cur.getString(1);     //获取第二列信息
95                    int sage = cur.getInt(2);             //获取第三列信息
96                    String sclass = cur.getString(3);     //获取第四列信息
97                    Toast.makeText(
98                            getBaseContext(),
99                            "查询到的记录为:'" + sno + "'\t'" + sname
100                            + "'\t\t'" + sage+ "'\t'" + sclass + "'",
101                            Toast.LENGTH_LONG).show();
102                }
103                cur.close();                             //关闭Cursor
104            } catch (Exception e) {
105                e.printStackTrace();
106    }}}
  • 第9-43行为案例中的各个按钮添加监听器,监听器中调用对应的方法来实现数据库的打开/创建、关闭、插入、删除和查询等操作。
  • 第43-60行为创建及打开数据库的方法,方法中首先获取了SQLiteDatabase对象的引用,并为其指定数据库的存储路径和读写模式,然后用“create table”语句创建了一张名称为student的表。
  • 第69-78行为向数据库中插入一条记录的方法,插入的记录内容为“'001','Android',22,'283'”。
  • 第79-87行为删除数据库中所有记录的方法。
  • 第88-106行为从数据库中查找符合条件记录的方法,首先需要获取Cursor对象的引用,并为其添加查找范围(具体范围为年龄大于20)。若查到相应记录,则将该记录信息用Toast显示出来。

2.3.4 使用ContentProvider组件共享数据

前一小节介绍了SQLite数据库中的一些操作,但有时数据库中的信息不但创建其的应用程序要使用,还希望能够分享给其他应用程序使用。这时就需要使用ContentProvider组件了,ContentProvider组件的基本情况如下所列。

Android平台中每个应用程序都有自己的用户ID并在自己的进程中运行,每个进程拥有独立的运行环境,这样可以保证程序的完整性。但这也使得应用程序在需要进行资源共享和数据通信时很不方便。为了解决这一问题,Android提供了专门用来在应用程序之间分享数据的ContentProvider组件。
ContentProvider能将应用程序中特定的数据提供给其他应用程序使用,这些数据可以来自应用程序私有文件夹下的私有数据文件,也可以来自应用程序自己私有的SQLite数据库。当然,数据的来源还有很多其他选择,ContentProvider组件本身并没有做出限制,读者可以充分发挥想象的空间。
使用ContentProvider组件共享数据的基本方式是继承ContentProvider类并重写其中的相应方法,具体情况在后面的案例中进行介绍。
别的应用程序想分享数据时需要使用ContentResolver,通过ContentResolver对象将需要分享数据的请求发送给ContentProvider组件,而不能直接调用ContentProvider组件。
下面使用ContentProvider组件将上一小节的案例进行升级,使得此案例具有分享数据给其他应用程序的能力,其具体开发步骤如下。

(1)在案例Sample2_4的com/bn/pp4包下创建MyContentProvider类,该类继承自ContentProvider类,并要实现其中所有的抽象方法,具体代码如下。

1    package com.bn.pp4;
2    ……//此处省略了部分类的引入代码,读者可自行查看随书的源代码
3    public class MyContentProvider extends ContentProvider {  //继承ContentProvider
4        private static final UriMatcher um;                //声明Uri匹配引用
5        static {
6            um = new UriMatcher(UriMatcher.NO_MATCH);     //创建UriMatcher
7            um.addURI("com.bn.pp4.provider.student", "stu", 1); //设置匹配字符串
8        }
9        SQLiteDatabase sld;                             //声明SQLiteDatabase引用
10        @Override
11        public String getType(Uri uri) {
12            return null;
13        }
14        @Override    //调用数据库的query方法时会自动调用该方法
15        public Cursor query(Uri uri, String[] projection, String selection,
16                String[] selectionArgs, String sortOrder) {
17            switch (um.match(uri)) {                //若匹配成功
18            case 1:                             //执行操作,获取Cursor对象引用
19                Cursor cur = sld.query("student", projection, selection,
20                        selectionArgs, null, null, sortOrder);
21                return cur;                     //返回Cursor对象引用
22            }
23            return null;
24        }
25        @Override
26        public int delete(Uri arg0, String arg1, String[] arg2) {    //空实现
27            return 0;
28        }
29        @Override
30        public Uri insert(Uri uri, ContentValues values) {            //空实现
31            return null;
32        }
33        @Override
34        public boolean onCreate() {                     //创建数据库时自动调用该方法
35            sld = SQLiteDatabase.openDatabase(
36                    "/data/data/com.bn.pp4/mydb",     //数据库所在路径
37                    null,                         //游标工厂,默认为null
38                    SQLiteDatabase.OPEN_READWRITE|
39                    SQLiteDatabase.CREATE_IF_NECESSARY //读写、若不存在则创建
40            );
41            return false;
42        }
43        @Override
44        public int update(Uri uri, ContentValues values, String selection,
45                String[] selectionArgs) {                //空实现
46            return 0;
47    }}
  • 第4-8行为声明Uri匹配对象,并且设置匹配字符串。此匹配字符串在需要得到分享数据的应用程序中提供给ContentResolver使用,以进行配对。
  • 第11-13行重写了getType方法,本案例中对getType方法没有要求,因此其返回空值。
  • 第15-24行重写了query方法,在匹配成功后,数据需求方通过ContentResolver调用此方法查询需要的数据。
  • 第26-32行重写了delete与insert方法,本案例中对这两个方法没有要求,因此都设置为返回空值。
  • 第34-42行重写了onCreate方法,其功能为首先获取SQLiteDatabase对象引用,然后创建或打开数据库,为信息的分享做好准备。
  • 第44-47行重写了update方法,本案例中对这个方法没有要求,因此设置为返回空值。
    (2)仅仅是完成上面的代码还是不够的,在Android程序开发中,有一个很重要的配置文件AndroidManifest.xml。要想使用ContentProvider组件,在完成代码的开发后,还必须在该配置文件中进行相应的配置,将如下代码插入到AndroidManifest.xml文件中的application标签中。
1    <provider
2         android:name="MyContentProvider"              <!--将调用的类名-->
3         android:authorities="com/bn/pp4.provider.student"    <!--要匹配的Uri字符串-->
4          android:exported="true"/>

2.3.5 使用ContentResolver获取分享数据

升级完了Sample2_4使其具有了数据分享能力之后,就可以在别的应用程序中通过ContentResolver匹配到Sample2_4案例中的ContentProvider组件获取分享的数据了。具体的开发步骤如下所列。

(1)创建项目Sample2_4_From,将项目的包名设定为com.bn.pp4f,并创建一个继承自Activity的类ContentConsumerActivity,其代码如下。

1    package com.bn.pp4f;                                        //包声明
2    import android.app.Activity;                                //相关类的引入
3    //……此处省略了部分相关类的引入代码,读者可自行查看随书的源代码
4    import android.widget.EditText;                                //相关类的引入
5    public class ContentConsumerActivity extends Activity {
6        ContentResolver cr;                // ContentResolver的引用
7        @Override                                            //重写方法的标志
8        public void onCreate(Bundle savedInstanceState) {
9            super.onCreate(savedInstanceState);            //继承父类的onCreate方法
10            setContentView(R.layout.main);                //跳转到主界面
11            cr=this.getContentResolver();                    //获取ContentResolver的对象
12            //初始化查询按钮
13            Button b=(Button)this.findViewById(R.id.Button01);        //Button类的引用
14            b.setOnClickListener(                                //设置按钮监听
15              new OnClickListener(){
16                @Override                            //重写方法的标志
17                public void onClick(View v) {        //重写onClick方法
18                    String stuname="Android";        //设置查询的字符串
19                    Cursor cur=cr.query(
20                       Uri.parse("content://com.bn.pp4.provider.student/stu"),
21                       new String[]{"sno","stuname","sage","sclass"},
22                       "stuname=?",                     //查询条件
23                       new String[]{stuname},
24                       "sage ASC"
25                    );
26                    while(cur.moveToNext()){
27                        String sno=cur.getString(0);            //获取学号
28                        String sname=cur.getString(1);            //获取名称
29                        int sage=cur.getInt(2);                    //获取年龄
30                        String sclass=cur.getString(3);            //获取班级
31                        appendMessage(sno+"\t"+sname+"\t\t"+sage+"\t"+sclass);
32                    }
33                    cur.close();                        //关闭ContentResolver
34        }});}
35        public void appendMessage(String msg){            //向文本区中添加文本
36                EditText et=(EditText)this.findViewById(R.id.EditText02);
                                                 //获取EditText的对象
37                et.append(msg+"\n");                        //添加显示的字符串
38    }}
  • 第8-25行主要功能为获取ContentResolver对象的引用,并给按钮添加监听器,使得按钮按下后可以通过ContentResolver匹配到Sample2_4案例中的ContentProvider组件获取需要的数据。
  • 第26-33行功能为将获取的Sample2_4案例分享的数据显示到屏幕上的EditText控件中。
    第35-38行为向EditText控件中添加文本信息的方法。

(2)Sample2_4_From案例开发完成后,运行该案例,其效果如图2-13和图2-14所示。

说明 

图2-13为运行该案例后的界面效果图,图2-14为单击“获取”按钮后,通过ContentResolver匹配到Sample2_4案例中的ContentProvider组件获取数据后的效果图。

时间: 2024-09-24 06:45:27

《OpenGL ES 3.x游戏开发(上卷)》一2.3 手机自带数据库——SQLite的相关文章

《OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例》——6.4节点法向量和面法向量

6.4 点法向量和面法向量 OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例 本章前面几节的案例都是基于球面开发的,球面属于连续.平滑的曲面,因此面上的每个顶点都有确定的法向量.但现实世界中的物体表面并不都是连续.平滑的,此时对于面上的某些点的法向量计算就不那么直观了,图6-18说明了这个问题. 从图6-18中可以看出,顶点A位于长方体左.上.前3个面的交界处,此处是不光滑的.这种情况下顶点A的法向量有两种处理策略,具体如下所列. 在顶点A的位置放置3个不同的顶点,每个顶点看作是仅

《OpenGL ES 3.x游戏开发(上卷)》一第1章 Android概述

第1章 Android概述 OpenGL ES 3.x游戏开发(上卷)随着移动互联网时代的到来,智能手机逐渐走进了人们的生活, Google公司于2007年11月5日发布了基于Linux平台的开源手机操作系统--Android.由于Android系统的开源性以及其他各个方面的因素,其受到了广大手机厂商的青睐,因此需要大量的Android开发人员来满足日益增长的海量软件开发需求. 提示 有些读者可能会有一点奇怪,不是介绍OpenGL ES 3.0的知识吗,怎么一开始就介绍Android呢?这是因为

《OpenGL ES 3.x游戏开发(上卷)》一第2章 游戏开发相关的 Android基础知识

第2章 游戏开发相关的 Android基础知识 OpenGL ES 3.x游戏开发(上卷)虽然本书主要是介绍OpenGL ES 3.0 3D应用及游戏开发的,但由于很多3D游戏应用中还需要用到目标平台的一些其他应用开发方面的知识,而本书3D基础知识部分主要是借助于Android平台来介绍OpenGL ES 3.0 3D应用及游戏开发的.故本章将向读者简要介绍一些在Android游戏开发中必备的一些基础知识,如音效.文件的读取.游戏信息的存储.Socket网络.蓝牙网络等. 提示 由于介绍Andr

OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例》一6.3 定位光与定向光

6.3 定位光与定向光 OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例上一节中介绍的光照效果都是基于定位光光源的,定位光光源类似于现实生活中的白炽灯灯泡,其在某个固定的位置,发出的光向四周发散.定位光照射的一个明显特点就是,在给定光源位置的情况下,对不同位置的物体产生的光照效果不同. 现实世界中并不都是定位光,例如照射到地面上的阳光,光线之间是平行的,这种光称为定向光.定向光照射的明显特点是,在给定光线方向的情况下,场景中不同位置的物体反映出的光照效果完全一致.图6-16中对定位

《OpenGL ES 3.x游戏开发(上卷)》一导读

前 言 为什么要写这样一本书随着智能手机硬件性能的不断提升,如水果忍者.极品飞车.狂野飙车等一批优秀的3D游戏娱乐应用在众多智能机用户间流行开来.与此同时,也带动了手机游戏产业逐渐从2D走向3D.但目前国内专门介绍这方面开发的书籍与资料都非常少,同时3D应用开发的门槛又比较高,使得很多初学者无从下手.根据这种情况,笔者结合多年从事3D游戏应用开发的经验编写了本书. 了解一些3D开发领域的技术人员都知道,移动嵌入式平台上的3D应用开发主要是基于OpenGL ES的3个版本,1.x.2.x和3.x.

《OpenGL ES 3.x游戏开发(下卷)》一导读

前 言 OpenGL ES 3.x游戏开发(下卷) 为什么要写这样一套书 随着智能手机硬件性能的不断提升,如"水果忍者""极品飞车""狂野飙车8:极速凌云"等一批优秀的3D游戏娱乐应用在广大智能机用户间流行开来.与此同时,也带动了手机游戏产业逐渐从2D走向3D.但目前国内专门介绍3D游戏开发的书籍与资料都非常少,同时3D应用开发的门槛又比较高,使得很多初学者无从下手.根据这种情况,笔者结合多年从事3D游戏应用开发的经验编写了这样一套书. 了解一些

《Android 3D游戏开发技术宝典——OpenGL ES 2.0》——2.3节手机自带数据库——SQLite

2.3 手机自带数据库--SQLiteAndroid 3D游戏开发技术宝典--OpenGL ES 2.0上一节介绍了如何使用Preferences存储简单数据,而复杂的数据就需要存储到文件或数据库中了. Android自带了一款轻量级的关系数据库--SQLite,其具有体积小,功能强大等诸多特点,成为嵌入式设备首选的数据库系统.本节将带领读者走进SQLite的世界,去学习如何应用SQLite数据库进行数据的增.删.改.查等基本操作. 2.3.1 初识SQLiteSQLite是一款满足ACID特性

《OpenGL ES 3.x游戏开发(上卷)》一1.4 已有Android项目的导入和运行

1.4 已有Android项目的导入和运行 上一节介绍了如何搭建Android开发环境.如何开发Hello Android应用程序以及如何调试Android的应用程序,接下来在本节中将简要介绍已有Android项目的导入和运行. 1.4.1 项目的导入 首先介绍怎样将已有的Android项目导入Eclipse,此处以本书最后部分大案例中的"3D可爱抓娃娃"为例进行讲解,具体步骤如下. (1)启动Eclipse,依次单击"File|Import",系统将弹出导入项目的

《OpenGL ES 3.x游戏开发(上卷)》一2.7 小结

2.7 小结 本章主要对Android平台下游戏开发中可能会用到的Android平台的相关基础知识进行详细介绍,如文件的I/O操作.SQLite数据库的增.删.改.查,游戏中声音特效.蓝牙互连等.只有学好这些基础知识,开发人员才能开发出更好的Android手机游戏.读者一定要在这些基础上下足工夫,今后的开发道路才会一帆风顺. 提示 Android平台的其他相关知识还有很多,由于本书侧重于介绍OpenGL ES 3.0 3D应用程序的开发,故本章只是简单介绍了一些与3D开发不直接相关的,但在游戏开