Android实验:contentprovider 实验+SQLite 数据库的实现

目录

  • SQLite
  • 实验目的
  • 实验内容
  • 实验要求
  • 项目结构
  • 代码实现
  • 结果展示

SQLite

SQLite 是一个开源的嵌入式关系数据库,实现了自给自足的、无服务器的、配置无需的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库系统不同,比如 MySQL、PostgreSQL 等,SQLite 不需要在系统中设置和管理一个单独的服务。这也使得 SQLite 是一种非常轻量级的数据库解决方案,非常适合小型项目、嵌入式数据库或者测试环境中

SQLite 的一些主要特性包括:

无服务器的:SQLite 不是一个单独的服务进程,而是直接嵌入到应用程序中。它直接读取和写入磁盘文件
事务性的:SQLite 支持 ACID(原子性、一致性、隔离性、持久性)属性,能够确保所有事务都是安全、一致的,即使在系统崩溃或者电力中断的情况下
零配置的:SQLite 不需要任何配置或者管理,这使得它非常容易安装和使用
自包含的:SQLite 是一个自包含系统,这意味着它几乎不依赖其他任何外部系统或者库,这使得 SQLite 的跨平台移植非常方便
小型的:SQLite 非常小巧轻量,全功能的 SQLite 数据库引擎的大小只有几百KB
广泛应用:SQLite 被广泛应用在各种各样的产品和系统中,包括手机、平板电脑、嵌入式系统、物联网设备等。它也被广泛用于网站开发、科学研究、数据分析等领域
在一些轻量级的应用场景下,SQLite 是一个非常理想的选择,因为它简单、高效、易于使用和部署。然而,对于需要处理大量并发写操作或者需要更高级的功能(如用户管理或者存储过程等)的应用场景,更全功能的数据库系统(如 PostgreSQL 或 MySQL)可能会是更好的选择
当然了,这里只是见到那的提一下关于SQLite的内容,想深入了解可以自行查阅资料

实验目的

1、 掌握如何在 Android 开发中使用 SQLite 数据库
2、 熟悉设计数据库表结构的方法与步骤
3、 理解 contentprovider 的使用方法及流程,理解 ContentProvider、
Resolver、Uri、Urimatcher 等的原理。

实验内容

1、实现 contentprovider 和 contentresolver 通过 uri 的调用;
2、实现 contentprovider 对数据库 sqlite 的功能:增、删、改、查;
3、数据库的表结构自行设计;

实验要求

1、配置 SQLite 数据库的运行环境
2、熟悉 contentprovider 对数据库 sqlite 增、删、改、查的具体操作和流程
3、充分理解 SQLite 数据库的使用原理和方式

项目结构

在这里插入图片描述

代码实现

ContentProvider

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;public class ContentProvider extends android.content.ContentProvider {private Context mContext;DBHelper mDbHelper = null;SQLiteDatabase db = null;@Overridepublic boolean onCreate() {mContext = getContext();mDbHelper = new DBHelper(getContext());db = mDbHelper.getWritableDatabase();db.execSQL("delete from user");db.execSQL("insert into user values(1,'丁真');");db.execSQL("insert into user values(2,'孙笑川');");return true;}@Overridepublic Uri insert(Uri uri, ContentValues values) {String table = DBHelper.USER_TABLE_NAME;db.insert(table, null, values);mContext.getContentResolver().notifyChange(uri, null);return uri;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder){String table = DBHelper.USER_TABLE_NAME;return db.query(table, projection, selection, selectionArgs, null, null, sortOrder, null);}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {String table = DBHelper.USER_TABLE_NAME;return db.update(table, values, selection, selectionArgs);}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {String table = DBHelper.USER_TABLE_NAME;return db.delete(table, selection, selectionArgs);}@Overridepublic String getType(Uri uri) {return null;}
}

DBHelper

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import android.widget.Toast;import androidx.annotation.Nullable;public class DBHelper extends SQLiteOpenHelper {private static final String DATABASE_NAME = "Student";// 表名public static final String USER_TABLE_NAME = "user";private static final int DATABASE_VERSION = 1;//数据库版本号public DBHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL("CREATE TABLE IF NOT EXISTS " + USER_TABLE_NAME + "(_id INTEGER PRIMARY KEY AUTOINCREMENT," + " name TEXT)");}@Overridepublic void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {}
}

