这是我参与「第四届青训营 」笔记创作活动的第7天。 本文将对一些不常用知识点进行梳理,包括除了Activity的剩余三大组件、内部存储、外部存储。
Activity
Service
Service使用详解 Service 使用详解 - 掘金 (juejin.cn)
要点梳理:
Service服务:主要用于组件建交互
注意:
- Service在主线程运行时长不超过20s(ANR)
- 一定注册;但若没有注册也不会报异常信息
Activity运行在前台,用户看得见;Service运行在后台,无用户界面,用户看不见
启动模式:
- 启动模式startService();一直后台运作
- 绑定模式bindService();随绑定组件的消亡而解除绑定 ps:多个组件可以同时绑定一个Service,还可以通过进程间通信(IPC )执行跨进程操作等。
服务优先级
- 服务默认启动方式是后台程序。
- 前台程序:避免因程序优先级过低,当手机内存紧张时,服务进程被杀死
- 设置前台服务startForeground(int, Notification);
- 取消前台服务stopForeground(true);
- 使用AIDL接口实现远程绑定(缺)
广播Broadcast
Broadcast 使用详解 - 掘金 (juejin.cn) 广泛运用在app之间的异步传输信息的机制,本质上是Intent对象,Broadcast可以被多个BroadcastReiver处理
- BroadcastReceiver是一个全局监听器,通过它的onReceive()过滤用户想要的广播,进而进行其他操作。
- 默认在主线程执行,onReceive()处理事件超过10s,在ANR(Application Not Responding)。监理工作线程不能解决该问题,故建议:处理耗时操作,用Service代替
注册
- 静态注册
- 开机广播:特殊需要在注册表中添加权限
- 动态注册
- 注意使用context.getApplicationContext(),防止context为空,引起空指针异常
- context.registerReceiver(mScreenOnOffReceiver, screenOffFilter);动态注册广播方法
发送
ps:发送自定义广播:自定义广播也是在Androidmanfest.xml中静态注册的
1.发送无序广播:一对多,主要通过sendBroadcast(intent);发送广播
2. 发送有序广播
- 优先级高的广播可以终止或修改广播内容。通过修改注册表中
<intent-filter android:priority="500"> 中值对广播优先级进行排序。值越大,优先级越高。
- 有序广播需要声明并使用权限
3. 发送持续广播已弃用
接受
- 系统广播
- 自定义广播
ContentProvider
本质是一个标准化的数据管道,它屏蔽了底层的数据管理和服务等细节,以标准化的方式在app内共享数据。用户可以灵活实现ContentProvider所封装的数据存储以及增删改查等,所有的ContentProvider必须事项对外统一的接口(URI)。
URI
android:authorities="ProgramAndroid"
static {
// content://programandroid/person
matcher.addURI(MAUTHORITIESNAME, "person", PERSON);
// # 代表任意数字content://programandroid/person/4
matcher.addURI(MAUTHORITIESNAME, "person/#", PERSON_NUMBER);
// * 代表任意文本 content://programandroid/person/filter/ssstring
matcher.addURI(MAUTHORITIESNAME, "person/filter/*", PERSON_TEXT);
}
- 增
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
// 过滤URI
int match = matcher.match(uri);
switch (match) {
case PERSON:
// content://autoname/person
long id = db.insert(TABLE_NAME, null, values);
// 将原有的uri跟id进行拼接从而获取新的uri
return ContentUris.withAppendedId(uri, id);
case PERSON_NUMBER:
break;
case PERSON_TEXT:
break;
default:
break;
}
return null;
}
- 删改
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
return 0;
}
- 查
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// 过滤URI
int match = matcher.match(uri);
switch (match) {
case PERSON:
// content://autoname/person
return db.query(TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
case PERSON_NUMBER:
break;
case PERSON_TEXT:
break;
default:
break;
}
return null;
}
- 对外数据库修改
- 其他APK访问ContentProvider数据库 ps:
// 此条添加上才ContentObserver可以监听数据库改变
getContentResolver().notifyChange(Uri.parse(uri),null);
获取联系人信息方法
Android系统自带一下ContentProvider - 从系统数据库中获取联系人数据,权限,读取联系人 1. 获取内容解析器(访问地址(后门)) 2. 对数据库指定表进行查询操作 3. 判断游标中是否有数据 4. 通过id去关联data表和minetype表生成视图,data1(数据),mimetype(数据类型) 5. 游标向下移动获取数据 6. 稿纸主线程集合中数据以及准备完毕,让主线程去使用此集合,填充数据适配器
获取短信内容的方法
短信内容数据也是Android系统提供的
ContentResolver内容解析者
ContentResolver主要是通过URI调用getContentResolver()获取ContentProvider提供的数据接口,进而增删改查
ContentObserver内容观察者
ContentObserver内容观察者通过指定URI监听ContentProvider数据是否改变。
- 注册
- 继承ContentObserver,实现onChange方法
- 调用ContentObserver监听短信数据改变
ContentProvider ContentResolver ContentObserver三者关系
内部存储
- Android可以直接保存文件到内部存储中,该文件是应用的私有文件,其他应用无法访问。
- 当应用被卸载时,文件也会被删除。
- 内部存储以文件形式保存。
基本
- 保存路径
/data/data/com.**包名/files/文件名
- 使用方法
- 保存
- 使用文件名称和操作模式调用openFileOutput(),得到返回的FileOutputStream类型的fos。(打开输入流,并创建文件)
- 使用write()写入到文件
- close()关闭流式传输
- 读取
- 使用文件名称调用openFileInput(),得到返回的FileInputStream类型的fis。(打开文件得到一个只读的输入流)
- 使用read()读取文件字节
- 使用close()关闭流式传输
- 删除
- 使用文件名称调用deleteFile()。
- 保存
- 其他
- 获取在其中存储尼日不文件的文件系统目录的绝对路径。
getFilesDir()- 在内部创建或打开现有目录
getDir()- 返回您的应用当前保存的一系列文件
fileList()
外部存储
外部存储 使用详解 - 掘金 (juejin.cn)
Android设备支持外部存储,比如SD卡,保存在外部存储数据具有全局可读性。使用外部存储需要获取外部存储的访问权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />。
- 申请保存外部存储权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- 使用方法 判断是否挂载SD卡方法
/**
* 1.判断SD卡是否挂载
* **/
public static boolean isMounted() {
String state = Environment.getExternalStorageState();
return state.equals(Environment.MEDIA_MOUNTED);
}
- 保存
- 读取
- 删除