深入分析 Android ContentProvider (十)

news2024/11/14 15:01:22

文章目录

    • 深入分析 Android ContentProvider (十)
    • ContentProvider 的高级使用及最佳实践(续)
      • 1. ContentProvider 与异步加载
        • 使用 CursorLoader 进行异步数据加载
      • 2. 动态权限请求
        • 动态请求权限示例
      • 3. ContentProvider 的缓存优化
        • 使用 LruCache 实现内存缓存
      • 4. ContentProvider 的安全性
        • 1. 权限控制
        • 2. 数据加密
        • 示例:使用 AES 加密数据
      • 5. ContentProvider 的多进程支持
        • 示例:多进程 ContentProvider
      • 6. 总结

深入分析 Android ContentProvider (十)

ContentProvider 的高级使用及最佳实践(续)

1. ContentProvider 与异步加载

在 Android 应用开发中,响应 UI 的数据加载应该尽量在异步线程中进行,以避免阻塞主线程,提升用户体验。Loaders 和 ContentProvider 可以结合使用,实现高效的数据加载。

使用 CursorLoader 进行异步数据加载

CursorLoader 是一个专门用于 ContentProvider 的 Loader 类,能够在后台线程中执行查询操作,并在数据改变时自动刷新。

public class MyActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
    private static final int LOADER_ID = 1;
    private MyAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        adapter = new MyAdapter(this, null);
        ListView listView = findViewById(R.id.listView);
        listView.setAdapter(adapter);

        getLoaderManager().initLoader(LOADER_ID, null, this);
    }

    @NonNull
    @Override
    public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
        return new CursorLoader(this, MyContentProvider.CONTENT_URI, null, null, null, null);
    }

    @Override
    public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
        adapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(@NonNull Loader<Cursor> loader) {
        adapter.swapCursor(null);
    }
}

在这个示例中,CursorLoader 负责在后台线程中执行查询操作,当数据加载完成后会自动更新 UI。

2. 动态权限请求

从 Android 6.0 (API level 23) 开始,应用在运行时需要动态请求权限。对于 ContentProvider,通常涉及到对存储或联系人等敏感数据的访问权限。

动态请求权限示例
public class MyActivity extends AppCompatActivity {
    private static final int PERMISSIONS_REQUEST_READ_CONTACTS = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
        } else {
            loadContacts();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                loadContacts();
            } else {
                Toast.makeText(this, "Permission denied to read contacts", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private void loadContacts() {
        // 执行联系人加载操作
    }
}

动态请求权限可以确保在用户明确授权后才进行敏感数据操作,提升应用的安全性。

3. ContentProvider 的缓存优化

为了提升 ContentProvider 的性能,可以使用内存缓存或磁盘缓存来减少数据库访问次数。可以使用 LruCache 或 DiskLruCache 来实现。

使用 LruCache 实现内存缓存
public class MyContentProvider extends ContentProvider {
    private static LruCache<String, Bitmap> memoryCache;

    @Override
    public boolean onCreate() {
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        final int cacheSize = maxMemory / 8;
        memoryCache = new LruCache<>(cacheSize);
        return true;
    }

    public static void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null) {
            memoryCache.put(key, bitmap);
        }
    }

    public static Bitmap getBitmapFromMemCache(String key) {
        return memoryCache.get(key);
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
                        @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        // 查询逻辑,并从缓存中读取数据
        return null;
    }
}

通过 LruCache,我们可以在内存中缓存常用的数据,减少频繁的数据库查询,提高访问速度。

4. ContentProvider 的安全性

在设计 ContentProvider 时,安全性是一个关键问题。为了确保数据的安全,可以使用以下几种方法:

1. 权限控制

通过定义权限,限制哪些应用可以访问 ContentProvider。

<provider
    android:name=".MyContentProvider"
    android:authorities="com.example.provider"
    android:exported="true"
    android:permission="com.example.provider.READ_WRITE">
</provider>
2. 数据加密

对于敏感数据,可以在存储前进行加密,读取时进行解密,确保数据在存储介质中的安全。

示例:使用 AES 加密数据
public class EncryptionHelper {
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES";

    public static byte[] encrypt(String key, byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), ALGORITHM));
        return cipher.doFinal(data);
    }

    public static byte[] decrypt(String key, byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(), ALGORITHM));
        return cipher.doFinal(data);
    }
}

通过加密敏感数据,可以有效防止数据泄露和未授权访问。

5. ContentProvider 的多进程支持

在多进程应用中,ContentProvider 可以实现跨进程数据共享。通过设置 android:process 属性,可以指定 ContentProvider 运行在不同的进程中。

示例:多进程 ContentProvider
<provider
    android:name=".MyContentProvider"
    android:authorities="com.example.provider"
    android:process=":remote"
    android:exported="true">
