Android Studio中SQLite的使用,主要介紹sqlite插入和讀出圖片(ViewBinder)的操作方法

来源:https://www.cnblogs.com/zhangyiwen03/archive/2023/06/19/17471774.html
-Advertisement-
Play Games

# 一、Android程式員需要具備的素養 1. 應該熱愛學習Android知識 2. 具備基本的自學能力和解決問題的能力 3. 具備實踐能力 # 二、Android程式員最終需要熟練掌握的語言 1. Java(基本) 2. C/C++(進階) 3. Kotlin(基本) 4. Python(可選) ...


sqlite簡介

本人最近在寫一個小的安卓項目,開發app過程中用到了安卓自帶的sqlite。本文主要對sqlite圖片操作進行介紹,其他存入文本之類的操作和普通資料庫一樣,眾所周知,sqlite是一款輕型的資料庫,以下先簡單介紹一下sqlite,為後續做鋪墊,有瞭解的大佬可以跳過此部分:

 

SQLite是一種輕量級、嵌入式的關係型資料庫管理系統,它以庫的形式提供了一組編程介面,可以在各種操作系統上運行,如Windows、Linux、Mac OS等,被廣泛應用於移動設備和嵌入式系統中。SQLite的數據存儲在單個文件中,不需要專門的伺服器進程或後臺進程,它支持絕大多數的SQL語法,可以處理大部分中小型應用程式的數據存儲和管理需要。

 

SQLite的優點主要有以下幾個:

簡單易用:SQLite非常易於安裝和使用,只需要引入單個庫文件,便可以開始使用它提供的API進行開發。

小巧靈活:由於SQLite的設計目標定位為輕量級的資料庫管理系統,因此它的庫文件非常小巧,適合在嵌入式設備和移動終端中使用。

零配置:SQLite不需要任何專門的配置或安裝過程,用戶只需要將其API引入到程式中即可使用,大大簡化了部署和維護的工作。

相容性強:SQLite支持大部分標準的SQL語法,同時可以通過插件或擴展使用自定義的函數和AGGREGATE聚合函數。

 

SQLite的缺點也是比較明顯的:

不適合大規模數據存儲:由於SQLite的數據存儲在單個文件中,因此不適合處理大規模數據存儲的需求,處理大量數據的查詢和更新操作性能可能較差。

難以擴展:SQLite的特性和限制都固定在庫文件中,因此很難對其進行重構或擴展,無法滿足高度定製化需求。

 

總的來說,SQLite是一種非常輕量級的資料庫管理系統,在小型應用開發及移動端開發中十分適合,但在處理大規模數據存儲及高併發操作的應用場景下效果不佳。

 

插入圖片

進入正題,在使用sqlite的過程中,我遇到了插入圖片失敗的問題,查了不少資料,才知道sqlite不能直接存入.jpg還有.png之類的文件,需要以二進位的形式存儲在sqlite中,這也是為什麼上面說的sqlite不適合大規模數據存儲,是一個輕量級資料庫。我用下麵代碼來進一步說明

 

要用到的方法以及部分名詞說明:

 

Bitmap是Android系統中的圖像處理的最重要類之一。用它可以獲取圖像文件信息,進行圖像剪切、旋轉、縮放等操作,並可以指定格式保存圖像文件。

BitmapFactory.decodeResource(?,?)這個帶兩個參數的方法:第一個參數是包含你要載入的點陣圖資源文件的對象(一般寫成 getResources()就ok了);第二個時你需要載入的點陣圖資源的Id。

點陣圖介紹:點陣圖(Bitmap)格式其實並不能說是一種很常見的格式(從我們日常的使用頻率上來講,遠不如 .jpg .png .gif 等),因為其數據沒有經過壓縮,或最多只採用行程長度編碼(RLE,run-length encoding)來進行輕度的無損數據壓縮

這是一個寫好的調用語句和方法,insertdb()是寫好的方法,可以稍加修改後放入你的Activity頁面或fragment頁面,調用語句如圖。

複製代碼
//你的圖片在andriod studio中是存在R.drawble中的,並且是int型的
//存入資料庫的id是自己定義資料庫時設計好的,可以參考我的資料庫代碼
 
insertdb( R.drawable.你的圖片名,存入資料庫的id);
 
