天天看點

【Android 練習】安卓存儲練習

文章目錄

  • ​​安卓存儲練習​​
  • ​​一、概述​​
  • ​​二、SharedPreferennces 的使用​​
  • ​​1.activity_shared_prefences.xml布局​​
  • ​​2.SharedPreferencesActivity​​
  • ​​三、SQLite資料庫​​
  • ​​1.SQLite簡介​​
  • ​​2.SQLite的特點​​
  • ​​3.簡單實作​​
  • ​​3.1 頁面布局​​
  • ​​3.2 Activity功能實作​​
  • ​​3.3 效果展示​​

安卓存儲練習

一、概述

存儲方式:

  • SharedPreferences
  • 臨時資料存儲
  • 本質是xml,存在标簽備援
  • 不安全,xml可以直接解析
  • 資料輕量級
  • SQLite資料庫
  • 增删改一般不使用緩存 — 實時
  • 資料量稍大,改動少 — 緩存應用場景
  • servlet 存儲是檔案形式,應用解除安裝後資料存儲永久性消失
  • 記憶體
  • SD卡

​​傳回頂部​​

二、SharedPreferennces 的使用

1.activity_shared_prefences.xml布局

【Android 練習】安卓存儲練習
<?xml versinotallow="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".store.SharedPreferencesActivity">

    <EditText
        android:id="@+id/data1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="48dp"
        android:ems="10"
        android:hint="資料1" />

    <EditText
        android:id="@+id/data2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="0dp"
        android:layout_marginTop="114dp"
        android:ems="10"
        android:hint="資料2" />

    <Button
        android:id="@+id/sShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_marginTop="260dp"
        android:layout_marginEnd="53dp"
        android:text="系統擷取"
        tools:layout_editor_absoluteX="89dp"
        tools:layout_editor_absoluteY="246dp" />

    <Button
        android:id="@+id/sAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_marginTop="205dp"
        android:layout_marginEnd="53dp"
        android:text="系統定義"
        tools:layout_editor_absoluteX="187dp"
        tools:layout_editor_absoluteY="334dp" />

    <Button
        android:id="@+id/pShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="41dp"
        android:layout_marginTop="258dp"
        android:text="自定義擷取"
        tools:layout_editor_absoluteX="116dp"
        tools:layout_editor_absoluteY="427dp" />

    <Button
        android:id="@+id/pAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="41dp"
        android:layout_marginTop="202dp"
        android:text="自定義存入"
        tools:layout_editor_absoluteX="257dp"
        tools:layout_editor_absoluteY="446dp" />

    <Button
        android:id="@+id/pDelete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="41dp"
        android:layout_marginTop="320dp"
        android:text="自定義删除"
        tools:layout_editor_absoluteX="257dp"
        tools:layout_editor_absoluteY="446dp" />

    <Button
        android:id="@+id/pUpdate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="41dp"
        android:layout_marginTop="384dp"
        android:text="自定義修改"
        tools:layout_editor_absoluteX="257dp"
        tools:layout_editor_absoluteY="446dp" />
</RelativeLayout>      

​​傳回頂部​​

2.SharedPreferencesActivity

package com.example.jyandroid.store;

import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.jyandroid.R;

public class SharedPreferencesActivity extends AppCompatActivity {