</provider>

通过指定 android:process 属性,可以让 ContentProvider 运行在一个独立的进程中,提高应用的稳定性和安全性。

6. 总结

ContentProvider 是 Android 中实现数据共享和管理的重要组件,通过深入理解和灵活运用,可以实现高效、安全的数据操作。通过结合 Loaders 实现异步数据加载,使用缓存提升性能,动态请求权限确保安全,设计合理的 URI 结构和权限管理,可以大幅提升 ContentProvider 的使用效果。在实际开发中,结合具体需求和场景,灵活应用这些高级技巧和最佳实践,是开发高性能、稳定 Android 应用的关键。通过具体的代码示例和实践案例,我们展示了 ContentProvider 的广泛应用和最佳实践,为开发者提供了丰富的参考。

欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力

在这里插入图片描述

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

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

相关文章

优化 GitHub 体验的浏览器插件「GitHub 热点速览」

上周&#xff0c;GitHub 有个“安全问题”——CFOR&#xff08;Cross Fork Object Reference&#xff09;冲上了热搜&#xff0c;该问题的表现是&#xff1a; 远程仓库的提交内容任何人可以访问&#xff0c;即使已被删除。只需要拿到 commit ID源/Fork 的项目地址&#xff0c;任…

猫头虎分享AI写真系统架构分析

摘要 AI写真系统 是目前最受欢迎的技术之一&#xff0c;本文将详细介绍该系统的架构和实现&#xff0c;包括 前端框架Uni-app、后端框架Saas、AI Agent后端框架dify和langchain&#xff0c;以及通义千问 GPT-4 MJ DALL-E 3的应用。无论是技术小白还是大佬&#xff0c;都能从…

docker安装人大金仓最新数据库

1.下载docker版本人大金仓数据库 1.1 点击人大金仓网址&#xff0c;下载镜像包 1.2 上传镜像包并导入镜像 在这里插入代码片 #上传后导入镜像2.启动人大金仓数据库容器 docker run -tid \ --privileged \ --name kingbase \ -v /opt/kingbase/data:/home/kingbase/userdata…

2024思维导图软件大赏:哪些工具让知识管理更轻松

如果你是上班族&#xff0c;有时候会议需要头脑风暴&#xff0c;收到的信息总是杂乱无章令人头疼。这时候使用幕布思维导图这样的工具就如同智慧的灯塔&#xff0c;他会帮我们指引准确的方向。 1.福昕思维导图 链接直达&#xff1a;https://www.pdf365.cn/naotu/ 这个思维导…

LLC数字控制TMS320F28034,2-根据原理图配置GPIO控制引脚

LLC数字控制TMS320F28034&#xff0c;2-根据原理图配置GPIO控制引脚 LLC数字控制TMS320F28034&#xff0c;2-根据原理图配置GPIO控制引脚1 TMS320F280341.1 GPIO概述1.2 GPIO寄存器说明1.3 GPIO寄存器使用注意事项 2 项目原理图介绍2.1 GPIO使用介绍2.2 功能引脚使用说明 3 软件…

5、注册字符类设备

字符设备 cdev结构体 Linux中使用cdev结构体描述一个字符设备。结构体定义在include/linux/cdev.h 文件中&#xff0c; struct cdev{struct kobject kobj;struct module *owner; //所属模块const struct file_operations *ops; //文件操作结构体struct list_head lis…

Spring Cloud 集成 Nacos、openfeign 错误解决

前言&#xff1a; 在集成 Nacos 和 openfeign 的时候&#xff0c;过程出现了一点小曲折&#xff0c;这里简单分享一下&#xff0c;希望可以帮助到有需要的朋友。 Spring boot 版本如下&#xff1a; <version>2.4.5</version>Spring Alibaba 版本如下&#xff1a…

【狂神】多线程(含内部类、Lambda)

整体参考 一、线程 1、多任务&#xff1a; 现实中太多这样同时做多件事情的例子了&#xff0c;看起来是多个任务都在做&#xff0c;其实本质上我们的大脑在同一时间依旧只做了一件事情。 2、多线程&#xff1a; 原来是一条路&#xff0c;慢慢因为车太多了&#xff0c;道路…

程序员面试 “八股文”在实际工作中是助力、阻力还是空谈?

“八股文”在实际工作中是助力、阻力还是空谈&#xff1f; 作为现在各类大中小企业面试程序员时的必问内容&#xff0c;“八股文”似乎是很重要的存在。但“八股文”是否能在实际工作中发挥它“敲门砖”应有的作用呢&#xff1f;有IT人士不禁发出疑问&#xff1a;程序员面试考…

