[Android game development 13th] (Saving game data [below]) explains how to store SQLite database files in the SD card !!!

Source: Internet
Author: User

Li huaming himiOriginal, reprinted must be explicitly noted:
Reprinted from[Heimi gamedev block]Link: http://www.himigame.com/android-game/329.html

 

Many kids shoes say that after my code is run, clicking home or back will cause a program exception. If you have encountered this, you certainly haven't carefully read the himi blog, in article 19th, himi specifically wrote about the causes and solutions of these errors. I have added my remarks on this blog, and my provincial children's shoes are always confused. Please click here to contact us for further reading:

[Android game development 19th] (required) surfaceview Running Mechanism explanation-analyze back and home buttons and switch to the background to handle exceptions!


The previous article introduced how sharedpreference and file stream store data. We recommend that you use fileoutputstream/fileinputstream to store game data, so this article is like introducing another method suitable for game data storage: SQLite lightweight database!

 

First, we will introduce several basic concepts:

 

What is SQLite:

SQLite is a lightweight database designed for embedded systems and occupies a very small amount of resources. In embedded devices, only a few hundred KB is required !!!!!

 

SQLite features:

 

  • Lightweight
    To use SQLite, you only need to bring a dynamic library to enjoy all its functions, and the size of the dynamic library is smaller.
  • Independence
    The core engine of the SQLite database does not need to rely on third-party software or be "installed ".
  • Isolation
    All information (such as tables, views, and triggers) in the SQLite database is contained in a folder for convenient management and maintenance.
  • Cross-platform
    Currently, SQLite supports most operating systems, and does not allow computer operating systems to run in many mobile phone systems, such as Android.
  • Multilingual Interface
    The SQLite Database supports multi-language programming interfaces.
  • Security
    SQLite databases implement independent transaction processing through database-level exclusivity and shared locks. This means that multiple processes can read data from the same database at the same time, but only one can write data.

Advantages: 1. It can store more data.

2. Store database files in the SD card!

 

 

What is sqlitedatabase?

An instance of sqlitedatabase represents an SQLite database. Through some methods of the sqlitedatabase instance, we can execute SQL statements to add, delete, query, and modify data databases. Note that the database is private to an application, and the database name is unique in an application.

 

What is sqliteopenhelper?

According to this name, we can see that this class is a helper class. This class mainly generates a database and manages the database version. When the program calls the getwritabledatabase () method of this class or the getreadabledatabase () method, if there is no data at the time, the android system will automatically generate a data base. Sqliteopenhelper is an abstract class. We usually need to inherit it and implement the three functions in it,

 

What is the contentvalues class?

The contentvalues class is similar to hashmap/hashtable. It is also responsible for storing some name-value pairs, but the name of the name-Value Pair stored in it is

String type, while values are all basic types.

 

What is cursor?

Cursor is a very useful interface in Android. With cursor, we can perform on-demand read/write access to the result set queried from the database.

 

 

OK. The basic knowledge is introduced here. The following code is started: According to my consistent style, the explanations in the Code have been commented and explained in time in the code!

By the way, project:

 

First, XML is given:

<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <linearlayout xmlns: Android = "http://schemas.android.com/apk/res/android" <br/> Android: Orientation = "vertical" Android: layout_width = "fill_parent" <br/> Android: layout_height = "fill_parent"> <br/> <textview Android: layout_width = "fill_parent" <br/> Android: layout_height = "wrap_content" Android: text = "SQL exercises! (If you use the SD card to store data, please click to create a table before proceeding to the operation) "<br/> Android: textsize =" 20sp "Android: textcolor = "# ff0000" Android: Id = "@ + ID/TV _title"/> <br/> <button Android: Id = "@ + ID/SQL _addone" Android: layout_width = "fill_parent" <br/> Android: layout_height = "wrap_content" Android: text = "insert a record"> </button> <br/> <button Android: id = "@ + ID/SQL _check" Android: layout_width = "fill_parent" <br/> Android: layout_height = "wrap_content" Android: TEXT = "query database"> </button> <br/> <button Android: Id = "@ + ID/SQL _edit" Android: layout_width = "fill_parent" <br/> Android: layout_height = "wrap_content" Android: text = "modify a record"> </button> <br/> <button Android: id = "@ + ID/SQL _deleteone" Android: layout_width = "fill_parent" <br/> Android: layout_height = "wrap_content" Android: TEXT = "delete a record"> </button> <br/> <button Android: Id = "@ + ID/SQL _deletetable" Android: layout_width = "fill_parent" <br/> Android: layout_height = "wrap_content" Android: text = "delete data form"> </button> <br/> <button Android: id = "@ + ID/SQL _newtable" Android: layout_width = "fill_parent" <br/> Android: layout_height = "wrap_content" Android: TEXT = "New Data Form"> </button> <br/> </linearlayout> <br/> 

 