myActivty

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;import com.example.exp61.R;import java.util.ArrayList;
import java.util.List;
import java.util.Random;public class myActivity extends Activity {// 设置URIprivate Uri uri = Uri.parse("content://com.example.exp61.ui.theme.ContentProvider/user");ContentResolver resolver;Button bt_add, bt_delete, bt_querry, bt_update;ListView listView;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.myactivity);bt_add = findViewById(R.id.b_add);bt_delete = findViewById(R.id.b_delete);bt_querry = findViewById(R.id.b_querry);bt_update = findViewById(R.id.b_update);listView = findViewById(R.id.list_view);bt_add.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {ContentValues values = new ContentValues();values.put("_id",4);values.put("name", "luyunchi");resolver = getContentResolver();resolver.insert(uri, values);Toast.makeText(myActivity.this, "添加成功", Toast.LENGTH_SHORT).show();}});bt_querry.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {List<String> data = new ArrayList<String>();resolver = getContentResolver();Cursor cursor = resolver.query(uri, new String[]{"_id","name"}, null, null, null);while (cursor.moveToNext()){data.add(cursor.getInt(0) + " " + cursor.getString(1));}ArrayAdapter<String> adapter=new ArrayAdapter<>(myActivity.this,android.R.layout.simple_list_item_1,data);listView.setAdapter(adapter);cursor.close();Toast.makeText(myActivity.this, "查询完成", Toast.LENGTH_SHORT).show();}});bt_delete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {resolver = getContentResolver();String selection = "_id = ?";String [] Arg = new String[]{"2"};int rowsAffected = resolver.delete(uri, selection, Arg);if (rowsAffected > 0) {Toast.makeText(myActivity.this, "删除成功", Toast.LENGTH_SHORT).show();} else {Toast.makeText(myActivity.this, "删除失败", Toast.LENGTH_SHORT).show();}}});bt_update.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {ContentValues values = new ContentValues();values.put("_id", 10);String selection = "_id = ?";String [] Arg = new String[]{"1"};resolver = getContentResolver();int rowsAffected = resolver.update(uri, values, selection, Arg);if (rowsAffected > 0) {Toast.makeText(myActivity.this, "更新成功", Toast.LENGTH_SHORT).show();} else {Toast.makeText(myActivity.this, "更新失败", Toast.LENGTH_SHORT).show();}}});}
}

myactivity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><ListViewandroid:id="@+id/list_view"android:layout_width="match_parent"android:layout_height="455dp" /><Buttonandroid:id="@+id/b_add"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="添加" /><Buttonandroid:id="@+id/b_delete"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="删除" /><Buttonandroid:id="@+id/b_update"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="更新" /><Buttonandroid:id="@+id/b_querry"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="查询" /></LinearLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.Exp61"tools:targetApi="31"><activityandroid:name=".ui.theme.myActivity"android:exported="true"android:label="@string/app_name"android:theme="@style/Theme.Exp61"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><providerandroid:name=".ui.theme.ContentProvider"android:authorities="com.example.exp61.ui.theme.ContentProvider"android:exported="true"/></application></manifest>

结果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/586112.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全面好用的setting.xml配置

<?xml version"1.0" encoding"UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information…

轻松实现iphone截图传电脑

目录 摘要 引言 用户登录工具和连接设备 生成截图 摘要 本篇博文介绍了克魔助手这款工具&#xff0c;解决了iPhone与Windows系统下图片传输的烦恼。通过连接同一Wi-Fi&#xff0c;使用克魔助手轻松实现了iPhone截图传输到电脑上的便捷操作。用户只需简单地下载并安装克魔助…

前端优化 - 防抖和节流

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; CSS专栏&#xff1a;想学CSS的&#xff0c;冲这里 &#x1f4…

使用Go-Gin框架实现 OSS 前端直传功能

引言 在现代 Web 应用中&#xff0c;文件上传是一项常见功能。传统的上传方式通常需要文件经过后端服务器转发到对象存储服务&#xff08;如阿里云 OSS&#xff09;。然而&#xff0c;这种方法可能对服务器造成额外的负担&#xff0c;并降低上传效率。本文将探讨如何使用 Go-G…

Harmony全局应用生命周期 EntryAbility.ts 讲解

之前 我们说过 page页面的生命周期 组件的生命周期 其实他和uni一样有一个整个应用的生命周期 我们如下图打开EntryAbility.ts 这是我们整个程序app的状态控制 他这里也有几个全局的生命周期 比如 我们手机 点开当前 App 启动 app 会触发 它的 onCreate 生命周期 当我们从手…

Elasticsearch 8.X进阶搜索之“图搜图”实战

Elasticsearch 8.X “图搜图”实战 1、什么是图搜图&#xff1f; "图搜图"指的是通过图像搜索的一种方法&#xff0c;用户可以通过上传一张图片&#xff0c;搜索引擎会返回类似或者相关的图片结果。这种搜索方式不需要用户输入文字&#xff0c;而是通过比较图片的视…

米贸搜|LinkedIn和Facebook在营销上有哪些区别?

一、领英做营销有哪些优势&#xff1f; 领英为什么受到很多营销人员的欢迎呢?因为领英的功能和大多数的社交平台都有所不同&#xff0c;自然在做营销这一方面也有其他平台所不能达到的优势&#xff0c;在这里也为大家总结了几点&#xff1a; 1、领英是一个专业的职场社交平台…

前端八股文(工程化篇)