    EditText data1,data2;
    Button pAdd,pShow,pDelete,pUpdate,sAdd,sShow;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shared_prefences);

        data1 = findViewById(R.id.data1);
        data2 = findViewById(R.id.data2);
        pAdd = findViewById(R.id.pAdd);
        pShow = findViewById(R.id.pShow);
        pDelete = findViewById(R.id.pDelete);
        pUpdate = findViewById(R.id.pUpdate);
        sAdd = findViewById(R.id.sAdd);
        sShow = findViewById(R.id.sShow);

        // 增
        pAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*建構 SharedPreferences
                   參數:名稱+模式
                   1.MODE_PRIVATE           僅目前App中可使用共享資料
                   2.MODE_WORLD_READABLE    隻讀 ,已棄用
                   3.MODE_WORLD_WRITEABLE   可寫 ,已棄用
                   4.MODE_APPEND            追加
                 */
                SharedPreferences sp = getApplicationContext().getSharedPreferences("myDatas", Context.MODE_PRIVATE);
                // 添加資料,首先要建立Editor
                SharedPreferences.Editor editor = sp.edit();
                editor.putString("data1Str",data1.getText().toString().trim());
                editor.putFloat("data2Float", Float.parseFloat(data2.getText().toString().trim()));
                // 一定要送出
                editor.commit();
                Toast.makeText(SharedPreferencesActivity.this,"存入成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 删
        pDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences sp = getApplicationContext().getSharedPreferences("myDatas", Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = sp.edit();
                editor.clear();
                // 一定要送出
                editor.commit();
                Toast.makeText(SharedPreferencesActivity.this,"删除成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 改
        pUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences sp = getApplicationContext().getSharedPreferences("myDatas", Context.MODE_PRIVATE);
                // 添加資料,首先要建立Editor
                SharedPreferences.Editor editor = sp.edit();
                editor.putString("data1Str",data1.getText().toString().trim());
                editor.putFloat("data2Float", Float.parseFloat(data2.getText().toString().trim()));
                // 一定要送出
                editor.commit();
                Toast.makeText(SharedPreferencesActivity.this,"修改成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 查
        pShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences sp = getApplicationContext().getSharedPreferences("myDatas", Context.MODE_PRIVATE);
                // 查詢不需要使用Editor
                String data1Str = sp.getString("data1Str","");
                float data2Float = sp.getFloat("data2Float", 0.0f);
                String message = "資料1:" + data1Str +";資料2:"+ data2Float;
                Toast.makeText(SharedPreferencesActivity.this,message,Toast.LENGTH_SHORT).show();
            }
        });

        sAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*建構 SharedPreferences => PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                        使用系統預設的
                 */
                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                // 添加資料,首先要建立Editor
                SharedPreferences.Editor editor = sp.edit();
                editor.putString("data1Str",data1.getText().toString().trim());
                editor.putFloat("data2Float", Float.parseFloat(data2.getText().toString().trim()));
                // 一定要送出
                editor.commit();
                Toast.makeText(SharedPreferencesActivity.this,"存入成功!",Toast.LENGTH_SHORT).show();
            }
        });
        sShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                // 查詢不需要使用Editor
                String data1Str = sp.getString("data1Str","");
                float data2Float = sp.getFloat("data2Float", 0.0f);
                String message = "資料1:" + data1Str +";資料2:"+ data2Float;
                Toast.makeText(SharedPreferencesActivity.this,message,Toast.LENGTH_SHORT).show();
            }
        });

    }
}      

​​傳回頂部​​

三、SQLite資料庫

1.SQLite簡介

SQLite是一款輕量級的開源的嵌入式資料庫,由D.Richard Hipp在2000年釋出。SQLite使用友善,性能出衆,廣泛應用于消費電子、醫療、工業控制、軍事等各種領域。

​​傳回頂部​​

2.SQLite的特點

(1)體積小:最低隻需要幾百K的記憶體就可以運作。

(2)性能高:對資料庫的通路性能很高,其運作速度比Mysql等開源資料庫要快很多。

(3)可移植性強:能支援各種32位和64位體系的硬體平台,也能在Windows、Linux、BSD、Mac OS、Solaries等軟體平台中運作。

(4)SQL支援:SQLite支援ANSI SQL92中的大多數标準,提供了對子查詢、視圖、觸發器等機制的支援。

(5)接口:SQLite為C、Java、PHP、Python等多種語言提供了API接口,所有的應用程式都必須通過接口通路SQLite資料庫。

【Android 練習】安卓存儲練習

1)編譯器。編譯器由詞法分析、文法分析和中間代碼生成三個子產品組成。其中,詞法分析子產品和文法分析子產品負責檢查SQL語句的文法,然後把生成的文法樹傳遞給中間代碼生成子產品。中間代碼生成子產品負責生成SQLite引擎可以識别的中間代碼。

2)資料庫引擎。資料庫引擎是SQLite的核心,負責運作中間代碼,指揮資料庫的具體操作。

3)背景。背景由B樹、頁緩存和系統調用三個子產品組成。其中,B樹負責維護索引,頁緩存負責頁面資料的傳送,系統調用負責和作業系統互動,最終實作資料庫的通路。

值得一提的是,袖珍型的SQLite竟然可以支援高達2TB大小的資料庫,每個資料庫都是以單個檔案的形式存在,這些資料都是以B-Tree的資料結構形式存儲在磁盤上。

在事務處理方面,SQLite通過資料庫級上的獨占性和共享鎖來實作獨立事務處理。這意味着多個程序可以在同一時間從同一資料庫讀取資料,但隻有一個可以寫入資料。在某個程序或線程想資料庫執行寫操作之前,必須獲得獨占鎖。在獲得獨占鎖之後,其他的讀或寫操作将不會再發生。