The XML defines several operation buttons that we need to practice. Here we will not explain them much. Let's look at the Java source code: Let's first look at the inherited sqliteopenhelper class.

 

Package COM. himi; <br/> Import android. content. context; <br/> Import android. database. SQLite. sqlitedatabase; <br/> Import android. database. SQLite. sqliteopenhelper; <br/> Import android. util. log; <br/>/** <br/> * @ author himi <br/> * @ to explain this class, we only need to create a constructor and override the two methods. OK, <br/> */<br/> public class mysqliteopenhelper extends sqliteopenhelper {<br/> Public final static int version = 1; // version <B R/> Public final static string table_name = "himi"; // table name <br/> Public final static string id = "ID "; // use <br/> Public final static string text = "text"; <br/> Public static final string database_name = "himi. DB "; <br/> Public mysqliteopenhelper (context) {<br/> // you can use the openorcreatedatabase method to create and open a database in Android, <br/> // it automatically checks whether the database exists. If yes, it is enabled. If no database exists, it is created. <br/> // create a database Returns a sqlitedatabase object. Otherwise, an exception filenotfoundexception is thrown. <Br/> // create a database named "database_name" and return a sqlitedatabase object </P> <p> super (context, database_name, null, version); <br/>}< br/> @ override <br/> // this method is called when the database is generated for the first time, generally, we generate a database table in this method. <br/> Public void oncreate (sqlitedatabase dB) {<br/> string str_ SQL = "CREATE TABLE" + table_name + "(" + id <br/> + "integer primary key autoincrement," + TEXT + "text ); "; <br/> // create table: Create a table, followed by our table name <br/> // Then, the first column in the table is ID to facilitate data operations. Int type <br/> // primary key indicates the primary key. This is an int type and is used to uniquely identify a row; <br/> // autoincrement indicates that the database will add a key for each record to ensure the uniqueness of the record; <br/> // Add a column of text string type to the end <br/> // ---------- Note: str_ SQL is an SQL statement, similar to the doscommand. Pay attention to spaces! <Br/> db.exe csql (str_ SQL); <br/> // execsql () the method is to execute an SQL statement <br/> // although this statement generates a database table and an SQL statement containing this table. himi file, <br/> // but note that the method is not creation, but the SQL statement str_ SQL passed in indicates creation !! <Br/>}< br/> @ override <br/> Public void onupgrade (sqlitedatabase dB, int oldversion, int newversion) {<br/> // by default, when we insert a database, update it immediately <br/> // when the database needs to be upgraded, the android system will actively call this method. <Br/> // generally, we delete the data table in this method and create a new data table. <br/> // Of course, whether other operations are required depends on the needs of the game. <Br/> log. V ("himi", "onupgrade"); <br/>}< br/>}

 

I like to add an explanation to the code,I feel like this code makes it easier for everyone to understand and find. Of course, if the kids do not like it, you can tell me how to change it ~ Hey hey ~

 

The code in the most important mainactivity is as follows:

 

Package COM. himi; <br/> Import Java. io. file; <br/> Import Java. io. ioexception; <br/> Import android. app. activity; <br/> Import android. content. contentvalues; <br/> Import android. database. cursor; <br/> Import android. database. SQLite. sqlitedatabase; <br/> Import android. OS. bundle; <br/> Import android. view. view; <br/> Import android. view. window; <br/> Import android. view. windowmanager; <br/> Import android. vie W. view. onclicklistener; <br/> Import android. widget. button; <br/> Import android. widget. textview; <br/> // ------------ third storage method -------- SQLite --------- <br/>/** <br/> * @ author himi <br/> * @ storage method: SQLite lightweight Database, <br/> * @ advantage: You can store your data in a file system or database, you can also store your data <br/> * to the SQLite database, or to the SD card <br/> * @ NOTE 1: The database is for a game (an application) it is private, and in a game, <br/> * The database name is also unique. <Br/> * @ note that the external process of the database created in 2 APK does not have the permission to read/write, <br/> * we need to create database files on sdcard to solve similar problems. <br/> * @ Note 3 SQLite does not automatically sort data before the ID or all the data deleted, <br/> * That is to say, if you do not specify the ID when adding the data, SQLite adds a new data entry at the end of the original ID by default. <br/> * @ Note 4 The SQLite syntax in Android case Insensitive, that is, it is case insensitive. <br/> */<br/> public class mainactivity extends activity implements onclicklistener {<br/> private button btn_addone, btn_deleteone, btn_check, btn_deletetable, <Br/> btn_edit, btn_newtable; <br/> private textview TV; <br/> private mysqliteopenhelper myopenhelper; // create an instance that inherits the sqliteopenhelper class <br/> private sqlitedatabase MySQL; <br/> // --------------- the following two member variables are used to store database files on the SD card. <br/> // Private File Path = new file ("/sdcard/himi "); // create a directory <br/> // Private file F = new file ("/sdcard/himi. DB "); // create a file <br/> @ override <br/> Public void oncreate (bundle savedinstanc Estate) {<br/> super. oncreate (savedinstancestate); <br/> getwindow (). setflags (windowmanager. layoutparams. flag_fullscreen, <br/> windowmanager. layoutparams. flag_fullscreen); <br/> This. requestwindowfeature (window. feature_no_title); <br/> setcontentview (R. layout. main); <br/> TV = (textview) findviewbyid (R. id. TV _title); <br/> btn_addone = (button) findviewbyid (R. id. SQL _addone); <br/> btn_check = (button) Fi Ndviewbyid (R. id. SQL _check); <br/> btn_deleteone = (button) findviewbyid (R. id. SQL _deleteone); <br/> btn_deletetable = (button) findviewbyid (R. id. SQL _deletetable); <br/> btn_newtable = (button) findviewbyid (R. id. SQL _newtable); <br/> btn_edit = (button) findviewbyid (R. id. SQL _edit); <br/> btn_edit.setonclicklistener (this); <br/> btn_addone.setonclicklistener (this); <br/> btn_check.setonclicklistener (this); <B R/> listener (this); <br/> btn_deletetable.setonclicklistener (this); <br/> btn_newtable.setonclicklistener (this); <br/> myopenhelper = new mysqliteopenhelper (this ); // instance a database helper <br/> // Note 1 ---- if you are using the database file created in the SD card, create the database MYSQL as follows: <br/> // If (! Path. exists () {// If the directory exists, false is returned. <br/> // path. mkdirs (); // create a directory <br/>//} <br/> // If (! F. exists () {// returns false if the file exists <br/> // try {<br/> // F. createnewfile (); // create a file <br/> //} catch (ioexception E) {<br/> /// todo auto-generated Catch Block <br/> // E. printstacktrace (); <br/>/}< br/>}< br/> @ override <br/> Public void onclick (view V) {<br/> try {<br/> // Note 2 ---- if you are using the function of creating a database file on the SD card, perform the following operations to create a database MYSQL: <br/> // MySQL = sqlitedatabase. openorcreatedatabase (F, null); <br/> // Note 3 --- if you want By default, the following operations are performed to create a database MYSQL: <br/> MySQL = myopenhelper. getwritabledatabase (); // instance database <br/> If (V = btn_addone) {// Add data <br/> // ---------------------- read/write handle to insert --------- <br/> // contentvalues is actually a hashmap table, and the key value is the field name, <br/> // The value is the value of the field. Then, you can use the PUT Method of contentvalues to <br/> // put the data in contentvalues and insert it into the table! <Br/> contentvalues CV = new contentvalues (); <br/> cv. put (mysqliteopenhelper. text, "test new data"); <br/> MySQL. insert (mysqliteopenhelper. table_name, null, CV); <br/> // The first parameter of inser () identifies the name of the table to be inserted <br/> // The second parameter: the default value is null. <br/> // The third value is the inserted data. <br/> // ---------------------- SQL statement: insert ---------------- <br/> // string insert_data = <br/> // "insert into himi (ID, text) values (1, 'insert using SQL statement ') "; <br/> // db.exe csql (insert _ Data); <br/> TV. settext ("data added successfully! Click to view database query "); <br/>} else if (V = btn_deleteone) {// delete data <br/> // ---------------------- read/write handle to delete <br/> MySQL. delete ("himi", mysqliteopenhelper. ID + "= 1", null ); <br/> // name of the table to be operated by the first parameter <br/> // The second parameter is ID + subscript of the operation. If null is input here, delete all <br/> // The third parameter defaults to null <br/> // --------------------- SQL statement to delete <br/> // string delete_data = "delete from himi where id = 1 "; <br/> // db.exe csql (delete_data); <br/> TV. settext ("Delete Data Division successful! Click to view database query "); <br/>} else if (V = btn_check) {// traverse data <br/> // Note 4 ------ <br/> cursor cur = MySQL. rawquery ("select * from" <br/> + mysqliteopenhelper. table_name, null); <br/> If (cur! = NULL) {<br/> string temp = ""; <br/> int I = 0; <br/> while (cur. movetonext () {// until false is returned, it indicates that the table ends with the data. <br/> temp + = cur. getstring (0); <br/> // parameter 0 indicates the subscript of the column, where 0 indicates the ID column <br/> temp + = cur. getstring (1); <br/> // The value 0 indicates that it is our text column relative to the current value. <br/> I ++; <br/> temp + = ""; // here is my display format ~ <Br/> if (I % 3 = 0) // here is my display format ~ <Br/> temp + = "/N"; // here is my display format ~ <Br/>}< br/> TV. settext (temp); <br/>}< br/>} else if (V = btn_edit) {// modify data <br/> // ------------------------ modify the data in the handle mode ------------- <br/> contentvalues CV = new contentvalues (); <br/> cv. put (mysqliteopenhelper. text, "modified data"); <br/> MySQL. update ("himi", CV, "ID" + "=" + integer. tostring (3), null); <br/> // ------------------------ modify the SQL statement ------------- <br/> // string updata_data = <br/> // "Update himi Set text = 'modify data using SQL statements 'where id = 1 "; <br/> // db.exe csql (updata_data); <br/> TV. settext ("data modified successfully! Click to view database query "); <br/>} else if (V = btn_deletetable) {// Delete the table <br/> mysql.exe csql (" Drop table himi "); <br/> TV. settext ("Table deleted! Click to view database query "); <br/>} else if (V = btn_newtable) {// create a table <br/> string table_name =" himi "; <br/> string id = "ID"; <br/> string text = "text "; <br/> string str_sql2 = "create table" + table_name + "(" + id <br/> + "integer primary key autoincrement, "+ TEXT <br/> +" text); "; <br/> mysql.exe csql (str_sql2); <br/> TV. settext ("table created successfully! Click to view database query "); <br/>}< br/> // Delete the database: <br/> // This. deletedatabase ("himi. DB "); <br/>}catch (exception e) {<br/> TV. settext ("operation failed! "); <Br/>}finally {// if an exception occurs in try, you must also disable the database. <br/> MySQL. close (); <br/>}< br/>}

 

The above code implements two storage methods:

One storage under the default system path/data-data-com.himi-databases, the other is saved under/sdcard-himi, generate the database file himi. DB

 

The steps and differences between the two implementation methods are as follows:

 

-----------If we use the default system path to store database files:

Step 1: Create a class that inherits sqliteopenhelper; write a constructor and rewrite two functions!

Step 2: Create a table in the oncreate (sqlitedatabase dB) method of the newly created class;

Step 3: obtain a database read/write handle before deleting or adding data;

Note: Inherit to write this helper class to automatically generate a database and generate database files when we do not have a database. A table is also created here, because we create a table in the database in oncreate; note that we did not create a database in the new mysqliteopenhelper instance object ~! Instead, we call(Note 3) mysqliteopenhelper .. getwritabledatabase () This method gets the database read and write handle, Android will analyze whether there is a database, if not will default for us to create a database and generate himi in the system path data-data-com.himi-databases. DB file!

(If we use the SD card to store database files, there is no need to write this class. Instead, we open our own files to get a database, which is convenient to the west ~ )

 

----------- If we need to store database files to the SD card:

Step 1: confirm that the simulator has an SD card. For two ways to create the SD card, see my blog: [Android 2D Game Development 10]

Step 2:(Note 1)First, create the SD card directory and path for our database files! Unlike the above default path, if there is no database, a database and a database file will be generated by default in the system path! We must manually create database files!

Step 3: obtain a database read/write handle before deleting or adding data;(Note 2)At this time, the creation is not like the default creation of the system, but we get the database instance by opening the file created in step 1. Create a database !!!!

Step 4: Create a table before deleting or adding data!

Step 5: declare the permission to write data to the SD card in the configuration file androidmainfest. xml. the permission has been described in the previous article. If you do not know the permission, go and check it.

Some children's shoes do not understand what default path methods contain tables? That's because we have the table creation operation when it creates a database by default, that is, the operation in the oncreate () method in the mysqliteopenhelper class! Therefore, if we want to create a table before deleting or adding data, the methods for creating the table are the same.

 

Conclusion: In either way, we need to create a database, create a table, and perform operations!

 

Note 4:

In Android, data is queried through the cursor class. When we use the sqlitedatabase. Query () method, we will get a cursor object, which points to each piece of data. It provides many query methods. The specific method is as follows:

 

The methods and descriptions are as follows:

 

Move takes the current position as a reference and moves the cursor to the specified position. If the cursor is successfully moved, true is returned. If the cursor fails, false is returned.

 

Movetoposition: move the cursor to the specified position. If the value is successful, true is returned. If the value is failed, false is returned.

 

Movetonext moves the cursor forward to a position. If the cursor is successfully moved, true is returned. If the cursor is failed, false is returned.

 

Movetolast moves the cursor backward to a position. If it succeeds, true is returned. If it fails, false is returned.

 

Movetofirst moves the cursor to the first row. If the row is successfully moved, true is returned. If the row fails, false is returned.

 

Isbeforefirst returns whether the cursor points to the first data item

 

After isafterlast returns whether the cursor points to the last data item

 

Isclosed returns whether cursor is disabled

 

Isfirst: Indicates whether cursor points to the first data item.

 

Islast returns whether cursor points to the last data item

 

Isnull returns whether the value at the specified position is null

 

Getcount returns the total number of data items.

 

Getint returns the specified index data in the current row.

 

Many children's shoes of SQLite have been touched, but I don't know how to store them in SD. So I have also studied how to provide the SD card in this article.

 

OK. This will be written for you just a few days after the New Year's Day holiday ~ It's about 2 o'clock in the morning ~ It's time to go to bed. (I usually go to bed at AM and get up to work at AM ~ Used ~)

(We recommend that you subscribe to this blog, because our update speed is very fast ~ Wahaha)

This article Source: http://www.himigame.com/android-game/329.html

 

 

 

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.