目录 1.常用的git命令有哪些&#xff1f; 2.git rebase和git merge的区别 3.有哪些常见的Loader和Plugin&#xff1f; 4.webpack的构建流程 5.bundle,chunk,module是什么&#xff1f; 6.如何提高webpack的打包速度 7.vite比webpack快在哪里 8.说一下你对Monorepo的理解 …

MySQL MVCC精讲

版本链 我们前面说过&#xff0c;对于使用InnoDB存储引擎的表来说&#xff0c;它的聚簇索引记录中都包含两个必要的隐藏列&#xff08;row_id并不是必要的&#xff0c;我们创建的表中有主键或者非NULL的UNIQUE键时都不会包含row_id列&#xff09;&#xff1a; trx_id&#xff…

GBASE南大通用-GBase 8s分片表操作 提升大数据处理性能

目录 一、GBase 8s分片表的优势 二、六种分片方法 轮转 1.轮转法 基于表达式分片 2.基本表达式 3.Mod运算表达式 4.Remainder关键字方式 5.List方式 6.interval 固定间隔 三、分片表的索引 1.创建索引的注意事项 2.detach索引替代delete功能展现 3.在现有分片表上增加一个新…

状态模式-概述

在软件系统中&#xff0c;有些对象也像水一样具有多种状态&#xff0c;这些状态在某些情况下能够相互转换&#xff0c; 而且对象在不同的状态下也将具有不同的行为。相同的方法在不同的状态中可能会有不同的实现。 为了实现不同状态下对象的各种行为以及对象状态之间的相互转换…

【Apache Doris】自定义函数之 JAVA UDF 详解

【Apache Doris】自定义函数之 JAVA UDF 详解 一、背景说明二、原理简介三、环境信息3.1 硬件信息3.2 软件信息 四、IDE准备五、JAVA UDF开发流程5.1 源码准备5.1.1 pom.xml5.1.2 JAVA代码 5.2 mvn打包5.2.1 clean5.2.2 package 5.3 函数使用5.3.1 upload5.3.2 使用 六、注意事…

2023年03月18日_微软office365 copilot相关介绍

文章目录 Copilot In WordCopilot In PowerpointCopilot In ExcelCopilot In OutlookCopilot In TeamsBusiness Chat1 - copilot in word2 - copilot in excel3 - copilot in powerpoint4 - copilot in outlook5 - copilot in teams6 - business chat word 1、起草草稿 2、自动…

JavaScript使用教程(二):类型、值和变量

计算机程序通过操作值&#xff08;如数值3.14&#xff09;或文本&#xff08;如“Hello World”&#xff09;来工作。编程语言中这些可以表示和操作的值被称为类型&#xff0c;而一门语言支持的类型集也是这门语言最基本的特征。程序在需要把某个值保存下来以便将来使用时&…

腾讯云系统盘50G通用型SSD云硬盘不够用怎么办?

腾讯云服务器系统盘50G通用型SSD云硬盘不够用怎么办&#xff1f;可以云硬盘扩容&#xff0c;也可以挂载数据盘。腾讯云服务器的系统盘可以不停服在线扩容&#xff0c;数据存储也可以通过挂载数据盘来实现更大的容量空间。腾讯云百科txybk.com分享腾讯云服务器系统盘不够用的操作…

2023 年终总结

引言 先说 2022 年留下的期待完成情况 健身&#xff0c;经过教练的指导后&#xff0c;自己开始做计划锻炼了&#xff0c;逐渐掌握到健身的要领&#xff1a;脸皮厚。 读书&#xff1a;今年可以说是读书最多的一年了&#xff0c;书单很长 旅行&#xff1a;去了上海&#xff0c;哈…

HTML5 Canvas 面试题

HTML5 Canvas 面试题 什么是HTML5 Canvas&#xff1f; Canvas是HTML5提供的一个绘图API&#xff0c;它允许通过JavaScript在网页上动态绘制图形、图像以及进行图形处理。 如何在HTML中创建一个Canvas元素&#xff1f; 使用<canvas>标签即可创建一个Canvas元素&#xff0…

VSCODE 修改Test模式下的的java jvm堆内存大小

在settings.json中添加如下语句 "java.test.config": {"vmArgs": ["-Xmx12G"]},

LeetCode75| 单调栈

目录 739 每日温度 901 股票价格跨度 739 每日温度 求后面第一个比他大的元素的位置&#xff0c;单调栈需要递增 求后面第一个比他小的元素的位置&#xff0c;单调栈需要递减 本题栈头到栈底的顺序应该从小到大 class Solution { public:vector<int> dailyTemperatures…

k8s中DaemonSet实战详解

一、DaemonSet介绍 DaemonSet 的主要作用&#xff0c;是在 Kubernetes 集群里&#xff0c;运行一个 Daemon Pod。DaemonSet 只管理 Pod 对象&#xff0c;然后通过 nodeAffinity 和 Toleration 这两个调度器参数的功能&#xff0c;保证了每个节点上有且只有一个 Pod。 二、Daem…