//s指你的圖片資源,int型,即R.drawable.你的圖片名
private void insertdb(int s,int id){
 
        //把你的圖片資源轉化成點陣圖
        Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), s);
 
        //Mysql是自己寫的資料庫類,需要自己編寫,下麵兩句話是實例化一個sqlite資料庫對象
        Mysql mySqlLite = new Mysql(this);
        SQLiteDatabase database = mySqlLite.getReadableDatabase();
        
        //設置一個size大小,用來壓縮圖片文件
        int size = bitmap.getWidth() * bitmap.getHeight() * 4;
 
        //ByteArrayOutputStream(位元組數組輸出流)對byte類型數據進行寫入的類,屬於記憶體操作流
        ByteArrayOutputStream baos= new ByteArrayOutputStream(size);
 
        //壓縮點陣圖bitmap
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
 
        //定義一個byte類型的數組bytedata存儲點陣圖位元組流轉化成的byte數組
        byte[] bytedata = baos.toByteArray();
 
        //sql語句是根據自己需求寫的,不要照抄
        database.execSQL("update 你的表名 set image=? where _id=?",new Object[] {bytedata,id});
    }
複製代碼 複製代碼
//MySQL.java
package 你的包名; import android.content.ContentValues; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class Mysql extends SQLiteOpenHelper { private static final String DB_NAME="INFORM.db"; private static final int DB_VERSION=1; public Mysql(Context context){ super(context,DB_NAME,null,DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL( "CREATE TABLE INFORMATION(" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," +"NAME TEXT," +"TITLE TEXT," +"image blob," +"TEXTS TEXT);" ); insertTest(db, "程式員", "程式員.exe無響應","祝你有美好的一天"); insertTest(db, "程式員", "已停止運行","下輩子再也不用sqlite了"); @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } public void insertTest(SQLiteDatabase db,String name,String title,String texts){ ContentValues value=new ContentValues(); value.put("NAME",name); value.put("TITLE",title); value.put("TEXTS",texts); db.insert("INFORMTION",null,value); } }
複製代碼

 

讀取圖片

已經往資料庫插入圖片了,現在可以讀取圖片了,這裡我用的是游標

複製代碼
package 你的包名;
 
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import com.example.garden.database.Mydb;
 
public class SearchResult extends AppCompatActivity implements AdapterView.OnItemClickListener {
 
    //定義游標
    private Cursor cursor;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search_result);
 
        Intent rit = getIntent();
        String text = rit.getStringExtra("key");
 
        ListView listview=findViewById(R.id.listview);
 
        //幫助器和管理器兩個老朋友了,實例化資料庫對象
        SQLiteOpenHelper helper=new Mydb(this);
        SQLiteDatabase db=helper.getWritableDatabase();
 
        //游標讀取資料庫
        cursor=db.rawQuery("select * from KNOW where name like '%"+text+"%'",null);
        cursor.moveToFirst();
 
        //資料庫的簡單游標適配器,簡單來說就是往模板填充內容的一個橋梁
        SimpleCursorAdapter mAdapter=new SimpleCursorAdapter(this,R.layout.item_list,
                cursor,new String[]{"NAME","image","TITLE"},new int[]{R.id.iv1,R.id.iv2,R.id.iv3},0);//自己的xml組件名R.id.iv1,R.id.iv2,R.id.iv3與資料庫欄位名"NAME","image","TITLE"對應,更多用法自己查
 
        //僅僅是上面的簡單游標適配器是不能讀取圖片的,重點來了,此處用到了ViewBinder
        SimpleCursorAdapter.ViewBinder binder=new SimpleCursorAdapter.ViewBinder() {
            @Override
            public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
 
        //判斷是否是ImageView,這個判斷非常關鍵,詳細可以按ctr去查找ViewBinder,就去文檔看,不要找其他資料,如果想真的搞懂一定要看!
                if (view instanceof ImageView) {
                    ImageView imageView = (ImageView) view;
 
           imageView.setImageBitmap(readImageFromDb(cursor.getString(cursor.getColumnIndex("_id"))));//為imageView配置id所對應的圖片   
                    return true;
                }
                return false;
            }
        };
 
        //配置ViewBinder
        mAdapter.setViewBinder(binder);
        //配置適配器
        listview.setAdapter(mAdapter);
        //點擊監聽器
        listview.setOnItemClickListener(this);
 
   }
 
    //
    @SuppressLint("Range")
    private Bitmap readImage(String id) {
 
    //至於為什麼又要實例化,是因為sqlite不能同時使用,術語不專業,總之要重新實例化,不然會報錯
        Mysql mySqlLite2 = new Mysql(this);
        SQLiteDatabase database2 = mySqlLite2.getReadableDatabase();
 
        Bitmap image= null;
        byte[] bytes;
        Cursor cursor = database2.rawQuery( "SELECT * FROM INFORMATION WHERE _id = ?", new String[]{id});
        if (cursor.moveToFirst()) {
            if ((bytes = cursor.getBlob(cursor.getColumnIndex("image"))) != null) {
                image= BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
            }
        }
        cursor.close();
        return image;
    }
 
 
    //listview的點擊事件
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //此處寫點擊事件,我用來傳值以及跳轉頁面
        Intent it=new Intent(this, Show.class);
        it.putExtra("ID",(int)id-1);
        startActivity(it);
        finish();
    }
}
複製代碼

 

 