SQLite采用動态資料類型,當某個值插入到資料庫時,SQLite将會檢查它的類型,如果該類型與關聯的列不比對,SQLite則會嘗試将該值轉換成該列的類型,如果不能轉換,則該值将作為本身的類型存儲,SQLite稱這為“弱類型”。但有一個特例,如果是INTEGER PRIMARY KEY,則其他類型不會被轉換,會報一個“datatype missmatch”的錯誤。

概括來講,SQLite支援 NULL、INTEGER、REAL、TEXT 和 BLOB 資料類型,分别代表空值、整型值、浮點值、字元串文本、二進制對象。

​​傳回頂部​​

3.簡單實作

3.1 頁面布局

【Android 練習】安卓存儲練習
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".store.SQLiteActivity">

    <EditText
        android:id="@+id/data"
        android:layout_width="399dp"
        android:layout_height="78dp"

        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_marginStart="9dp"
        android:layout_marginTop="447dp"
        android:layout_marginEnd="3dp" />

    <Button
        android:id="@+id/add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="62dp"
        android:layout_marginTop="178dp"
        android:text="增" />

    <Button
        android:id="@+id/delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_centerVertical="true"
        android:layout_marginStart="60dp"
        android:layout_marginTop="370dp"
        android:text="删" />

    <Button
        android:id="@+id/update"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="60dp"
        android:layout_marginTop="306dp"
        android:text="改" />

    <Button
        android:id="@+id/select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="61dp"
        android:layout_marginTop="241dp"
        android:text="查" />

    <Button
        android:id="@+id/create_table"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="15dp"
        android:layout_marginTop="109dp"
        android:text="建立表" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="35dp"
        android:text="SQLite操作"
         />
</RelativeLayout>      

​​傳回頂部​​

3.2 Activity功能實作

package com.example.jyandroid.store;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.jyandroid.R;
import java.io.File;
import java.util.ArrayList;

public class SQLiteActivity extends AppCompatActivity {

    // 按鈕元件
    private EditText data;
    private Button create_table,add,delete,update,select;
    private SQLiteDatabase sqLiteDatabase;

