版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android数据存储与处理前言在Android应用开发旅程中,数据存储与处理是构建强大业务功能的关键。本章将聚焦于Android平台的核心数据存储技术,特别是SharedPreferences和SQLite数据库。掌握这些技术,将赋予我们的应用以数据持久化的能力,为实现复杂的业务逻辑提供坚实的基础。目录01Android数据存储方式03SQLite数据存储与处理02SharedPreferences数据存储与处理
6.1Android数据存储方式
6.1.1Android提供常用数据存储方式(1)SharedPreferences数据存储:一种轻量级数据存储方式,适用于存储应用配置和用户设置等少量简单数据。(2)文件数据存储:适用于保存图片、音频、视频等整体数据块。(3)SQLite数据库存储:通过SQL语句管理结构化数据,适合存储业务对象等复杂数据结构。(4)网络数据存储:通过远程服务器实现数据的开放存储,适用于互联网应用,需配合后端服务器接口使用。(5)ContentProvider作为数据分享接口,允许不同应用间共享数据,但并非直接的数据存储方式。本章主要介绍Android特有的SharedPreferences和SQLite数据存储。
6.1Android数据存储方式
数据存储方式文件存储SharedPreferencesSQLite数据库ContentProvider网络存储特点:openFileInput()和openFileOutput()读取设备上的文件。特点:以XML格式将数据存储到设备。特点:运算速度快,占用资源少,还支持基本SQL语法。特点:应用程序之间的数据交换,可以将自己的数据共享给其他应用程序使用。特点:通过网络提供的存储空间来存储/获取数据信息。
6.2
SharedPreferences数据存储与处理
6.2.1什么是SharedPreferencesSharedPreferences是Android的一种轻量级存储类,特别适合用于保存软件配置参数和用户信息。微信:字体大小今日头条:播放与网络设置6.2.1什么是SharedPreferencesSharedPreferences的主要特点如下:(1)数据以键值对的形式存储,键和值都是基础类型数据。(2)通过getSharedPreferences()方法获得SharedPreferences。(3)一般配合SharedPreferences.Editor来对存储的数据进行修改。(4)修改后需要调用commit()方法apply()方法提交变更。(5)通过SharedPreferences的getInt()、getString()等方法读取数据。(6)数据被保存在XML文件中,每份SharedPreferences对应一个XML文件。(7)有公有、私有等多种存储模式,私有模式下的数据只能被本程序访问。(8)不适合存储复杂数据,适合存储轻量级配置信息。(9)线程安全,可以在多线程环境中使用。
6.2
SharedPreferences数据存储与处理
6.2
SharedPreferences数据存储与处理
6.2.2SharedPreferences常用方法方法名功能描述getSharedPreferences(name,mode)在Activity中获取SharedPerferences对象。参数name指定文件名,mode指定操作模式。sharedPerferences.edit()获取SharedPerferences.Editor对象应用,以写入数据。editor.putXXX(key,value)存入指定key对应的数据。sharedPerferences.getXXX(key)获取指定key对应的数据。editor.apply()/mit()提交修改,推荐使用apply。editor.remove(key)删除指定key对应的数据。editor.clear()清空所有数据。editor.contains()判断是否包含数据。
6.2
SharedPreferences数据存储与处理
6.2.3SharedPreferences的写入(1)获取SharedPreferences对象:可以通过getSharedPreferences()方法或getPreferences()方法获取。(2)获取SharedPreferences.Editor对象:可以通过SharedPreferences对象的edit()方法获取。(3)向SharedPreferences.Editor对象中添加数据:可以使用putString()、putInt()、putBoolean()等方法。(4)提交数据,可以使用commit()方法或apply()方法提交数据。
6.2
SharedPreferences数据存储与处理
6.2.3SharedPreferences的写入参考示例:
6.2
SharedPreferences数据存储与处理
6.2.3SharedPreferences的写入写入SharedPreferences数据后,可以通过DeviceFileExplorer查看生产的数据文件。可以看到SharedPreferences数据是XML格式的。
6.2
SharedPreferences数据存储与处理
6.2.4SharedPreferences的读取(1)获取SharedPreferences对象:使用getSharedPreferences方法获得SharedPreferences对象(2)通过SharedPreferences对象获取数据:通过getString()、getInt()、getBoolean()等方法获取数据。
6.2
SharedPreferences数据存储与处理
6.2.4SharedPreferences的读取参考示例:
6.3SQLite数据存储与处理
6.3.1SQLite数据库SQLite是一种轻量级的关系数据库,由RichardHipp于2000年创建。SQLite的核心代码主要由C语言开发,是一种世界上使用广泛的数据库,常常被用于各类小型系统和设备中。与其他关系数据库相比,SQLite又具有如下自身特点:(1)SQLite体积小,资源占用少。(2)自包含,无需额外安装和配置。(3)免费且开源。(4)跨平台,可在多种操作系统上运行。(5)使用简单,兼容性强,易于上手。(6)功能全面,支持标准SQL、事务和高级数据库特性。
6.3SQLite数据存储与处理
6.3.1SQLite数据库Android平台内置SQLite数据库,Android应用可直接使用。在开发、设计时,通过SQLiteExpertProfessional等客户端软件可以创建并测试SQLite数据库。
6.3SQLite数据存储与处理
6.3.1SQLite数据库SQLite中,表字段常用数据类型如下:数据类型说明NULL空值,表示该字段的值为空INTEGER整型REAL浮点型TEXT文本字符串型,使用数据库设定的编码(UTF-8、UTF-16BE或UTF-16LE)存储BLOB二进制形式,用于存放图片、音频等,不建议过多使用
6.3SQLite数据存储与处理
6.3.1SQLite数据库1.DDL语句创建表语法:
示例:createtabletbl_user(idintegerprimarykeyautoincrement,usernametext
notnull,passwordtext
not
null);CREATETABLE数据表名(字段名数据类型约束,字段名数据类型约束,…);
6.3SQLite数据存储与处理
6.3.1SQLite数据库1.DDL语句删除表语法:
示例:DROPTABLEtbl_user;DROPTABLE数据表名;
6.3SQLite数据存储与处理
6.3.1SQLite数据库2.DML语句,增删改查语法:/*插入数据*/INSERTINTO表名(字段1,字段2,...)values(字段值1,字段值2,...);/*删除数据*/DELETEFROM表名WHERE筛选条件;/*更新数据*/UPDATE表名SET字段1=值1,字段2=值2,...WHERE筛选条件;/*查询数据*/SELECT字段列表FROM表名WHERE筛选条件ORDERBY排序字段列表;
6.3SQLite数据存储与处理
6.3.1SQLite数据库2.DML语句,增删改查示例:/*查询数据*/select*fromtbl_user;/*插入数据*/insertintotbl_user(username,password)values('zhangsan','1234');insertintotbl_user(username,password)values('lisi','1234');insertintotbl_user(username,password)values('zhaoliu','1234');/*删除数据*/deletefromtbl_userwhereid=3;/*更新数据*/updatetbl_usersetusername='li4'whereid=2;
6.3SQLite数据存储与处理
6.3.1SQLite数据库在Android平台上的SQLite开发前,对SQL语法不熟悉的同学建议在客户端中先行测试。
6.3SQLite数据存储与处理
6.3.2SQLiteOpenHelper1.Android中的SQLite开发中的常用类:类说明SQLiteOpenHelper用于创建和打开数据库的帮助类。SQLiteDatabase一个SQLite示例,用于执行SQL语句。Cursor数据库游标,表示执行SQL语句后结果集中的每行记录。ContentValues用于封装插入或更新数据行时的键值对数据。SQLiteStatement预编译的SQLite程序,可以重复执行。SQLiteException数据库操作产生的异常。
6.3SQLite数据存储与处理
6.3.2SQLiteOpenHelper2.SQLiteOpenHelper概述:SQLiteOpenHelper是Android中用于数据库创建、版本升级和开启操作的关键辅助类。其作用主要有:(1)创建与版本管理:SQLiteOpenHelper自动创建和升级数据库,简化数据库管理。(2)避免重复操作:使用单例模式,防止重复打开和创建数据库。(3)事件回调支持:通过onCreate()和onUpgrade()方法,实现数据库创建和版本升级时的自定义操作。(4)简化数据库访问:通过getReadableDatabase()和getWritableDatabase()方法连接数据库并获取数据库读写对象。
6.3SQLite数据存储与处理
6.3.2SQLiteOpenHelper3.Android中SQLite的使用步骤:(1)自定义子类继承SQLiteOpenHelper,重写onCreate()和onUpgrade()方法。(2)在onCreate()中执行创建数据表操作。(3)在onUpgrade()方法中执行删除或修改数据表等升级操作。(4)在构造函数中传递数据库名称、版本号等给父类对象。(5)调用getWritableDatabase()方法或getReadableDatabase()方法获取SQLiteDatabase示例。(6)使用SQLiteDatabase执行创建表、插入数据等操作。
6.3SQLite数据存储与处理
6.3.2SQLiteOpenHelper4.SQLiteOpenHelper常用方法方法说明onCreate()在第一次创建数据库时调用,重写该方法可以实现数据库的创建和初始化onUpgrade()在升级数据库时调用,重写该方法可以实现删除、添加数据表或修改数据表结构等操作,以满足程序升级到新版本时对数据库结构的修改需求SQLiteOpenHelper()构造方法,创建一个帮助对象,打开或管理数据库。该方法通常快速返回。数据库并没有实际被创建或打开,直到getWritableDatabase()方法或getReadableDatabase()方法被调用close()关闭任何打开的数据库getWritableDatabase()创建或打开一个数据库,获取的是一个可用于读取和写入数据的SQLite示例。该方法被调用时,数据库被打开,相应的onCreate()方法、onUpgrade()方法或onOpen()方法将被调用getReadableDatabase()创建或打开数据库,和getWritableDatabase()方法返回的对象是同一个,获取的是一个只可以用于读取的SQLite示例。该方法被调用时,数据库被打开,相应的onCreate()方法、onUpgrade()方法或onOpen()方法将被调用
6.3SQLite数据存储与处理
6.3.2SQLiteOpenHelper5.SQLiteOpenHelper建库首次执行getReadableDatabase()或getWritableDatabase()时,onCreate方法被调用。
6.3SQLite数据存储与处理
6.3.2SQLiteOpenHelper6.SQLiteOpenHelper升级库当数据库版本号增加时,触发onUpgrade()执行。
6.3SQLite数据存储与处理
6.3.3SQLiteDatabase1.SQLiteDatabase概述SQLiteDatabase用于管理SQLite数据库,对数据库中的数据进行增加、修改、删除、查询、执行SQL命令,并执行其他常见的数据库管理任务。方法说明voidexecSQL(Stringsql)执行非查询的SQL语句。voidexecSQL(Stringsql,Object[]bindArgs)执行一个非查询的SQL语句。longinsert(Stringtable,StringnullColumnHack,ContentValuesvalues)插入数据行。intdelete(Stringtable,StringwhereClause,String[]whereArgs)删除数据行。
intupdate(Stringtable,ContentValuesvalues,StringwhereClause,String[]whereArgs)更新数据行。CursorrawQuery(Stringsql,String[]args)执行原生SQL语句。
6.3SQLite数据存储与处理
6.3.3SQLiteDatabase2.使用SQLiteDatbase(1)插入数据
6.3SQLite数据存储与处理
6.3.3SQLiteDatabase(2)删除数据
6.3SQLite数据存储与处理
6.3.3SQLiteDatabase(3)更新数据示例
6.3SQLite数据存储与处理
6.3.3SQLiteDatabase(4)查询数据示例
6.3SQLite数据存储与处理
6.3.4分层结构与DAO模式1.分层结构和DAO在一定规模的项目中,通常采用三层结构来优化代码,提高重用性和维护性。三层结构分别为:(1)表示层(UI):界面部分。(2)业务逻辑层(Service):封装业务逻辑代码。(3)数据访问层(DAO):封装数据库增删改查操作。
6.3SQLite数据存储与处理
6.3.4分层结构与DAO模式2.应用DAO模式(1)封装数据实体类实体类用于保存某一数据表中的记录对象。
6.3SQLite数据存储与处理
6.3.4分层结构与DAO模式(2)封装DAO对象:封装某个数据表的增删改查功能。本章小结Android数据存储方式SharedPreferences数据存储与处理SQLite数据库的使用常用SQL语句(常用DDL、DML)使用SQLiteOpenHelper为应用创建数据库使用SQLiteDatabase实现数据的增删改查使用分层结构和DAO模式开发。ContentProvider前言ContentProvider(内容提供者)是Android应用开发中的一个关键组件,负责管理数据的共享和访问。本章将深入介绍它的重要性、应用场景和基本概念,以帮助读者全面了解其在Android应用开发中的重要性;并探讨它的工作原理,了解它如何协调不同应用之间的数据共享,提供标准的数据访问接口;使用它共享数据,使用ContentResolver操作数据,以及使用ContentObserver监听数据。03使用ContentResolver
操作数据04使用ContentObserver监听数据目录01ContentProvider简介02使用ContentProvider共享数据
7.1ContentProvider简介
7.1.1ContentProvider的重要性和应用场景当谈到Android应用的数据共享和访问时,ContentProvider是一个不可或缺的组件。它是Android平台中的一个重要部分,用于管理和共享应用数据,以及实现跨应用的数据交换。它在Android应用开发中扮演着重要的角色,主要表现在:1)数据隔离和安全性;2)跨应用数据交换;3)数据访问接口统一;4)多线程操作支持。常见的应用场景包括:1)设备联系人和日历数据访问;2)外部媒体文件访问;3)设置和配置信息共享;4)数据库访问;5)搜索功能。
7.1ContentProvider简介
7.1.2ContentProvider的基本概念和工作原理每个ContentProvider都可以管理一种或多种类型的数据,如数据库中的表、文件等。它的功能逻辑如图所示。应用可以通过ContentResolver来进行数据的增删改查,ContentResolver会根据URI找到相应的ContentProvider并进行数据操作。
7.1ContentProvider简介
7.1.2ContentProvider的基本概念和工作原理ContentProvider的工作原理涉及以下几个方面。1)注册和声明;2)URI匹配和权限验证;3)数据操作处理;4)数据返回;通过上述过程,ContentProvider实现了应用之间的数据共享和访问。其他应用可以通过ContentResolver发起请求,并通过URI获取数据。ContentProvider在内部处理数据操作,以确保数据的安全性和一致性。这使得Android应用能够更好地协同工作,并实现更多的功能。
7.2使用ContentProvider共享数据
7.2.1Uri简介ContentProvider使用的Uri在Android应用开发中非常重要,Uri用于标识和定位ContentProvider中的数据。Uri提供了一种统一的方式来描述资源的位置,使得应用可以准确地访问和操作数据。Uri的用途:标识资源位置、描述操作、控制权限;Uri的组成结构:scheme://authority/pathUriMatcher:用于帮助ContentProvider解析URI并匹配相应的操作。
7.2使用ContentProvider共享数据
7.2.2创建ContentProvider首先,定义一个数据模型,即创建DragonBoatContract,包括name字段、date字段、decor字段、location字段,程序代码如下:publicclassDragonBoatContract{publicstaticclassRaceEntryimplementsBaseColumns{publicstaticfinalStringTABLE_NAME="races";publicstaticfinalStringCOLUMN_NAME="name";publicstaticfinalStringCOLUMN_DATE="date";publicstaticfinalStringCOLUMN_DECOR="decor";publicstaticfinalStringCOLUMN_LOCATION="location";}}
7.2使用ContentProvider共享数据
7.2.2创建ContentProvider其次,创建自定义的ContentProvider,并定义URI和UriMatcher。在实际开发中,不需要手动创建类和在清单文件中添加标签,在AndroidStudio中可以使用快捷方式创建所有组件,ContentProvider也不例外。把鼠标指针移移到包名处并右击,在弹出的快捷菜单中选择“New”→“Other”→“ContentProvider”命令,弹出如图所示的“NewAndroidComponent”对话框。
7.2使用ContentProvider共享数据
7.2.3设置权限设置权限在Android应用中是非常重要的,它可以帮助控制应用对系统和其他应用资源的访问权限,确保数据的安全性。在使用ContentProvider时,设置权限是一个关键的方面,可以限制其他应用对共享数据的访问。<providerandroid:name=".DragonBoatProvider"android:authorities="vider"android:enabled="true"android:exported="true"android:permission="android.permission.READ_WRITE"/>
7.3使用ContentResolver操作数据
7.3.1ContentResolver简介ContentResolver是Android应用中的一个关键类,用于在应用之间进行数据通信。它充当了应用与ContentProvider之间的桥梁,使得某个应用能够访问和共享其他应用或系统中的数据。ContentResolver提供了一系列方法来操作数据:1)query()方法用于执行数据查询操作;2)insert()方法用于执行数据插入操作;3)update()方法用于执行数据更新操作;4)delete()方法用于执行数据删除操作。
7.3使用ContentResolver操作数据
7.3.2使用ContentResolver在Activity中,使用ContentResolver来查询DragonBoatProvider提供的比赛日期,并将其显示出来。Uriuri=Uri.parse("content://vider/races/date");Cursorcursor=getContentResolver().query(uri,null,null,null,null);
TextViewspecialFeatureTextView=findViewById(R.id.specialFeatureTextView);
if(cursor!=null&&cursor.moveToFirst()){StringraceDate=cursor.getString(cursor.getColumnIndex(DragonBoatContract.RaceEntry.COLUMN_DATE));specialFeatureTextView.setText("比赛日期:"+raceDate);cursor.close();}
7.4使用ContentObserver监听数据
7.4.1ContentObserver简介ContentObserver(内容观察者)是用于监听数据变化的组件。它可以注册监听特定的URI,当该URI对应的数据变化时,ContentObserver会接收到相应的通知。ContentObserver基于观察者设计模式,使应用能够实时获取数据的变化并采取相应的操作。ContentObserver的主要作用有:监听数据变化、实时更新UI、执行后续操作、数据同步和自动化处理,以及管理数据依赖关系。
7.4使用ContentObserver监听数据
7.4.2使用ContentObserver首先,创建一个继承Android提供的ContentObserver的子类,并在该子类中实现onChange()方法,用于处理数据变化的通知。publicclassDragonBoatObserverextendsContentObserver{privatefinalTextViewspecialFeatureTextView;privatefinalContextcontext;publicDragonBoatObserver(Handlerhandler,Contextcontext,TextViewtextView){super(handler);this.context=context;this.specialFeatureTextView=textView;}@OverridepublicvoidonChange(booleanselfChange,Uriuri){super.onChange(selfChange,uri);specialFeatureTextView.setText("最新比赛日期:1999-09-09");}}
7.4使用ContentObserver监听数据
7.4.2使用ContentObserver其次,在需要监听数据变化的位置创建ContentObserver的示例,并注册ContentObserver监听。Uriuri=Uri.parse("content://vider/races/date");ContentResolvercontentResolver=getContentResolver();DragonBoatObserverobserver=newDragonBoatObserver(newHandler(),MainActivity.this,findViewById(R.id.specialFeatureTextView));contentResolver.registerContentObserver(uri,true,observer);Cursorcursor=contentResolver.query(uri,null,null,null,null);if(cursor!=null){while(cursor.moveToNext()){//处理查询结果
//此处省略业务逻辑代码}cursor.close();}
7.4使用ContentObserver监听数据
7.4.2使用ContentObserverContentObserver是如何知道数据变化的呢?答案是ContentResolver,它提供了notifyChange()方法,可以手动触发数据变化的通知。在进行数据变化的操作后,调用ContentResolver的notifyChange()方法,并传入相应的URI,将通知注册的ContentObserver的数据已经发生了变化,。Uriuri=Uri.parse("content://vider/races/date");ContentResolverresolver=getContentResolver();DragonBoatObserverobserver=newDragonBoatObserver(newHandler(),MainActivity.this,findViewById(R.id.specialFeatureTextView));resolver.notifyChange(uri,observer);本章小结掌握如何创建自定义的ContentProvider,以及如何使用它与SQLite集成,从而实现数据持久化;知道ContentObserver的注册和注销、onChange()方法回调的使用方法,以及如何结合ContentObserver来实现UI的更新和数据的同步;如何使用ContentObserver监听数据。Service
与
IntentService前言Service
是一种可以在后台执行长时间运行操作而不提供界面的应用组件。
使用Service执行长时间运行操作还是可能会导致界面阻塞,引发系统的ANR错误,Android框架还提供了Service的IntentService子类来解决这个问题。02IntentService目录01Service
8.1Service
8.1.1Service的类型Service即服务,包括以下类型:(1)前台Service:执行一些用户会直接注意到的操作。例如,音频应用会使用前台Service来播放音频曲目。(2)后台Service:执行用户不会直接注意到的操作。例如,如果应用使用某个Service来压缩其存储空间。(3)绑定型Service:通过用
bindService()
方法绑定到Service时,该Service处于绑定状态。使用导航时,关闭屏幕,导航应用会继续服务
8.1Service
8.1.1Service的类型Service重要回调方法:1)onStartCommand()方法:前台Service与后台Service的业务逻辑实现函数。2)onBind()方法:绑定型Service必须实现的回调函数,返回
IBinder
提供一个接口,以供客户端与Service进行通信,非绑定型则返回null。3)onCreate()方法:首次创建Service时执行一次性设置程序的回调函数。4)onDestroy()方法:Service销毁前的回调函数,应通过该方法清理资源。
8.1Service
8.1.2创建Service选择菜单“File”→“New”→“Service”→“Service”
ClassName:Service的类名。Exported:Service的exported属性。Enabled:Service的enabled属性。SourceLanguage:代码语言。
8.1Service
8.1.2创建Service创建完成后清单文件增加了Service的注册信息
8.1Service
8.1.3Service属性常用属性说明name实现Service的类名。enabled确定系统是否可以示例化Service。exported确定其他应用组件是否可以调用Service或与之交互。permission实体启动Service或绑定到Service所需的权限名。process运行Service的进程名。
8.1Service
8.1.4创建启动型Service通过将
Intent
传递给
startService()
方法或
startForegroundService()方法。Android会调用Service的
onStartCommand()
方法,并向其传递
Intent。Intentintent=newIntent(this,MyService.class);startService(intent);
8.1Service
8.1.5停止启动型Service启动型Service
必须自己管理生命周期。Service在
onStartCommand()
方法返回后仍会继续运行。必须通过自身调用
stopSelf()
方法自行停止,或由另一个应用组件通过调用
stopService()
方法停止。
8.1Service
8.1.6创建绑定型Service绑定型Service允许应用组件通过调用
bindService()
方法与其绑定。需要通过实现
onBind()
方法返回
IBinder,从而定义与Service进行通信的接口。多个客户端可以同时绑定到Service。完成与Service的交互后,客户端会通过调用
unbindService()
方法取消绑定。
8.1Service
8.1.6创建绑定型Service客户端通过调用unbindService()取消绑定。绑定型Service由系统停止,系统检测到没有绑定到Service的客户端,则会销毁该Service。
8.1Service
8.1.6创建绑定型Service定义接口的方法:1.扩展BinderService供自有应用专用,且在与客户端相同的进程中运行。
8.1Service
8.1.6创建绑定型Service定义接口的方法:2.使用Messenger若需让接口跨不同进程工作,则可以使用
Messenger
为Service创建接口。
8.1Service
8.1.6创建绑定型Service定义接口的方法:3.使用AIDL如果想让Service同时处理多个请求,那么可以直接使用AIDL。
8.1Service
8.1.7扩展Binder设置方式:(1)在Service中,创建可执行以下某种操作的
Binder
示例。1).包含客户端可调用的公共方法。2).返回当前
Service
示例,该示例中包含客户端可调用的公共方法。3).返回由Service承载的其他类示例,该示例包含客户端可调用的公共方法。(2)使用
onBind()方法返回
Binder
示例。(3)在客户端中,使用onServiceConnected()方法接收
Binder,并使用提供的方法调用绑定。
8.1Service
8.1.8使用Messenger设置方式:(1)Service实现一个
Handler,由其接收来自客户端的每个调用的回调
。(2)Service使用
Handler
来创建
Messenger
(该对象是对
Handler
的引用)。(3)使用Messenger
创建一个
IBinder,Service通过
onBind()
方法将其返回给客户端。(4)使用客户端先使用
IBinder
将
Messenger(引用服务的
Handler)实例化,再使用Messenger将消息发送给Service。(5)Service在
Handler
中(具体而言,是在
handleMessage()
方法中)接收每个消息。
8.1Service
8.1.9绑定到Service操作步骤:(1)要实现
ServiceConnection,必须替换两个回调方法。(2)系统会调用onServiceConnected()方法以传递Service的onBind()方法返回的
IBinder。(3)当与Service的连接意外中断时,如Service崩溃或被终止,Android会调用onServiceDisconnected()方法。当客户端取消绑定时,系统不会调用该方法。(4)调用
bindService()方法,从而传递
ServiceConnection
。(5)当系统调用
onServiceConnected()
方法时,可以使用接口定义的方法开始调用Service。(6)若要断开与Service的连接,则应调用
unbindService()方法。
8.2IntentService
8.2.1ANRAndroid应用界面的进程处于阻塞状态的时间过长,那么会触发ANR。触发条件:(1)输入调度超时:5秒。(2)执行Service:几秒。(3)未调用startForeground()方法:5秒。(4)Intent广播
:5秒或20秒。ANR提示
8.2IntentService
8.2.1ANR在Service内触发ANR定义一个Service,其onStartCommand()实现如下,并在应用界面的进程种启动该ServicepublicintonStartCommand(Intentintent,intflags,intstartId){try{Thread.sleep(20000);}catch(Exceptione){e.printStackTrace();}returnsuper.onStartCommand(intent,flags,startId);}
8.2IntentService
8.2.2IntentService简介IntentService是Service的一个子类。与Service的显著区别是,它并不与界面进程处于同一线程,而是独立开启了一个工作线程
。要使用IntentService必须先继承IntentService并实现onHandleIntent()方法,将耗时的任务放在这个方法中执行。
8.2IntentService
8.2.2IntentService简介选择菜单“File”→“New”→“Service”→“Service(IntentService)”ClassName:Service的类名。SourceLanguage:代码语言。
8.2IntentService
8.2.3使用IntentService请参考课本模拟文件下载进度的例子本章小结Service的使用场景Service的类型Service的使用过程ANR错误IntentService的使用场景IntentService的使用过程BroadcastReceiver前言本章将深入探讨Android应用中的广播,介绍如何通过广播来实现组件之间的通信,以及如何通过EventBus来更加灵活地管理应用内的事件流。此外,还将介绍如何使用AppWidget创建各种实用的桌面应用,以为用户提供更为便捷的功能和展示信息。03创建桌面应用目录01发送与监听广播02管理事件
9.1发送与监听广播
9.1.1BroadcastReceiver简介BroadcastReceiver(广播接收者)是一种常见的Android组件,用于接收和处理系统或应用发出的Broadcast(广播消息)。可以是系统事件(如设备启动或网络状态改变),也可以是应用内部定义的事件。BroadcastReceiver类似于一个监听器,可以在后台接收特定的Broadcast,并执行相应的操作。使用BroadcastReceiver可以实现不同组件之间的通信,无论这些组件是应用内部的不同部分,还是不同的应用。BroadcastReceiver是基于发布/订阅模式的。应用可以注册自己感兴趣的Broadcast,当发出这些Broadcast时,BroadcastReceiver就会被触发并执行。
9.1发送与监听广播
9.1.2创建BroadcastReceiver首先,创建一个继承BroadcastReceiver的类,这将是“南狮广播接收器”。这个接收器用于监听特定的广播动作,并在收到Broadcast时执行相应的操作。publicclassNanShiBroadcastReceiverextendsBroadcastReceiver{@OverridepublicvoidonReceive(Contextcontext,Intentintent){//获取动作Stringaction=intent.getAction();
//检查广播动作是否匹配if(action!=null&&action.equals("com.example.nanshi.ACTION")){performNanShiShow(context);}}
privatevoidperformNanShiShow(Contextcontext){//在这里执行南狮表演的操作,如播放音乐、展示动画等//简单地显示一个ToastToast.makeText(context,"南狮正在表演!",Toast.LENGTH_SHORT).show();}}
9.1发送与监听广播
9.1.2创建BroadcastReceiver其次,在AndroidManifest.xml文件中注册BroadcastReceiver,以便系统能够识别并调用它。使用<receiver>元素实现注册,并使用<intent-filter>元素指定自己感兴趣的广播动作。<receiverandroid:name=".NanShiBroadcastReceiver"android:enabled="true"android:exported="true"/>
9.1发送与监听广播
9.1.2创建BroadcastReceiver在使用AndroidStudio进行Android应用开发时,BroadcastReceiver不需要手动创建,可以通过开发平台一键生成。把鼠标指针移动到包名处并右击,在弹出的快捷菜单中选择“New”→“Other”→“BroadcastReceiver”命令,弹出如图9-1所示的“NewAndroidComponent”对话框。
9.1发送与监听广播
9.1.3注册BroadcastReceiver动态注册BroadcastReceiver是在程序代码中动态实现的。这种方式适用于应用局部范围的BroadcastReceiver,只有在特定的上下文中才会接收到Broadcast。publicclassMainActivityextendsAppCompatActivity{
NanShiBroadcastReceiverreceiver;
@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
receiver=newNanShiBroadcastReceiver();IntentFilterintentFilter=newIntentFilter();intentFilter.addAction("com.example.nanshi.ACTION");registerReceiver(receiver,intentFilter);}
@OverrideprotectedvoidonDestroy(){super.onDestroy();
//在Activity销毁时取消注册BroadcastReceiverunregisterReceiver(receiver);}}
9.1发送与监听广播
9.1.4发送BroadcastBroadcastReceiver用于接收Broadcast,而发送Broadcast则指向系统或其他应用发送Broadcast。通过发送Broadcast可以触发特定事件或通知其他组件进行相应的操作。在发送Broadcast时需要遵循以下步骤。首先创建一个Intent,用于描述广播动作和数据。其次,调用sendBroadcast()方法发送Broadcast。//创建IntentIntentbroadcastIntent=newIntent();broadcastIntent.setAction("com.example.nanshi.ACTION");//发送BroadcastsendBroadcast(broadcastIntent);
9.1发送与监听广播
9.1.4发送BroadcastBroadcastReceiver用于接收Broadcast,而发送Broadcast则指向系统或其他应用发送Broadcast。通过发送Broadcast可以触发特定事件或通知其他组件进行相应的操作。在发送Broadcast时需要遵循以下步骤。首先创建一个Intent,用于描述广播动作和数据。其次,调用sendBroadcast()方法发送Broadcast。//创建IntentIntentbroadcastIntent=newIntent();broadcastIntent.setAction("com.example.nanshi.ACTION");//发送BroadcastsendBroadcast(broadcastIntent);
9.2
管理事件
9.2.1EventBus架构概念定义作用备注发布者(Object)事件发布对象(EventBus.post(事件))创建事件的对象
订阅者(Object)事件订阅方法的接收者(Method.invokde(订阅者,事件))处理事件的对象
发布线程(Thread)创建并发布事件的线程用于发布事件(执行EventBus.post()方法)UI线程和工作现场均可以作为发布线程或订阅线程订阅线程(Thread)接收并操作事件的线程用于承载执行订阅方法POSTING:发布线程|MAIN:主线程|MAIN_ORDERED:主线程(有序)|BACKGROUND:后台线程|ASYNC:异步线程订阅方法(Subscribe)使用@Subscribe注解修饰的方法用于订阅者接收事件后的处理逻辑
使用@Subscribe注解可以设置线程、粘性、优先级事件(Class<?>)组件/线程之间通信的数据单元存储需要操作的通信信息任何类型的对象都可以被当作事件发送出去事件哈希表(HashMap)一种数据结构(存储特点:快速插入和搜索)Key
:事件类型(Class<?>)|Value:订阅者列表(CopyOnWriterArrayList)在注册订阅者时,订阅关系会被存储到事件哈希表中
9.2
管理事件
9.2.1EventBus架构EventBus架构是基于发布/订阅模式的,订阅者通过注册到EventBus上来订阅特定类型的事件。在发布事件时,EventBus会根据事件类型找到对应的订阅者,并将事件传递给它们,从而实现组件之间解耦及通信。
9.2
管理事件
9.2.2使用EventBus首先,在项目的build.gradle文件中添加EventBus的依赖项;其次,创建一个Java类来表示事件。该类可以包含任意数据和方法,作为消息的载体。implementation'org.greenrobot:eventbus:3.2.0'publicclassMessageEvent{privatefinalStringmessage;
publicMessageEvent(Stringmessage){this.message=message;}
publicStringgetMessage(){returnmessage;}}
9.2
管理事件
9.2.2使用EventBus最后,在希望接收事件的组件中注册订阅者。通常情况下在Activity或Fragment的生命周期方法中进行注册和注销。@OverridepublicvoidonStart(){super.onStart();//注册定订阅者以接收事件
EventBus.getDefault().register(this);}@OverridepublicvoidonStop(){super.onStop();EventBus.getDefault().unregister(this);}
9.3创建桌面应用
9.3.1AppWidget简介AppWidget是Android平台上的小型应用,用于在用户的主界面中显示有限的信息,为用户提供快捷访问应用功能的便捷方式。AppWidgets允许用户在桌面上直接查看应用的部分内容,无须打开完整的应用,可以提供快速、高效的操作体验。AppWidget通常用于展示静态或动态的内容,如天气、最新新闻、音乐播放器控制等。用户可以根据个人喜好,自由添加和删除AppWidget,并根据需要调整AppWidgets的位置和大小。
9.3创建桌面应用
9.3.1AppWidget简介在AndroidStudio中可以快速创建AppWidget。把鼠标指针移动到包名处并右击,在弹出的快捷菜单中选择“New”→“Widget”→“AppWidget”命令,弹出如图所示的“NewAndroidComponent”对话框。
9.3创建桌面应用
9.3.2AppWidget布局设计快速创建AppWidget后,即可在layout目录中看到一个new_app_widget.xml文件,默认生成RelativeLayout,且里面只有一个TextView。这里把布局管理器修改为LinearLayout,且里面有TextView和ImageView。<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">
<TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:textSize="30sp"/>
<ImageViewandroid:id="@+id/imageView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"/>
</LinearLayout>
9.3创建桌面应用
9.3.3实现AppWidgetProviderInfoAppWidgetProviderInfo用于描述已安装的AppWidget提供程序的元数据。该类中的字段对应于<appwidget-provider>元素中的属性,即对应本示例中的lingnan_app_widget_info.xml文件。打开该文件可以发现,只有键值对形式的数据。<?xmlversion="1.0"encoding="utf-8"?><appwidget-providerxmlns:android="/apk/res/android"android:configure=".baiyunu.chapter_9.NewAppWidgetConfigureActivity"android:description="@string/app_widget_description"android:initialKeyguardLayout="@layout/new_app_widget"android:initialLayout="@layout/new_app_widget"android:minWidth="40dp"android:minHeight="40dp"android:previewImage="@drawable/example_appwidget_preview"android:previewLayout="@layout/new_app_widget"android:resizeMode="horizontal|vertical"android:targetCellWidth="1"android:targetCellHeight="1"android:updatePeriodMillis="86400000"android:widgetCategory="home_screen"/>
9.3创建桌面应用
9.3.4拓展AppWidgetProviderNewAppWidget继承了AppWidgetProvider,并重写了onUpdate()方法、onDeleted()方法、onEnabled()方法和onDisabled()方法。在onUpdate()方法中,AndroidStudio默认遍历appWidgetIds(每个AppWidget都有独一无二的ID)。staticvoidupdateAppWidget(Contextcontext,AppWidgetManagerappWidgetManager,intappWidgetId){CharSequencewidgetText=NewAppWidgetConfigureActivity.loadTitlePref(context,appWidgetId);//ConstructtheRemoteViewsobjectRemoteViewsviews=newRemoteViews(context.getPackageName(),R.layout.new_app_widget);views.setTextViewText(R.id.appwidget_text,widgetText);//InstructthewidgetmanagertoupdatethewidgetappWidgetManager.updateAppWidget(appWidgetId,views);}
9.3创建桌面应用
9.3.5声明AppWidget因为AppWidget本质上也是BroadcastReceiver,所以在AndroidManifest.xml文件中可以看到已经配置了<receiver>元素,将其与AppWidget相关联。这样,用户在添加或删除AppWidget时,系统将自动创建或销毁AppWidgetProvider示例。<receiverandroid:name=".NewAppWidget"android:exported="false"><intent-filter><actionandroid:name="android.appwidget.action.APPWIDGET_UPDATE"/></intent-filter><meta-dataandroid:name="vider"android:resource="@xml/new_app_widget_info"/></receiver>
9.3创建桌面应用
9.3.6实现ConfigurationActivity由于在快速创建AppWidget时勾选了“ConfigurationScreen”复选框,因此最终生成的文件多了NewAppWidgetConfigureActivity.java和new_app_widget_configure.xml两个。当用户添加一个AppWidget到主界面上时,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年晋宁县妇幼保健院医护人员招聘笔试备考试题及答案详解
- 2026贵州铜仁市玉屏侗族自治县面向县外选调(备选)在职在编教师29人考试模拟试题及答案详解
- 2026广东中山黄圃镇特教班合同制教职工招聘3人笔试备考试题及答案详解
- 2026四川宜宾市叙州区第五人民医院招聘4人笔试模拟试题及答案详解
- 常州市新桥高级中学招聘若干名编外聘用教师笔试备考题库及答案详解
- 2026湖北武汉市青山区红钢城街道招聘劳动监察协理员1人考试备考试题及答案详解
- 2026年广西(百色市)高校毕业生“三支一扶”计划招募164人考试参考题库及答案详解
- 2026年嘉兴市桐乡市教育系统公开招聘教师34人(第三批)考试参考题库及答案详解
- 2026宿迁市市级机关遴选和选调公务员35人考试参考题库及答案详解
- 2026福建师范大学招聘管理助理、教学助理岗位工作人员21人笔试备考题库及答案详解
- 2025年二级风力发电运维值班员职业技能鉴定考试题库(浓缩500题)
- 血液透析不同抗凝剂的应用及护理
- 《铁路信号与通信设备》课件
- 高速铁路信号系统信号机安装方法
- 年综合固废收集预处理20万吨新建项目环评资料环境影响
- 民居建筑-福建土楼课件
- DB43T 876.2-2014 高标准农田建设 第2部分:土地平整
- 2024年咨询服务协议书范文
- 制衣厂劳动合同模板
- DB50-T1486-2023城市运行管理服务平台技术规范(标准文本)
- 中医内科临床诊疗指南-肺动脉高压
评论
0/150
提交评论