[FBCTF2019]RCEService (PCRE回溯绕过和%a0换行绕过)

json格式输入ls出现index.php 这道题原本是给了源码的&#xff0c;BUUCTF没给 源码&#xff1a; <?phpputenv(PATH/home/rceservice/jail);if (isset($_REQUEST[cmd])) {$json $_REQUEST[cmd];if (!is_string($json)) {echo Hacking attempt detected<br/><br/…

WebLogic: CVE-2020-14882/14883【getshell】

记录第一次getshell公网设备 漏洞介绍 CVE-2020-14882&#xff1a;允许 未授权 的用户绕过管理控制台 &#xff08;Console&#xff09;的权限验证访问后台 CVE-2020-14883&#xff1a;允许后台任意用户通过HTTP协议 执行任意命令 使用这两个漏洞组成的利用链&#xff0c;可通过…

ECCV`24 | 比DragDiffusion快100倍!RegionDrag:快·准·好的图像编辑方法!港大牛津

文章链接&#xff1a;https://arxiv.org/pdf/2407.18247 github链接&#xff1a;https://github.com/LuJingyi-John/RegionDrag 亮点直击 引入了一种基于区域的图像编辑方法&#xff0c;以克服基于点拖拽方法的局限性&#xff0c;利用更丰富的输入上下文来更好地对齐编辑结果与…

排序算法:归并排序,golang实现

目录 前言 归并排序 代码示例 1. 算法包 2. 归并排序代码 3. 模拟程序 4. 运行程序 5. 从大到小排序 归并排序主要操作 1. 合并 2. 分割&#xff08;Divide&#xff09;与递归排序&#xff08;Conquer&#xff09; 总体思想 循环次数测试 假如 10 条数据进行排序…

虾皮笔试0620-编程题

难度偏易&#xff0c;给出解题思路。 按照空格分割字符串&#xff0c;每个字符串用双指针反转小写字母。 记录原来位置到二维数组&#xff0c;排序&#xff0c;从小到达购买&#xff0c;再把英雄对应之前的位置排序输出。 先变成循环链表&#xff0c;找到旋转后的头节点&#x…

day2 PS教程——搞定图层的使用方法,效率大翻倍

day2 PS教程——搞定图层的使用方法&#xff0c;效率大翻倍 目录 1.图层 智能对象 2.蒙版 与智能对象绑定 使用橡皮——镂空 剪切模板 上放图片&#xff0c;下放图形&#xff0c;按ALT同时&#xff0c;点击两图层间的即可 底下可以放黑色背景 选中多个图层后&#xff0…

海尔智家三翼鸟:从家电到场景,能否跨越智能化陷阱?

在智能家居浪潮的席卷之下&#xff0c;三翼鸟作为海尔智家旗下的场景品牌&#xff0c;曾一度被视为传统家电厂商转型升级的典范。然而&#xff0c;在光鲜亮丽的宣传背后&#xff0c;三翼鸟正逐步暴露出难以忽视的困境与挑战&#xff0c;其智能化之路似乎并不如预期般顺畅。 从用…

内存一直增加—-代码里有matplotlib绘图的代码

问题描述 最近在调试代码的时候发现内存一直在呈线性增加,持续一段时间后程序就会停止,但是排查了好久也没有发现问题. 最后发现竟然是绘图代码的问题,没有plt.close(),导致生成的绘图一直保存在内存里不断增加. 解决方案 增加一行代码plt.close(),把绘图关闭 点击访问博…

AcWing 1191. 家谱树(图论,拓扑排序的模板)

有个人的家族很大&#xff0c;辈分关系很混乱&#xff0c;请你帮整理一下这种关系。 给出每个人的孩子的信息。 输出一个序列&#xff0c;使得每个人的孩子都比那个人后列出。 输入格式 第 1 行一个整数 n&#xff0c;表示家族的人数&#xff1b; 接下来 n 行&#xff0c;…

app逆向实战:某新闻7.38.0版本加固脱壳和参数分析

本篇博客旨在记录学习过程&#xff0c;不可用于商用等其它途径 入口 这次研究的是头条数据接口&#xff0c;每次向下滑动即可刷新请求 抓包 根据抓包结果得知动态参数是st和sn&#xff0c;大胆猜测sn的生成跟st有关&#xff0c;其它参数是固定的&#xff0c;后面看生成具体…

windows如何让右键点击时不折叠选项(展开显示更多选项)?

升级windows后&#xff0c;发现右键菜单自动折叠了&#xff0c;用起来很不方便&#xff0c;有没有办法&#xff0c;让右键菜单自动展开那 &#xff1f; 期望的效果是这样的&#xff1a; 具体操作请参考我这篇公众号文章。 windows如何让右键点击时不折叠选项&#xff08;展开…