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上面去,做一个开源小项目给大家参考,本人目前大二计科学生,希望和各位一同成长前进。

Android Studio中SQLite的使用,主要介绍sqlite插入和读出图片(ViewBinder)的操作方法的更多相关文章

  1. Eclipse和Android Studio中的DDMS使用时什么不同?

    http://www.jb51.net/softjc/454131.html Eclipse和Android Studio中的DDMS使用时什么不同? 相信很多经常开发Android应用的朋友应该都接 ...

  2. Android Studio中配置及使用OpenCV示例

    Android Studio配置及使用OpenCV 前言:最近在做项目移植,项目较大,在Eclipse中配置的Jni及OpenCV环境没任何问题,但是迁移到Studio中就问题一大堆,网上也找了一些资 ...

  3. 浅谈Windows下SVN在Android Studio中的配置、基本使用及解除关联

    看到网上很多关于svn环境配置和关联Android-Studio的很多博文,发现很零散,想集大家所长整理一下: 在AndroidStudio中开发版本控制中,除了Git就是SVN,和Eclipse不同 ...

  4. Android Studio中创建Kotlin For Android项目

    Kotlin俗称Android中的Swift,它是Jetbrains公司开发的基于JVM的一门语言,JetBrains公司可能大家并不熟悉,不过相信IntelliJ IDE大家一定知道,Android ...

  5. 浅谈Kotlin(一):简介及Android Studio中配置

    浅谈Kotlin(一):简介及Android Studio中配置 浅谈Kotlin(二):基本类型.基本语法.代码风格 浅谈Kotlin(三):类 浅谈Kotlin(四):控制流 前言: 今日新闻:谷 ...

  6. jdk1.8新特性之lambda表达式及在Android Studio中的使用举例

    Jdk1.8已经出很久了但是很多同学对它的特性在android studio 中的应用可能还不是很熟悉,今天我们就来对这个新特性在AS中做它的应用实践. 一.首先在有JDK1.8的情况下我们要在AS的 ...

  7. Android Studio 中的FindBugs插件使用,轻松帮你发现Bug (转)

    在日常开发过程中难免会因为一时疏忽而留下一些Bug,这些Bug就是埋在程序里的定时炸弹,如果不能及时铲除就会导致程序的不稳定,异常或闪退的现象,从而导致用户的体验的下降.那么怎么才能找出这些埋在程序里 ...

  8. 在Android Studio中调用so中的方法

    本节用的so是上节用Android Studio创建的so.想在Android Studio中调用so中的方法,需要先引用so.Android Studio中引用so的方法有二种,下面开始介绍. 一 ...

  9. 在Android Studio中创建项目和模拟器

    北京电子科技学院 实      验      报      告 课程:移动平台应用开发实践  班级:201592  姓名:杨凤  学号:20159213 成绩:___________  指导老师:娄嘉 ...

  10. Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用

    在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法.可是我们能发现Messenger是以串行的方式来处理client ...

随机推荐

  1. 【命令设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    简介 命令模式(Command Pattern)是一种数据驱动的设计模式,也是一种行为型设计模式.这种模式的请求以命令的形式包裹在对象中,并传给调用对象.调用对象再寻找合适的对象,并把该命令传给相应的 ...

  2. Hugging News #0331: Hugging Papers 来啦,快来认领你的论文!

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  3. Oracle宕机之PMON (ospid: 248987): terminating the instance due to error 484(另附hugepage配置方法)

    数据库版本:11.2.0.4 RAC环境 操作系统版本:Asianux Server release 7.3 数据库报错分析 接到业务消息,应用无法访问,开发人员查看日志后发现无法连接数据库. 查看数 ...

  4. 一文彻底搞懂Raft算法,看这篇就够了!!!

    最近需要设计一个分布式系统,需要一个中间件来存储共享的信息,来保证多个系统之间的数据一致性,调研了两个主流框架Zookeeper和ETCD,发现都能满足我们的系统需求.其中ETCD是K8s中采用的分布 ...

  5. Oracle安装及各种问题

    --hsql 1:jdk 本机位置:E:\Program Files\Java\jdk1.7.0_80\ 安装教程:复制然后配置环境变量 (1)新建->变量名"JAVA_HOME&qu ...

  6. 如何在微信小程序中实现音视频通话

    微信小程序的音视频通话可以通过微信提供的实时音视频能力实现.这个能力包括了音视频采集.编码.传输和解码等多个环节,开发者只需要使用微信提供的 API 接口就可以轻松地实现音视频通话功能. 在具体实现上 ...

  7. DVWA上low级别反射型,存储型,DOM型XSS攻击获取用户cookie

    1.什么是反射型 XSS 攻击? 反射型 XSS 是指应用程序通过 Web 请求获取不可信赖的数据,并在未检验数据是否存在恶意代码的情况下,将其发送给用户. 反射型 XSS 一般可以由攻击者构造带有恶 ...

  8. Centos7 安装 codeblocks 搭建 C++ 集成开发环境

    1 安装GCC和G++ yum install gcc yum install gcc-c++ 2 安装gtk-devel 默认没有安装开发所需要的文档 yum install gtk* 3 安装wx ...

  9. Intellij_idea for循环 快捷键

    for循环四次.用 i 进行for循环 4.for fori 增强for循环 int [] arrays=new int[2]; arrays.for

  10. 【SpringMVC】(三)

    HTTPMessageConverter HttpMessageConverter报文信息转换器,将请求报文转换为java对象,或将java对象转换为响应报文. 1 @ResquestBody Res ...