Android 开发
工程结构
目录结构
在 Android Studio 中,项目可以使用两种不同的目录结构:Project 结构和 Android 结构。这两种结构在项目组织和管理方面有一些区别:
Project 结构:
- 这种结构更接近传统的项目结构,通常用于更复杂的项目或多模块项目。
- 根目录下包含了项目的配置文件和 Gradle 构建文件,如 settings.gradle 和 build.gradle。
- 子目录包含了不同的模块,每个模块可能是一个应用程序模块、库模块或者测试模块。
- 这种结构更加灵活,可以更好地管理多个模块、库和依赖关系。
Android 结构:
- 这种结构更加简化,更适用于较小的项目或者初学者。
- 根目录下直接包含了应用程序模块,通常是一个单一的模块。
- 不同的资源(如布局、字符串、图像等)通常直接位于模块的特定目录中。
- 这种结构对于小型项目或者只有一个应用程序模块的项目更加方便和简洁。
在实际使用中,你可以根据项目的规模和需求选择合适的项目结构。如果你的项目比较简单,只有一个应用程序模块,那么 Android 结构可能更适合你。但如果你的项目较大,包含多个模块或者库,那么 Project 结构可能更适合你,因为它提供了更好的模块化和组织管理能力。
manifest 文件
AndroidManifest.xml 文件是 Android 应用程序的配置文件,它描述了应用程序的基本信息,如应用程序的包名、版本号、权限等。Android 系统会在安装应用程序时读取这个文件,以了解应用程序的基本信息。
java 文件夹
java 文件夹是 Android 应用程序的源代码目录,它包含了应用程序的所有 Java 源代码文件。
res/layout 文件夹
res/layout 文件夹是 Android 应用程序的布局文件目录,它包含了应用程序的所有布局文件。
Intent
在 Android 中,Intent
类是一个用于在不同组件之间进行通信的重要类。它可以用于启动活动(Activity)、服务(Service)、发送广播(Broadcast)、启动外部应用等。以下是关于 Intent
类的一些重要概念和功能:
Intent 的作用:
Intent
用于在应用程序内或者不同的应用程序之间传递消息和执行操作。- 它允许开发者请求系统执行特定的操作,或者请求系统将数据传递给其他组件。
Intent 的类型:
- 显式 Intent:指定了要启动的目标组件的类名,用于在同一应用程序内的组件之间进行通信。
- 隐式 Intent:没有明确指定目标组件的类名,而是根据给定的动作、类别和数据等信息由系统来确定目标组件。用于在不同应用程序之间进行通信。
Intent 的构造:
- 通过指定动作(Action)、数据(Data)、类别(Category)等信息来构造 Intent 对象。
- 可以使用
putExtra()
方法向 Intent 中添加额外的数据。
Intent 的使用场景:
- 启动活动:通过
startActivity()
方法启动新的活动。 - 启动服务:通过
startService()
或bindService()
方法启动服务。 - 发送广播:通过
sendBroadcast()
或sendOrderedBroadcast()
方法发送广播。 - 启动外部应用:通过隐式 Intent 启动其他应用程序中的组件。
- 传递数据:可以通过 Intent 在不同组件之间传递数据。
- 启动活动:通过
Intent 过滤器:
- 用于在清单文件中声明组件(如活动、服务、接收器等)可以响应的 Intent 类型。
- 通过
<intent-filter>
元素指定组件可以处理的动作、类别、数据等信息。
使用 Intent
类可以实现 Android 应用程序中各个组件之间的交互,包括启动活动、服务、发送广播等操作,从而实现应用程序的各种功能。
Activity
在 Android 开发中,Activity
是一种表示用户界面和用户交互的基本组件。每个 Activity
都对应于应用程序中的一个屏幕,它通常包含用户与应用程序进行交互的界面元素。例如,一个简单的应用可能有一个主活动,用于显示应用的主要用户界面,以及其他活动,用于执行不同的操作或显示不同的信息。
每个 Activity
都是 android.app.Activity
类的子类。一个简单的 Activity
可以通过继承 Activity
类并实现其中的方法来创建。以下是一个简单的 Activity
示例:
import android.app.Activity;
import android.os.Bundle;
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置该活动的用户界面
setContentView(R.layout.activity_main);
// 在这里可以执行其他初始化操作
}
}
在上述示例中,onCreate
方法是在活动创建时调用的,你可以在这里进行初始化设置,比如设置布局(通过 setContentView
方法)、绑定事件处理程序等。
活动之间可以相互启动,通过 Intent
对象传递数据。这种方式使得应用程序可以在不同的活动之间进行导航和交互。例如,通过点击按钮启动新的活动,或者从一个活动返回到上一个活动。
一个应用程序通常由多个活动组成,每个活动负责不同的任务或用户界面。Android 系统通过活动栈来管理活动的生命周期和用户导航。当用户与应用程序进行交互时,活动栈会根据用户的行为来调整活动的状态。
生命周期
在 Android 开发中,每个 Activity
都有自己的生命周期,它包括了一系列的生命周期方法,用于处理活动的创建、启动、暂停、恢复、停止和销毁等过程。这些生命周期方法可以帮助你管理活动的状态和行为,以便在不同的阶段执行不同的操作。
以下是 Activity
的生命周期方法:
onCreate
:在活动创建时调用,用于初始化活动的布局、视图、数据等。onStart
:在活动启动时调用,用于准备活动的用户界面。onResume
:在活动恢复时调用,用于恢复活动的状态和用户交互。onPause
:在活动暂停时调用,用于暂停活动的用户交互和数据操作。onStop
:在活动停止时调用,用于停止活动的用户界面和数据操作。onDestroy
:在活动销毁时调用,用于释放活动的资源和数据。onRestart
:在活动重新启动时调用,用于重新启动活动的用户界面和数据操作。
例如,你可以在 onCreate
方法中初始化活动的布局和视图,然后在 onStart
方法中准备活动的用户界面,最后在 onResume
方法中恢复活动的状态和用户交互。
生命周期回调
在 Android 开发中,Activity
的生命周期方法是由 Android 系统自动调用的,你可以重写这些方法来处理活动的状态和行为。例如,你可以在 onCreate
方法中初始化活动的布局和视图,然后在 onStart
方法中准备活动的用户界面,最后在 onResume
方法中恢复活动的状态和用户交互。
以下是一个简单的 Activity
示例,演示了如何重写生命周期方法:
import android.app.Activity;
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 初始化活动的布局和视图
}
@Override
protected void onStart() {
super.onStart();
// 准备活动的用户界面
}
@Override
protected void onResume() {
super.onResume();
// 恢复活动的状态和用户交互
}
@Override
protected void onPause() {
super.onPause();
// 暂停活动的用户交互和数据操作
}
@Override
protected void onStop() {
super.onStop();
// 停止活动的用户界面和数据操作
}
@Override
protected void onDestroy() {
super.onDestroy();
// 释放活动的资源和数据
}
@Override
protected void onRestart() {
super.onRestart();
// 重新启动活动的用户界面和数据操作
}
}
在上述示例中,我们重写了 Activity
的生命周期方法,用于处理活动的状态和行为。这些方法可以帮助你管理活动的生命周期,以便在不同的阶段执行不同的操作。
Service
在 Android 中,Service(服务)是一种用于执行长时间运行操作而不需要用户界面的组件。Service 可以在后台运行,并且即使用户切换到其他应用程序或者退出应用程序,Service 仍然可以继续运行。以下是关于 Service 组件的一些重要概念和用途:
服务的作用:
- 服务主要用于执行后台任务,例如下载文件、播放音乐、处理网络请求等。
- 服务通常用于那些不需要用户交互界面或者需要长时间运行的操作。
服务的生命周期:
onCreate()
: 当服务被创建时调用,只会在服务第一次创建时调用。onStartCommand(Intent intent, int flags, int startId)
: 当另一个组件通过 startService() 方法启动服务时调用。在此方法中,你可以执行你想要在服务中处理的操作。onBind(Intent intent)
: 当另一个组件通过 bindService() 方法绑定到服务时调用。onDestroy()
: 当服务不再被使用且将要被销毁时调用。在此方法中,你可以清理资源或者执行其他必要的清理操作。
服务的类型:
- 前台服务(Foreground Service):会在通知栏显示一个持久通知,用于用户可以看到服务正在运行的情况。通常用于执行用户需要立即知晓的操作,如播放音乐。
- 后台服务(Background Service):在后台执行任务,不会给用户显示通知。通常用于执行不需要用户知晓的操作,如数据同步、网络请求等。
服务与线程:
- Service 默认在主线程中运行,因此如果需要执行耗时操作,需要在 Service 中创建新线程或使用 Handler 等机制。
- 也可以使用 IntentService 类来简化在后台执行耗时操作的流程,因为 IntentService 会自动创建工作线程来处理任务。
服务的启动与绑定:
- 启动服务:通过
startService()
方法启动服务,服务会一直运行,直到调用stopService()
或者服务自行停止。 - 绑定服务:通过
bindService()
方法绑定服务,使得其他组件可以与服务进行交互,服务会随着绑定组件的生命周期而启动或停止。
- 启动服务:通过
服务是 Android 开发中一个重要的组件,它使得开发者可以在后台执行长时间运行的任务,同时保持应用程序的响应性和用户体验。
BroadcastReceiver
Broadcast Receiver(广播接收器)是 Android 中的一个组件,用于接收和响应系统广播消息或者应用程序内部广播消息。它可以让应用程序在特定事件发生时得到通知,并执行相应的操作。以下是关于 Broadcast Receiver 组件的一些重要概念和用途:
接收系统广播:
- Broadcast Receiver 可以注册接收系统发出的广播消息,如手机开机完成、电池电量改变、网络连接状态改变等。
- 通过注册感兴趣的广播消息,应用程序可以在特定事件发生时得到通知并执行相应的操作。
接收应用程序内部广播:
- 应用程序内部的组件(如活动、服务等)可以发送自定义的广播消息,而 Broadcast Receiver 可以接收并响应这些广播消息。
- 这使得应用程序内不同组件之间可以进行通信和协作。
注册方式:
- 在 AndroidManifest.xml 文件中静态注册:通过
<receiver>
元素在清单文件中声明广播接收器,并指定需要接收的广播消息类型。 - 在代码中动态注册:通过
registerReceiver()
方法在代码中动态注册广播接收器,并在不需要接收广播时使用unregisterReceiver()
方法取消注册。
- 在 AndroidManifest.xml 文件中静态注册:通过
处理广播消息:
- 当广播接收器接收到广播消息时,系统会调用其
onReceive()
方法,开发者可以在该方法中编写处理接收到广播消息的逻辑。 - 在
onReceive()
方法中执行的操作通常应该尽量简短,以免阻塞主线程。
- 当广播接收器接收到广播消息时,系统会调用其
广播的有序性:
- 广播可以是有序的或者无序的,有序广播允许多个接收器按照优先级顺序接收和处理广播消息。
- 可以通过设置
android:priority
属性或者使用setPriority()
方法来指定广播接收器的优先级。
Broadcast Receiver 是 Android 开发中一个重要的组件,它可以让应用程序接收系统广播消息和应用程序内部广播消息,从而实现对特定事件的监听和响应。
Content Provider
Content Provider(内容提供器)是 Android 中的一个组件,用于向其他应用程序提供访问本应用程序数据的接口。它提供了一种统一的方式来管理应用程序中的结构化数据,并且可以让其他应用程序通过 URI(Uniform Resource Identifier)来访问和操作这些数据。以下是关于 Content Provider 组件的一些重要概念和用途:
数据共享:
- Content Provider 允许应用程序向其他应用程序共享数据,包括但不限于数据库中的数据、文件系统中的文件、甚至是内存中的数据。
- 其他应用程序可以通过 Content Resolver(内容解析器)来访问和操作 Content Provider 中的数据。
URI(Uniform Resource Identifier):
- Content Provider 使用 URI 来标识要访问的数据。URI 由以下几部分组成:authority、path、ID 等。
- 例如,content://authority/path/id 表示访问某个特定数据的 URI。
CRUD 操作:
- Content Provider 支持标准的 CRUD(创建、读取、更新、删除)操作,以便其他应用程序可以对数据进行增加、查询、更新和删除等操作。
- 通过 URI 来指定操作的数据,可以对数据进行精确的操作。
权限控制:
- Content Provider 可以通过权限控制来限制其他应用程序对数据的访问权限,以保护数据的安全性和隐私性。
- 开发者可以在清单文件中声明 Content Provider 的权限,并在需要时通过权限验证来控制对数据的访问。
内置 Content Provider:
- Android 系统提供了一些内置的 Content Provider,如联系人数据(Contacts Provider)、媒体库数据(MediaStore Provider)等。
- 应用程序也可以创建自己的 Content Provider 来管理自己的数据,并且可以选择是否共享给其他应用程序。
Content Provider 是 Android 开发中一个重要的组件,它提供了一种统一的接口来管理和共享应用程序中的数据,从而实现了不同应用程序之间的数据交互和共享。
Handler 消息传递机制
在 Android 中,Handler 是用于在不同线程之间传递消息和执行任务的机制。它通常用于实现在后台线程中执行任务并在主线程中更新 UI 的需求。Handler 的工作原理是通过消息队列(Message Queue)和消息循环(Message Loop)来实现的。以下是关于 Handler 消息传递机制的详细介绍:
消息队列和消息循环:
- 每个线程在运行时都会有一个与之关联的消息队列,用于存储要处理的消息。消息队列采用先进先出(FIFO)的方式存储消息。
- 消息循环负责循环地从消息队列中取出消息,并交给对应的 Handler 处理。消息循环会在没有消息时进入阻塞状态,直到有新消息到来。
Handler:
- Handler 是与特定线程关联的消息处理器,用于将消息发送到相应的消息队列中,并处理消息队列中的消息。
- 通过 Handler 可以发送消息、延迟发送消息以及处理消息。
消息(Message):
- 消息是一个轻量级的对象,用于封装要发送的数据和操作。每个消息对象可以包含一个标识符(what)、任意对象(obj)、整型数据(arg1、arg2)、延迟时间等信息。
- Handler 可以通过 sendMessage() 方法将消息发送到消息队列中,然后由消息循环处理。
工作流程:
- 当调用 Handler 的 sendMessage() 方法发送消息时,消息会被添加到 Handler 关联的线程的消息队列中。
- 消息循环会不断地从消息队列中取出消息,并交给对应的 Handler 进行处理。
- Handler 在处理消息时,会根据消息的标识符和携带的数据执行相应的操作,例如更新 UI、执行任务等。
主线程的 Handler:
- 在 Android 中,通常将 Handler 与主线程关联,以便在后台线程中执行耗时操作后,通过主线程的 Handler 更新 UI。
- 通过在主线程中创建 Handler 对象,可以在后台线程中发送消息到主线程,并在主线程中处理消息,从而更新 UI。
通过使用 Handler,开发者可以在不同线程之间进行消息传递和任务执行,实现了线程间的通信和协作,使得在 Android 开发中更容易实现异步操作、后台任务和 UI 更新等需求。
Handler 类
Handler 类是 Android 中用于在不同线程之间传递消息和执行任务的核心类之一。它主要用于在后台线程中执行任务并在主线程中更新 UI 的需求。以下是关于 Handler 类的详细介绍:
基本概念和作用:
- Handler 是与特定线程关联的消息处理器,用于将消息发送到消息队列中,并处理消息队列中的消息。
- 它允许您发送和处理与线程关联的消息对象。这些消息可以是空消息或包含数据的消息,并且可以在指定的时间后发送。
构造函数:
- Handler 类有多个构造函数,常用的有:
Handler()
:创建一个与当前线程关联的 Handler 对象。Handler(Looper looper)
:创建一个与指定 Looper 关联的 Handler 对象。
- Handler 类有多个构造函数,常用的有:
常用方法:
sendMessage(Message msg)
:将消息发送到与此 Handler 关联的消息队列中,消息将在消息队列中的消息循环中被处理。post(Runnable r)
:将 Runnable 对象添加到与此 Handler 关联的消息队列中,在消息队列中的消息循环中执行。postDelayed(Runnable r, long delayMillis)
:将 Runnable 对象延迟一定时间后添加到与此 Handler 关联的消息队列中,在消息队列中的消息循环中执行。removeCallbacks(Runnable r)
:从消息队列中移除指定的 Runnable 对象,以防止其执行。sendMessageAtTime(Message msg, long uptimeMillis)
:在指定的时间发送消息。sendMessageDelayed(Message msg, long delayMillis)
:延迟一定时间后发送消息。sendEmptyMessage(int what)
:发送一个空消息。sendEmptyMessageDelayed(int what, long delayMillis)
:延迟一定时间后发送一个空消息。removeMessages(int what)
:从消息队列中移除指定 what 值的消息。removeCallbacksAndMessages(Object token)
:从消息队列中移除所有属于指定对象 token 的消息和回调。
用法示例:
- 创建 Handler 并在主线程中执行任务:
javaHandler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { // 在主线程中执行任务 textView.setText("Hello, Handler!"); } });
- 延迟执行任务:
javaHandler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { // 延迟执行任务 textView.setText("Delayed task executed!"); } }, 2000); // 2 秒后执行
- 在后台线程中更新 UI:
javanew Thread(new Runnable() { @Override public void run() { // 执行耗时操作 // ... // 在主线程中更新 UI Handler mainHandler = new Handler(Looper.getMainLooper()); mainHandler.post(new Runnable() { @Override public void run() { // 更新 UI textView.setText("Updated from background thread!"); } }); } }).start();
通过使用 Handler,您可以在不同线程之间进行消息传递和任务执行,实现了线程间的通信和协作,使得在 Android 开发中更容易实现异步操作、后台任务和 UI 更新等需求。
持久化存储
在 Android 中,持久化存储指的是将数据保存在设备的存储介质上,以便在应用关闭后数据仍然保持可用,并且在设备重启后数据不会丢失。Android 提供了多种持久化存储的方式,包括以下几种:
SharedPreferences:
- SharedPreferences 是 Android 中用于存储小量键值对数据的一种机制,适用于保存应用的配置信息、用户偏好设置等数据。
- SharedPreferences 存储的数据是以键值对的形式存储在 XML 文件中,并且可以跨多个 Activity 和应用组件共享访问。
文件存储:
- Android 应用可以通过文件存储方式将数据以文件的形式保存在设备的内部存储空间或外部存储卡中。
- 内部存储空间的文件存储适用于私有数据,外部存储卡则适用于共享数据和大文件存储。
SQLite 数据库:
- SQLite 是 Android 中的轻量级关系型数据库管理系统,用于存储结构化数据。
- Android 应用可以使用 SQLite 数据库来创建和管理数据库,并在其中存储应用的数据,如用户信息、日志数据等。
Room Persistence Library:
- Room 是 Android 官方提供的 SQLite 数据库的抽象层和 ORM(对象关系映射)库,简化了 SQLite 数据库的使用。
- Room 提供了便捷的 API 和注解来定义数据库实体、数据访问对象(DAO)和数据库操作。
网络存储:
- Android 应用可以将数据存储在远程服务器上,并通过网络访问来获取数据。
- 可以使用诸如 HTTP、RESTful API、WebSocket 等网络通信技术与服务器进行数据交互。
选择适合的持久化存储方式取决于数据的类型、大小、访问频率以及安全性要求等因素。通常情况下,SharedPreferences 适用于存储小量简单的键值对数据,文件存储适用于存储中等大小的数据,而 SQLite 数据库适用于存储结构化的大量数据。 Room Persistence Library 则是在使用 SQLite 数据库时的一种方便的选择,提供了更高级的抽象和便捷的数据库操作方法。
SharedPreferences
SharedPreferences 是 Android 提供的一种轻量级的数据存储机制,用于存储应用的配置信息、用户偏好设置等简单的键值对数据。SharedPreferences 存储的数据是以 XML 文件的形式保存在应用的私有目录中。以下是关于 SharedPreferences 的相关 API 及其用法实例:
相关 API:
获取 SharedPreferences 对象:
getSharedPreferences(String name, int mode)
:获取指定名称的 SharedPreferences 对象。getPreferences(int mode)
:获取当前 Activity 对应的 SharedPreferences 对象。
编辑 SharedPreferences 数据:
SharedPreferences.Editor
:用于编辑 SharedPreferences 数据的编辑器对象。edit()
:获取 SharedPreferences 的编辑器对象。putXXX(String key, XXX value)
:向 SharedPreferences 中存入数据,其中 XXX 表示数据类型,如 putInt、putString、putBoolean 等。remove(String key)
:从 SharedPreferences 中移除指定键对应的数据。clear()
:清空 SharedPreferences 中的所有数据。apply()
:将编辑器中的修改应用到 SharedPreferences,并异步提交(推荐使用)。commit()
:将编辑器中的修改应用到 SharedPreferences,并同步提交。
读取 SharedPreferences 数据:
getXXX(String key, XXX defValue)
:从 SharedPreferences 中获取指定键对应的数据,如果不存在,则返回默认值 defValue。contains(String key)
:判断 SharedPreferences 是否包含指定键对应的数据。
用法实例:
// 获取 SharedPreferences 对象
SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE);
// 获取 SharedPreferences.Editor 对象并进行数据编辑
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("username", "John");
editor.putInt("age", 25);
editor.putBoolean("isLogged", true);
editor.apply(); // 将修改应用到 SharedPreferences,推荐使用 apply()
// 从 SharedPreferences 中读取数据
String username = sharedPreferences.getString("username", "");
int age = sharedPreferences.getInt("age", 0);
boolean isLogged = sharedPreferences.getBoolean("isLogged", false);
// 输出读取到的数据
Log.d("SharedPreferences", "Username: " + username);
Log.d("SharedPreferences", "Age: " + age);
Log.d("SharedPreferences", "IsLogged: " + isLogged);
以上示例展示了如何使用 SharedPreferences 进行数据的存储和读取。首先通过 getSharedPreferences()
方法获取 SharedPreferences 对象,然后通过 edit()
方法获取 SharedPreferences.Editor 对象进行数据编辑,最后使用 apply()
方法将修改应用到 SharedPreferences 中。在读取数据时,使用 getString()
、getInt()
、getBoolean()
等方法从 SharedPreferences 中获取数据。SharedPreferences 提供了简单而便捷的方式来存储和管理应用的配置信息和用户偏好设置。
SQLite 数据库
SQLite 是 Android 中内置的一种轻量级关系型数据库管理系统,它支持大部分 SQL92 的标准查询语言的功能,并且使用单一的磁盘文件存储整个数据库,因此非常适合在移动设备上使用。以下是关于 SQLite 数据库的详细介绍:
特点:
- 轻量级:SQLite 数据库的文件大小相对较小,适合在移动设备上使用。
- 零配置:SQLite 数据库无需任何配置,即可开始使用。
- 无服务器:SQLite 数据库是基于文件的,不需要额外的服务器进程来管理。
- 支持 ACID 事务:支持事务的原子性、一致性、隔离性和持久性。
- 跨平台:SQLite 数据库可以在多种操作系统平台上运行。
创建数据库:
- 在 Android 中,可以通过继承
SQLiteOpenHelper
类来创建和管理 SQLite 数据库。 - 在
SQLiteOpenHelper
的onCreate()
方法中创建数据库表,并在onUpgrade()
方法中处理数据库版本升级。
- 在 Android 中,可以通过继承
操作数据库:
- 使用 SQL 语句执行数据库操作,包括创建表、插入数据、查询数据、更新数据、删除数据等。
- SQLite 支持常见的 SQL 语句,如 CREATE TABLE、INSERT INTO、SELECT、UPDATE、DELETE 等。
数据类型:
- SQLite 支持多种数据类型,包括 INTEGER、REAL、TEXT、BLOB 等。
- INTEGER:整型数据类型,可以存储整数。
- REAL:浮点型数据类型,可以存储浮点数。
- TEXT:文本型数据类型,用于存储字符串。
- BLOB:二进制数据类型,用于存储二进制数据。
数据库操作 API:
- Android 提供了一组用于操作 SQLite 数据库的 API,包括
SQLiteDatabase
、SQLiteOpenHelper
、Cursor
等类。 SQLiteDatabase
类用于执行 SQL 语句和事务操作。SQLiteOpenHelper
类用于创建和管理数据库,包括创建数据库、创建表格等操作。Cursor
类用于查询数据库,并提供了遍历查询结果的方法。
- Android 提供了一组用于操作 SQLite 数据库的 API,包括
异步数据库操作:
- 为了避免在主线程中执行耗时的数据库操作,通常将数据库操作放在子线程中执行,以避免阻塞主线程。可以使用 AsyncTask 或其他方式来实现异步数据库操作。
SQLite 数据库是 Android 中常用的持久化存储方式之一,适用于存储结构化的大量数据。通过使用 SQLite 数据库,可以轻松地创建和管理数据表,执行 SQL 查询和事务操作,并实现数据的增删改查功能。
SQLiteOpenHelper 类
SQLiteOpenHelper
是 Android 中用于创建和管理 SQLite 数据库的辅助类。它提供了一种方便的方式来管理数据库的创建、升级和降级,以及对数据库的版本控制。以下是关于 SQLiteOpenHelper
类的详细介绍:
创建数据库:
SQLiteOpenHelper
负责管理一个 SQLite 数据库的创建和版本控制。通常,您需要继承SQLiteOpenHelper
类并实现其方法来创建您自己的数据库。- 在您的子类中,您需要实现
onCreate()
方法,用于在首次创建数据库时执行初始化操作,例如创建表格等。
版本管理:
SQLiteOpenHelper
还负责数据库版本的管理。每当数据库的版本号发生变化时,系统都会调用onUpgrade()
方法,您可以在此方法中执行数据库升级操作,例如修改表结构、添加新表格等。- 版本号通常在应用的
SQLiteOpenHelper
子类的构造函数中指定,并且应当递增,以便系统能够识别数据库版本的变化。
实现方法:
onCreate(SQLiteDatabase db)
:当数据库首次创建时调用此方法。您应在此方法中执行数据库的初始化操作,例如创建表格。onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
:当数据库需要升级时调用此方法。您应在此方法中执行数据库升级操作,例如修改表结构。onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)
:当数据库需要降级时调用此方法。通常情况下不建议降级数据库,该方法提供了一个空实现。
使用示例:
- 创建一个自定义的
SQLiteOpenHelper
子类,并实现其方法:
javapublic class MyDatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "mydatabase.db"; private static final int DATABASE_VERSION = 1; public MyDatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { // 创建表格 db.execSQL("CREATE TABLE IF NOT EXISTS my_table (" + "_id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT," + "age INTEGER)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 数据库升级操作 if (oldVersion < 2) { // 旧版本小于 2,执行升级操作 } if (oldVersion < 3) { // 旧版本小于 3,执行升级操作 } // ... } }
- 在应用中使用自定义的
SQLiteOpenHelper
子类来创建和管理数据库:
javaMyDatabaseHelper dbHelper = new MyDatabaseHelper(context); SQLiteDatabase db = dbHelper.getWritableDatabase(); // 获取可写数据库对象
- 创建一个自定义的
通过继承 SQLiteOpenHelper
类并实现其方法,您可以方便地管理 SQLite 数据库的创建、升级和降级,从而实现对数据库的版本控制和管理。