读书笔记App研发录--数据缓存设计

APP开发实战103-缓存简介 27 Android 缓存处理 27.1缓存简介 APP通常需要从服务器获取数据,服务器端的数据并不都是实时变化的,如商品的图片等;可以把服务器端数据复制到设备的内存或本地,APP从内存或本地获取数据,不用每次都从服务器获取,从而节约用户的上网流量和加快APP响应速度,这就是缓存设计。 内存和本地文件缓存空间并非是无限大的,容量越大读取效率越低,需要设置一个折中缓存容量比如10M,如果缓存已 阅读详情

读书笔记App研发录–数据缓存设计

标签(空格分隔): 数据缓存 android 优化


数据缓存策略

在2G和3G网络状态下,MobileApi访问速度过慢,会导致不好的用户体验。网络端的数据接受的限制主要是传输速度的限制。
策略

  • 减少MobileApi的调用次数
  • App缓存时间。分时间段调用,一段时间使用缓存数据

App缓存只使用于数据即时性要求不高的数据。当然也可以根据具体的需求调节App缓存时间

即使对于同一个MobileApi,传入的参数不同,缓存也应该是不同的

最简单的时间参数,在不同的时间获取的天气情况,date=A和date=B 应该分别对应两个缓存数据。不能存放在一起。

缓存位置

  • SD卡

App数据缓存较大,在内存中极易被GC回收。

存放方式

数据缓存应该在网络层完成
a) url.xml中为每一个MobileApi接口配置缓存时间Expired,对于Post,一律设置为0

public class URLData {
    private String key;
    private long expires; // 配置时间
    private String netType;
    private String url;
    private String mockClass;
}

b) 写一个排序算法sortKets,对URL中的key进行排序

void sortKeys() {
        for (int i = 1; i < parameter.size(); i++) {
            for (int j = i; j > 0; j--) {
                RequestParameter p1 = parameter.get(j - 1);
                RequestParameter p2 = parameter.get(j);
                if (compare(p1.getName(), p2.getName())) {
                    // 交互p1和p2这两个对象,写的超级恶心
                    String name = p1.getName();
                    String value = p1.getValue();

                    p1.setName(p2.getName());
                    p1.setValue(p2.getValue());

                    p2.setName(name);
                    p2.setValue(value);
                }
            }
        }
    }
    // 返回true说明str1大,返回false说明str2大
    boolean compare(String str1, String str2) {
        String uppStr1 = str1.toUpperCase();
        String uppStr2 = str2.toUpperCase();

        boolean str1IsLonger = true;
        int minLen = 0;

        if (str1.length() < str2.length()) {
            minLen = str1.length();
            str1IsLonger = false;
        } else {
            minLen = str2.length();
            str1IsLonger = true;
        }

        for (int index = 0; index < minLen; index++) {
            char ch1 = uppStr1.charAt(index);
            char ch2 = uppStr2.charAt(index);
            if (ch1 != ch2) {
                if (ch1 > ch2) {
                    return true; // str1大
                } else {
                    return false; // str2大
                }
            }
        }

        return str1IsLonger;
    }

c ) 将newUrl作为新key,检查是否存在缓存数据,有,返回

if (urlData.getExpires() > 0) {
                    final String content = CacheManager.getInstance()
                            .getFileCache(newUrl);
                    if (content != null) {
                        handler.post(new Runnable() {

                            @Override
                            public void run() {
                                requestCallback.onSuccess(content);
                            }

                        });

                        return;
                    }
                }

d )否则继续调用MobileApi从网络端获取数据,并存入缓存

{
                        // 把成功获取到的数据记录到缓存
                        if (urlData.getNetType().equals(REQUEST_GET)
                                && urlData.getExpires() > 0) {
                            CacheManager.getInstance().putFileCache(newUrl,
                                    responseInJson.getResult(),
                                    urlData.getExpires());
                        }

                        handler.post(new Runnable() {

                            @Override
                            public void run() {
                                requestCallback.onSuccess(responseInJson
                                        .getResult());
                            }

                        });

                        // 保存Cookie
                        saveCookie();
                    }

e )其中CacheManager的putFileCache()完成了数据的唯一性操作(MD5)

public void putFileCache(final String key, final String data,
            long expiredTime) {
        String md5Key = BaseUtils.getMd5(key); // 根据Url产生唯一的MD5

        final CacheItem item = new CacheItem(md5Key, data, expiredTime);
        putIntoCache(item);
    }