    @RequiresApi(api = Build.VERSION_CODES.O_MR1)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_s_q_lite);

        // 擷取元件
        data = findViewById(R.id.data);
        create_table = findViewById(R.id.create_table);
        add = findViewById(R.id.add);
        delete = findViewById(R.id.delete);
        update = findViewById(R.id.update);
        select = findViewById(R.id.select);

        // 建立資料庫檔案路徑
        File path = new File("/data/data/com.example.jyandroid/databases/");
        // 判斷檔案路徑是否存在
        if(!path.exists()){
            path.mkdirs();
        }
        // 建立資料庫
        // openOrCreateDatabase
        // 不是openDatabase!!!
        sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(new File(path + "/myDB.db"),null);

        // 建立表
        create_table.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                   VARCHAR(n)  可變長度字元串, n <= 4000
                   CHAR(n)     固定長度字元類型
                   INTEGER     整型資料
                   REAL        浮點型資料
                   TEXT        文本字元串
                   BLOB        Blob(Binary long Object)是二進制長對象的意思,Blob通常用于存儲大檔案,典型的Blob内容是一張圖檔或者一個聲音檔案,由于他們的特殊性,必須使用特殊的方式來存儲
                   DATE        日期類型
                   TIME        時間類型
                 */
                String sql =
                        "CREATE TABLE my_table1" +
                        "(" +
                        "id INTEGER PRIMARY KEY AUTOINCREMENT," +
                        "production_name TEXT," +
                        "production_price REAL" +
                        ")";
                sqLiteDatabase.execSQL(sql);
                // 提示
                Toast.makeText(SQLiteActivity.this,"建立表成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 增
        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                // 方式一:sql
                String sql = "insert into my_table (id,production_name,production_price) values ('蘋果',12.22)";
                sqLiteDatabase.execSQL(sql);
                // 提示
                Toast.makeText(SQLiteActivity.this,"添加成功!",Toast.LENGTH_SHORT).show();
                */

                // 方式二:android 提供的内置方法 insert(表名,空值預設值,ContentValues對象)
                ContentValues datas = new ContentValues();
                // 插入第一條資料
                datas.put("production_name","蘋果");
                datas.put("production_price","12.22");
                sqLiteDatabase.insert("my_table",null,datas);
                // 插入第二條資料
                datas.put("production_name","橙子");
                datas.put("production_price","18.50");
                sqLiteDatabase.insert("my_table",null,datas);
                // 插入第三條資料
                datas.put("production_name","橙子");
                datas.put("production_price","28.50");
                sqLiteDatabase.insert("my_table",null,datas);
                // 插入第四條資料
                datas.put("production_name","榴蓮");
                datas.put("production_price","8.50");
                sqLiteDatabase.insert("my_table",null,datas);
                // 插入第五條資料
                datas.put("production_name","草莓");
                datas.put("production_price","15.22");
                sqLiteDatabase.insert("my_table",null,datas);
                // 提示
                Toast.makeText(SQLiteActivity.this,"添加成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 删
        delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                // 方式一:sql
                String sql = "delete from my_table  where id = 1";
                sqLiteDatabase.execSQL(sql);
                */

                // 方式二:android 提供的内置方法 delete(表名,where條件,where args[])
                String whereClause = "production_name=? and production_price=?" ;
                sqLiteDatabase.delete("my_table",whereClause,new String[]{"榴蓮","8.50"});
                // 提示
                Toast.makeText(SQLiteActivity.this,"删除成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 改
        update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                // 方式一:sql
                String sql = "update my_table set production_name='芒果'";
                sqLiteDatabase.execSQL(sql);
                */

                // 方式二:Android提供的方法update(表名,ContentValues對象,whereClaus,where args[])
                ContentValues datas = new ContentValues();
                datas.put("production_price",15.00);
                String whereClause = "production_name=? and production_price>?";
                sqLiteDatabase.update("my_table",datas,whereClause,new String[]{"橙子","20.00"});
                // 提示
                Toast.makeText(SQLiteActivity.this,"修改成功!",Toast.LENGTH_SHORT).show();

            }
        });

        // 查
        select.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                // 方式一:sql
                String sql = "select * from my_table where production_name=? and production_price=?";
                Cursor cursor = sqLiteDatabase.rawQuery(sql,new String[]{"蘋果","12.22"});
                while(cursor.moveToNext()){
                    Toast.makeText(SQLiteActivity.this,cursor.getColumnIndex(0),Toast.LENGTH_SHORT).show();
                }
                */

                /*
                  方法二: Android的方法query()
                    參數清單:
                        distinct:是否去重
                        table:表名。相當于select語句from關鍵字後面的部分。如果是多表聯合查詢,可以用逗号将兩個表名分開。
                        columns:要查詢出來的列名。相當于select語句select關鍵字後面的部分。
                        selection:查詢條件子句,相當于select語句where關鍵字後面的部分,在條件子句允許使用占位符“?”
                        selectionArgs:對應于selection語句中占位符的值,值在數組中的位置與占位符在語句中的位置必須一緻,否則就會有異常。
                        groupBy:相當于select語句group by關鍵字後面的部分
                        having:相當于select語句having關鍵字後面的部分
                        orderBy:相當于select語句order by關鍵字後面的部分,如:id desc, age asc;
                        limit:指定偏移量和擷取的記錄數,相當于select語句limit關鍵字後面的部分。
                 */
                String[] columns = {"id","production_name","production_price"};
                String whereClause = " production_price>?";
                Cursor cursor = sqLiteDatabase.query(true,"my_table",columns,whereClause,new String[]{"10.00"},
                        null,null,"id desc", String.valueOf(2));
                ArrayList<MyTable> arrayList = new ArrayList();
                // 周遊
                while (cursor.moveToNext()){
                    MyTable myTable = new MyTable();
                    myTable.setId(cursor.getInt(0));
                    myTable.setProduction_name(cursor.getString(1));
                    myTable.setProduction_price(cursor.getDouble(2));
                    arrayList.add(myTable);
                }
                // 直接顯示查詢的資料
                for(MyTable myTable:arrayList){
                    Toast.makeText(SQLiteActivity.this,myTable.toString(),Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}      

​​傳回頂部​​

3.3 效果展示

建立表

【Android 練習】安卓存儲練習

插入資料

【Android 練習】安卓存儲練習
【Android 練習】安卓存儲練習

删除資料

【Android 練習】安卓存儲練習
【Android 練習】安卓存儲練習

修改資料

【Android 練習】安卓存儲練習
【Android 練習】安卓存儲練習

查詢資料

【Android 練習】安卓存儲練習