可能會出現的問題

此處重點!我遇到的大問題目前只有一個,就是行過大導致無法讀取資料庫,原因是我放入的圖片太大了,大概1MB左右的樣子,我其他的圖片大小一般是200KB到500KB左右,1MB的圖片太大了,導致那個點陣圖轉化的二進位數據流太大了,資料庫無法一次讀取完,會導致程式直接崩潰,解決辦法就是不存入太大的圖片。畢竟它還只是個”孩砸“啊,sqlite是個輕量級的資料庫,不要存入太大的圖片

 

總結

寫代碼的過程中遇到了不少問題,感謝互聯網各位大佬發的參考資料,由於參考了許多資料和文獻,也因為當時寫的太快了沒有記住大佬的博客和文章,深表歉意,本項目後續完善後也會發到GitHub上面去,做一個開源小項目給大家參考,本人目前大二計科學生,希望和各位一同成長前進。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Getting started | Prometheus Configuration | Prometheus Download | Prometheus Download Grafana | Grafana Labs # prometheusmkdir -m=777 -p /data/{downl ...
  • # vi命令使用詳解 ### 1. 三種工作模式 1. 命令模式:通過**命令**對文件進行常規操作 * 打開文件時進入命令模式 **(vi的入口)** * 通過命令對文件進行常規操作,如定位、翻頁、複製、粘貼、刪除等在圖形界面下通過滑鼠或快捷鍵實現的的操作 2. 末行模式:執行**保存、退出**等 ...
  • 大家好,我是 god23bin。歡迎來到《一分鐘學一個 Linux 命令》系列,每天只需一分鐘,記住一個 Linux 命令不成問題。今天要說的是 ps 命令。 ...
  • MVCC併發版本控制 本文大部分來自《MySQL是怎樣運行的》,這裡只是簡單總結,用於各位回憶和複習。 版本鏈 對於使用 InnoDB 存儲引擎的表來說,它的聚簇索引記錄中都包含兩個必要的隱藏列(不知道的快去看《MySQL是怎樣運行的》) trx_id :每次一個事務對某條聚簇索引記錄進行改動時,都 ...
  • Linux安裝MongoDB 4.0.3 1.準備 CentOS下安裝MongoDB 官網提供windows、Linux、OSX系統環境下的安裝包,這裡主要是記錄一下在Linux下的安裝。首先到官網下載安裝包。文中安裝的是4.0.3版本的。 官網地址:https://www.mongodb.com/ ...
  • 近日,華為全球智慧金融峰會2023在上海順利舉行,華為雲副總裁、戰略與產業發展部總裁黃瑾發表了《做強堅實數據底座,GaussDB與產業攜手共進》的主題演講。 以下為演講實錄: 尊敬的各位來賓,大家下午好!非常高興和大家探討關於做堅實數據底座,GaussDB與產業攜手共進的一些思考。 中國資料庫市場發 ...
  • #報錯信息: ``` ****: 第4 行附近出現錯誤: 不是 GROUP BY 表達式 ``` #修改辦法: ######達夢可以配置相容參數,COMPATIBLE_MODE=4,靜態參數,需要重啟資料庫後生效! ``` sp_set_para_value(2,'COMPATIBLE_MODE', ...
  • 本文主要測試驗證 Elasticsearch 各版本快照在 [Easysearch](https://www.infinilabs.com/docs/latest/easysearch/overview) 中進行數據恢復。 ## 準備測試數據 ### 索引 ![](https://www.infin ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...