f )MD5加密的实现

 public static String getMd5(final String s)
    {
        try
        {
            // Create MD5 Hash
            final MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
            digest.update(s.trim().getBytes());
            final byte messageDigest[] = digest.digest();
            return BaseUtils.toHexString(messageDigest);
        }
        catch (final NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        return s;
    }

    /**
     * 转换为十六进制字符串
     * 
     * @param b
     *            byte数组
     * @return String byte数组处理后字符串
     */
    public static String toHexString(final byte[] b)
    {// String to byte
        final StringBuilder sb = new StringBuilder(b.length * 2);
        for (final byte element : b)
        {
            sb.append(BaseUtils.HEX_DIGITS[(element & 0xf0) >>> 4]);
            sb.append(BaseUtils.HEX_DIGITS[element & 0x0f]);
        }
        return sb.toString();
    }

g )最后将可序列化的Object类型,序列化到本地

public static final void saveObject(String path, Object saveObject) {
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        File f = new File(path);
        try {
            fos = new FileOutputStream(f);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(saveObject);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (oos != null) {
                    oos.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

强制更新

在RemoteService暴露出一个boolean类型的参数,用于判断是否要遵从App端的缓存缓存策略,如果是,则在从url.xml中读数据的时候(UrlData实体),将其expired强制设置为0。

public void invoke(final BaseActivity activity, 
            final String apiKey,
            final List<RequestParameter> params,
            final RequestCallback callBack
            final boolean forceUpdate) {

            if(forceUpdate) {
            urlData.setExpires(0);
            }
    }
简单图书馆数据库设计 掌握数据库设计的全过程;设计E-R模型,掌握表的创建语句,注意表的约束的应用:主键,外键及check约束;学会使用数据库辅助设计工具软件;掌握查询、增删改等数据操作语句;掌握视图的建立与删除方法并体会其作用; 内容:随着信息技术的发展及图书馆中需管理信息量的增加,图书馆中图书及读者的管理越来越需要使用计算机来进行管理,在本实验中要求建立一个图书馆信息模型的数据库,实现图书信息管理。 立即下载

相关推荐

Windows11下QGIS 3.34.4安装Geo-SAM插件全流程(附RTX3060 CUDA12.0配置技巧)

本文详细介绍了在Windows 11系统中为QGIS 3.34.4安装和配置Geo-SAM插件的完整流程,特别针对RTX 3060显卡用户提供了CUDA 12.0与PyTorch环境的精准搭建方案。通过预编码与交互式分割两大核心步骤,该插件能显著提升遥感图像半自动标注的效率,降低硬件门槛,是地理信息处理领域融合AI技术的实用指南。

weixin_29089057的博客 295

APP中缓存、加载与刷新机制设计

一、缓存机制 1、为什么要加缓存? 场景一:【等待】,在向服务器请求新的数据时。我们让用户看到什么?第一种是漂亮的等待加载页面;第二种是缓存的内容。对于第二种,用户可以对页面进行操作,等待新数据时可以查看旧数据,更具有“可操作性”与“可用性”,从而减轻了从服务器获取数据这一动作的大小和时间长短,增强了用户体验。另一方面,如果内容更新的间隔较长或者用户刷新的间

azengqiang的博客 1万+

SAP采购含税价转换的底层逻辑解析:ABAP例程如何实现价税分离计算

本文深入解析SAP系统中采购含税价与不含税价的转换机制,重点介绍VOFM例程和ABAP代码实现价税分离计算的方法。通过详细讲解数学原理、税率体系及SAP定价引擎架构,为开发人员提供完整的解决方案,帮助提升采购业务中的价格处理效率和准确性。

weixin_29237635的博客 450

软件系统缓存设计

缓存(cache)是用于存储数据的硬件或软件的组成部分,以使得后续更快访问相应的数据。简单来说,缓存就是数据交换的缓冲区。缓存是一种空间换时间的设计。缓存中的数据可能是提前计算好的结果、数据的副本等。典型的应用场景:有 CPU cache,磁盘 cache,进程内缓存,分布式缓存,数据库缓存等。

云原生Java Web领域技术博客 2524

第1章:Zephyr 开发环境搭建与 Hello World

📝【摘要】本文是Zephyr RTOS开发入门指南的第一章,详细介绍了从环境搭建到首个应用运行的完整流程。主要内容包括:1️⃣ Zephyr项目结构解析与west工具链部署;2️⃣ 开发环境配置(Linux/WSL)及SDK安装;3️⃣ 两种实践路径——官方HelloWorld样例与自定义应用开发;4️⃣ 实际硬件部署方法(nRF/STM32)及常用west命令速查;5️⃣ 典型问题解决方案。通过qemu_x86模拟器演示了基础打印功能实现,为后续深度开发奠定基础。

hemoparrot的专栏 1358

无人机测绘航线生成算法

JavaScript开发和测试无人机测绘航线的自动生成方法,设计可行,算法可靠

ly1302116的专栏 5235

产品设计之路:Android应用-开发技术【数据缓存】

最近真够忙的,瞎忙!好久没写博客。不知道写什么,就写些最近对用户体验这块的一个小的见解吧。 无论大型或小型应用,灵活的缓存可以说不仅大大减轻了服务器的压力,而且因为更快速的用户体验而方便了用户。从事Android开发工作以来,个人认为Android应用可以说是作为小型应用,只是其中很多的开发时间花费在细节之上(UI交互方式、响应速度、效果、字体、颜色等等),其中90%乃至99的应用并不是需要实时...

www.jiav.net技术网站的加盟博客 370

Open3D 计算点云的倒角距离(Chamfer Distance)【2025最新版】

;Chamfer Distance距离可以计算生成点云数据与标签点云数据之间的平均最短点距离。Open3D可以直接用来计算点云的Chamfer Distance距离。博客长期更新,本文最近一次更新时间为:2025年2月18日。

点云侠的博客 3254

移动应用开发中如何做数据缓存

随着移动互联网的发展,用户对App的性能、体验等各方面要求都有所增强,为了满足用户的需求,在移动平台中做数据缓存,来缩短App响应时间,提高App的响应效率显得尤为重要。良好的用户的体验,是建立在数据缓存之上的。 不管是iOS、Android还是windows phone,增加缓存模块的目的是要提高用户体验交互的,所以缓存的目的在于: 1、效率,缓存的目的是为了提高性能,不要因为缓存的原因反而

码农 5462

谷歌A2A协议入门指南:附简易Python代码示例

继"关税"之后,当下最热门的词汇当属AI智能体——这种基于人工智能的软件能够执行复杂任务、实现工作流自动化并提升生产效率。但迄今为止,大多数智能体都处于各自为政的状态,难以顺畅协作。就像团队执行重大项目时,成员之间却无法交流!对于技术人员而言,一个可能遇到的典型场景是:假设你需要协调四个不同的AI服务——处理用户查询的Gemini智能体、在向量数据库进行搜索的AI应用、基于Claude的摘要生成器,以及运行专业领域逻辑的Python智能体。

独立开发,substack顶级编辑 793

Spring AI Alibaba实战训练营-14基于A2A协议智能体应用开发指南

本文介绍了基于A2A协议的智能体应用开发流程,主要包括客户端和服务端两个模块的实现。关键技术包括A2A通信协议、Nacos服务发现、Spring AI Alibaba框架和DashScope通义千问API。开发步骤涵盖环境准备(JDK17、Maven、Nacos)、项目创建、依赖配置(重点引入spring-ai-alibaba相关组件)以及Nacos和DashScope的核心配置。整个系统架构采用客户端通过Nacos发现服务端Agent,再调用阿里云AI服务的模式,实现了AI能力的解耦与复用。

program哲学 504

[读书笔记]《APP研发录》第二章

APP研发录第二章笔记 抛弃AsyncTask,自定义一套网络底层的封装框架。 设计一套App缓存策略。 设计一套MockService的机制,在没有MobileAPI的时候,也能假装获取到了网络返回的数据。 封装了用户Cookie的逻辑。 2.1 网络底层封装很多公司和团队都是用AsyncTask来封装网络底层,因为这个类非常好用,内部封装了很多好用的方法,但缺点是可扩展性不高。对于网络请求,我们

陶程的博客 2506

WPF实现圆形菜单动态展开折叠效果

实现效果如下: 思路:根据子菜单个数计算旋转角度动态生成子菜单,并设置展开折叠动画。 步骤: 1、自定义按钮MyButton,建立展示图像属性DisplayImage public class MyButton : Button { public static readonly DependencyProperty DisplayImageProperty = DependencyProperty.Register("DisplayImage", typeof(

dnazhd的博客 3149

《App研发录》读书笔记

这本书基本上涵盖了移动开发中常见的关注点,之所以用关注点而不用技术点这个词是因为这本书并没有讲到具体的技术实现,但提供了行之有效的解决方案。读这本书的时候非常有感触,它很多的框架设计和解决方案与我实际开发中都是不谋而合的(有点自夸的意思哈)。所以也非常感谢作者能这么详细的记录下来。这篇读书笔记是记录我在阅读过程中感觉需要重点强调的地方和自己的一些理解,也供大家能快速的浏览本书的章节。 关于重构 对于

天盟 - 技术博客 - Eamon 1208

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

APP研发录读书笔记:网络底层框架设计

一.统一响应实体类Response  我们一般采用JSON作为API返回结果,数据格式一般为: { "errorCode":0, "errorMessage":""; "result":{} }一般有错误码,错误消息及返回数据,因此可以定义Response如下: public class Response { private int errorCode; private

hpb21的专栏 877

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

App 研发录、架构设计、Crash分析和竞品技术分析------读书笔记(第三章)

Android经典场景设计1、App图片缓存设计 设计一个ImageLoaderr,ImageLoader的工作原理是 这样的在显示图片的时候,这会先从内存中查找;如果没有就去本地查找,如果还没有就开一个新的线程去下载这个图片,下载成功会把图片同时缓存到内存和本地。 基于这个原理,我们可以在每次退出一个页面的时候,把ImageLoader内存中的缓存全部清除,这样就节省了大量的内存,反正

1739

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

App 研发录、架构设计、Crash分析和竞品技术分析------读书笔记(第二章)

网络底层框架设计1、不要自己定义网络请求框架,网络层不要使用AsyncTask 2、在网络返回数据Response的应该有一个规范的格式{ "isError":true, "errorType":1, "errorMessage":"网络异常" "result":"" }返回的真实数据应该放在result里面 3、使用原生的ThreadPoolExecutor+R

658

读书笔记----App研发录 第一章 重构

读书笔记—-App研发录 第一章 重构   对代码的重构,本质上遵循了六大设计原则。这是编码的根本准则,只有遵循这些准则,才会让代码避免恶化的脚步。拥有更好的扩展性,易读性和便于维护。这是一个良好项目的开始。

PirateBrook的天梯 632

App 研发录、架构设计、Crash分析和竞品技术分析------读书笔记(第一章)

第一章:重构 1、要新建一个AndroidLib类库,将业务无关的逻辑转移到AndroidLib,一般来说包含五在部分 activity:存放的是与业务无头的activity基类, net:存放网络请求相关的 cache:存放缓存数据和图片相关的处理 -ui:存放的是自定义控件 -util:存在工具类 2、为主项目的分类就根据情况来 activity:存在所有activity adapter

757

读书笔记-App研发录-第12章-无线团队的组建和管理

面试13问,20个技能点,书籍推荐。

Dsa_ 484

《移动App测试实战》读书笔记

第一章 概述 什么是移动产品?移动产品是一个可以在移动设备上安装的App,或者一个可以在移动设备上访问的定制页面。 1.1 研发流程 互联网产品的研发过程主要涉及以下职位分工。 产品经理:负责产品方向或需求规划,需求可能来自于产品经理本人或者由其代理的第三方客户 项目经理:负责项目实施安排,资源、进度、变更、风险等 设计师:产出设计原型 开发:产出可运行的实际产品,也可细分为...

weixin_30547797的博客 434

《Flutter技术解析与实战》读书笔记

第一章 混合工程 1. 混合工程下的Flutter研发结构 2. 构建优化 问题:Android在FLutter启动是构建缓慢 解决:是工程应用Module对应的build.gradle位于android/app下 Native启动下的Flutter调试 iOS:使用Observatory Android和iOS:使用IDE链接调试配置Dart Remote Debug Native启动下的Flutter热重载 启动App,进入Flutter页面后 iOS:查找Observatory端口x和认证码y,在

eaway2009的专栏 791

ANDROID学习书单

Skip to content PersonalOpen sourceBusinessExplore Sign upSign in PricingBlogSupport This repository Watch388 Star3,653 Fork1,375 GeniusVJR/Learni...

weixin_30478619的博客 151

Android--面试中遇到的问题总结(三)

《Android 开发工程师面试指南 LearningNotes 》,作者是陶程,由梁观全贡献部分。大家可以去知乎关注这两位用心的少年。这份指南包含了大部分Android开发的基础、进阶知识,不仅可以帮助准备面试的同学,也可以帮助正在学习和工作的同学梳理自己的知识点。有心的同学也可以帮他们不断完善。 微博关注:http://weibo.com/informationstation 第一部分: ...

超宇的博客 4299

Android复习指南 复习完,BAT offer不再难

《Android 开发工程师面试指南 LearningNotes 》,作者是知乎Android开发工程师陶程,由梁观全贡献部分。大家可以去知乎关注这两位用心的少年。这份指南包含了大部分Android开发的基础、进阶知识,不仅可以帮助准备面试的同学,也可以帮助正在学习和工作的同学梳理自己的知识点。有心的同学也可以帮他们不断完善。有其他需求的也可以私信我。 研发中 第一部分: Android...

weixin_43901866的博客 447

《web全栈工程师的自我修养》 读书笔记

《web全栈工程师的自我修养》 读书笔记 作者:余果。 人民邮电出版社。2015年9月第1版。 值得轻快一读,另外此书里推荐的书籍很好。Full-Stack Engineer! 一、如何成为全栈工程师 1 定义:全栈工程师是指,一个能处理数据库、服务器、系统工程和客户端的所有工作的工程师。根据项目不同,可能分为移动栈、web栈,或原生应用...

weixin_30315723的博客 184
上一篇: Android图片加载框架Fresco解析
下一篇: 单元测试和Mock方法
PirateBrook
博客等级 码龄11年 90粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值