基础Android(一) | 青训营笔记

162 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的第7天。 本文将对一些不常用知识点进行梳理,包括除了Activity的剩余三大组件、内部存储、外部存储。

Activity

Service

Service使用详解 Service 使用详解 - 掘金 (juejin.cn)

要点梳理:

Service服务:主要用于组件建交互

注意:

  1. Service在主线程运行时长不超过20s(ANR)
  2. 一定注册;但若没有注册也不会报异常信息

Activity运行在前台,用户看得见;Service运行在后台,无用户界面,用户看不见

启动模式:

  1. 启动模式startService();一直后台运作
  2. 绑定模式bindService();随绑定组件的消亡而解除绑定 ps:多个组件可以同时绑定一个Service,还可以通过进程间通信(IPC )执行跨进程操作等。

服务优先级

  1. 服务默认启动方式是后台程序。
  2. 前台程序:避免因程序优先级过低,当手机内存紧张时,服务进程被杀死
    • 设置前台服务startForeground(int, Notification);
    • 取消前台服务stopForeground(true);
  3. 使用AIDL接口实现远程绑定(

广播Broadcast

Broadcast 使用详解 - 掘金 (juejin.cn) 广泛运用在app之间的异步传输信息的机制,本质上是Intent对象,Broadcast可以被多个BroadcastReiver处理

  1. BroadcastReceiver是一个全局监听器,通过它的onReceive()过滤用户想要的广播,进而进行其他操作。
  2. 默认在主线程执行,onReceive()处理事件超过10s,在ANR(Application Not Responding)。监理工作线程不能解决该问题,故建议:处理耗时操作,用Service代替

注册

  1. 静态注册
    • 开机广播:特殊需要在注册表中添加权限
  2. 动态注册
    • 注意使用context.getApplicationContext(),防止context为空,引起空指针异常
    • context.registerReceiver(mScreenOnOffReceiver, screenOffFilter);动态注册广播方法

发送

ps:发送自定义广播:自定义广播也是在Androidmanfest.xml中静态注册的 1.发送无序广播:一对多,主要通过sendBroadcast(intent);发送广播 2. 发送有序广播 - 优先级高的广播可以终止或修改广播内容。通过修改注册表中 <intent-filter android:priority="500"> 中值对广播优先级进行排序。值越大,优先级越高。 - 有序广播需要声明并使用权限 3. 发送持续广播已弃用

接受

  1. 系统广播
  2. 自定义广播

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;
	}
  1. 删改
@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;
	}
  1. 对外数据库修改
  2. 其他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数据是否改变。

  1. 注册
  2. 继承ContentObserver,实现onChange方法
  3. 调用ContentObserver监听短信数据改变

ContentProvider ContentResolver ContentObserver三者关系

内部存储

内部存储 使用详解 - 掘金 (juejin.cn)

  1. Android可以直接保存文件到内部存储中,该文件是应用的私有文件,其他应用无法访问。
  2. 当应用被卸载时,文件也会被删除。
  3. 内部存储以文件形式保存。

基本

  1. 保存路径
/data/data/com.**包名/files/文件名
  1. 使用方法
    • 保存
      1. 使用文件名称和操作模式调用openFileOutput(),得到返回的FileOutputStream类型的fos。(打开输入流,并创建文件)
      2. 使用write()写入到文件
      3. close()关闭流式传输
    • 读取
      1. 使用文件名称调用openFileInput(),得到返回的FileInputStream类型的fis。(打开文件得到一个只读的输入流)
      2. 使用read()读取文件字节
      3. 使用close()关闭流式传输
    • 删除
      1. 使用文件名称调用deleteFile()。
  2. 其他
    1. 获取在其中存储尼日不文件的文件系统目录的绝对路径。
    getFilesDir()
    
    1. 在内部创建或打开现有目录
    getDir()
    
    1. 返回您的应用当前保存的一系列文件
    fileList()
    

外部存储

外部存储 使用详解 - 掘金 (juejin.cn) Android设备支持外部存储,比如SD卡,保存在外部存储数据具有全局可读性。使用外部存储需要获取外部存储的访问权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

  1. 申请保存外部存储权限
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  1. 使用方法 判断是否挂载SD卡方法
	/**
	 * 1.判断SD卡是否挂载
	 * **/
	public static boolean isMounted() {

		String state = Environment.getExternalStorageState();
		return state.equals(Environment.MEDIA_MOUNTED);

	}
  • 保存
  • 读取
  • 删除