精华内容
下载资源
问答
  • 设计人员有时会发现运算放大器产品说明书规范令人费解,因为并非所有性能特性都有最小规范或者最大规范。有时,您必须使用规范表或者典型性能图表中的...但是,这个“典型值”到底是什么意思呢?它的变化范围是多大呢?
  • 设计人员有时会发现运算放大器产品说明书规范令人费解,因为并非所有性能特性都有最小规范或者最大规范。有时,您必须使用规范表或者典型性能图表中的...但是,这个“典型值”到底是什么意思呢?它的变化范围是多大呢?
  • Android 4.3开始系统开放了NotificationListenerService API,让应用管理通知提供了可能,本文系统描述清理大师通知管理模块的设计与实现方式,以及开发过程中遇到问题和解决方案。[TOC]功能背景常驻通知栏清理大师...

    Android 4.3开始系统开放了NotificationListenerService API,让应用管理通知提供了可能,本文系统描述清理大师通知管理模块的设计与实现方式,以及开发过程中遇到问题和解决方案。

    [TOC]

    功能背景

    常驻通知栏

    清理大师内部一直存在一个问题就是常驻进程可能在某些条件下被kill掉,导致一些依赖常驻进程的功能失效,典型的如自动清理。由于android系统在管理内存的时候按照Low memory killer 机制来决定需要杀掉哪些进程,当系统内存不足的时候,按照oom_adj的值来判断进程的重要程度,这个值越小,表示进程越重要。而常驻通知栏的使用,可以提升进程的重要程度,因为实现上是一个前台服务,系统会认为此服务对用户来说是重要的,能一定程度上降低被系统kill掉的可能性。基于此背景,加入常驻通知栏功能对清理大师

    的功能完善上有促进作用,并且常驻通知栏提供一些小工具入口对于产品的活跃度提升也有一定帮助。

    关于oom_adj的规则不在本文的讨论范围,这里不再赘述。

    通知管理

    基于4.3API开放的接口,我们可以对系统发送的通知进行管理。android上很多应用会发送各种各样的通知,当用户下拉statusbar,会看到很多乱七八糟的通知存在通知栏,有些用户会认为这是一件很烦人的事情,所以管理通知可以帮用户解决这个问题。

    需求概述提供常驻通知栏入口;

    通知栏每一项功能分别为:进入大师内部,加速,通知管理/闹钟,手电/wifi,系统设置;

    通知栏样式适配;

    通知拦截;根据系统api对通知取消,使通知不再显示在通知栏。

    通知缓存;

    缓存分为内存缓存与本地缓存,其中内存缓存带跳转信息,可以跳转到原通知的目的地,本地缓存不带跳转信息,只打开应用。

    通知管理界面;

    对收到的通知界面展示,提供删除和加白功能。

    过滤规则;

    运营白名单机制,系统应用,带进度的通知,空通知,已经缓存的通知。

    前期调研

    对于系统回调返回的StatusBarNotification对象,通过源码可以发现里面其实是对Notification对象包装了一下,另外携带了一些基本信息。

    先来解决第一问题,怎么取消掉新收到的通知呢?NotificationListenerService提供了两个api,一个是取消所有通知(包括已经显示的),一个是根据参数取消单个通知,看上去第二个比较靠谱。写个demo试一下,果然是靠谱的,发送的新通知会被取消掉。根据经验换个5.0的系统试一下,果然是取消不掉的,又换API了?查官方文档,果然是换了:

    This method was deprecated in API level 21.Use cancelNotification(String) instead. Beginning with LOLLIPOP this method will no longer cancel the notification. It will continue to cancel the notification for applications whose targetSdkVersion is earlier than LOLLIPOP.

    5.0上不支持,改用cancelNotificatio(String)代替,5.0以下老方法还有效。那就适配一下加个判断解决。

    接下来看第二个问题。既然对收到的通知已经取消了,怎么缓存呢?需求是要求通知要带跳转信息,分析下Notification的源码吧,看看我们能获取到什么信息。发现contentIntent,contentRemoteView比较关键。contentIntent是一个PendingIntent对象,光它的内部机制就可以单开一个博文来描述,这里粗暴的理解为四个字“异步激发”。通知我们知道是由NotificationManagerService来管理的,通常我们点击它会启动目标应用,这显然是一个跨进程调用,我们要找的跳转信息就存在pendingIntent中。查看它的源码,发现一个叫send的方法,写个demo验证一下,完美。

    那么现在已经知道了,contentIntent这个对象是需要的,它携带了跳转信息。

    继续分析notification源码,发现contentRemoteView,这是一个RemoteView对象。熟悉自定义通知栏的同学应该用过这个。这个对象就是你布局的通知栏的样式。查看它的源码,发现有个apply的方法,描述如下:

    Inflates the view hierarchy represented by this object and applies all of the actions.

    这句话提供了两个信息,第一可以通过这个方法inflate出布局信息,返回一个view;

    另外一个是applies all of the actions。通过返回的view,我们可以得到通知栏的布局view,那么我们就可以在界面上还原出这个通知的原样了。

    这里的actions很有用,后面解决一个问题就研究了它,这里先不赘述了。

    好了,调研到这里,我们数据已经准备好了,接下来该缓存。第一反应,我能把这些数据持久化到本地就好了,这样数据不丢失,状态也能保存,之后需要的时候读取出来。听上去不错,但是一用就犯错,自定义的对象虽然实现了序列化接口,但是pendingIntent这个对象是个Parcelable对象,没法用java的序列化方式往磁盘写,它里面携带binder对象,并且自身没有实现Serializable,直接报错!此路不行。

    既然这样,就只能分为两块儿缓存了。内存缓存+磁盘缓存的方式来处理。内存缓存的数据,携带了pendingInetent,可以跳转到目标应用,本地缓存只保存通知基本信息,调研基本上能满足功能需求。

    设计思想

    缓存系统

    由于NotificationListenerService可以帮我们唤醒进程,并且需要有一份内存缓存,所以针对NotificationListenerService选择放在常驻进程中。缓存系统解决需要解决以下问题:

    内存限制

    出于占用内存的考虑,设计上缓存系统有上限为最新的200条通知,超过200条会移除最老的通知。

    多线程问题

    service在收到通知的时候,是在binder线程中,也就是说对于缓存系统,put操作是在binder线程中完成的。而UI可以对缓存操作,UI线程可以读取,修改缓存,所以同步问题是需要解决的。有以下两种方案:

    1.读写锁,此方式不赘述。

    2.任务队列。既然操作缓存不再一个线程,那么就让这些操作在同一个线程中排队完成。可以使用HandlerThread的任务队列来设计。

    跨进程传输问题

    由于数据在常驻进程,如果Activity也在常驻进程的话,每次开启界面退出后activity销毁内存释放得不是很及时,会导致常驻进程内存额外有UI的内存,所以对activity没有声明所属进程。那么当UI进程启动通知管理页面,需要跨进程取数据,需要用到AIDL方式。需要注意的是,binder在数据传输的时候数据大小限制为1M,而且是进程内部所有的binder通信共享的,所以当数据过大是传输出问题的。所以缓存系统需要提供分页传输,或者单个实体传输,避免使用集合传输。

    补充:既然传递大数据有问题,那么为什么bitmap可以传输呢?这是因为binder传输的时候对底层数据的大小做了分类,对于大型数据如bitmap,使用Ashmem匿名共享内存的方式传输的。所以,我们有两种方案:

    将数据转成bitmap格式,编码解码传输;

    直接使用android提供的MemoryFile传输;

    内存本地双缓存

    为了设计上方便,对于本地缓存设计成内存缓存的快照。每次更新内存缓存,同步更新本地缓存一次。这样避免设计成两份缓存,需要合并数据的麻烦。

    流程

    通知管理的主要流程如下:

    当收到一条通知的时候,会先经过一个过滤器,通过过滤器的通知,先取消掉它在通知栏的显示,然后进入缓存系统。

    当界面上展示的时候,通过一个UIop的中间层访问缓存系统,并通过UIop对数据删除,加白等操作。

    1st=>start: Start

    e=>end: End

    in=>operation: onNotificationPosted

    filter=>operation: doFilter

    cancle=>condition: cancle?

    cache=>subroutine: cache

    uiop=>operation: OP

    UI=>subroutine: UI

    st->in->filter->cancle

    cancle(yes,right)->in

    cancle(no)->cache

    cache(right)->uiop(right)->UI

    环境与配置

    目前清理大师依赖了额外sdk jar包,新增的NotificationListenerService在4.3以上才有,工程编译版本是4.0,所以将SDK目录下platforms/android-19的android.jar解压找出需要的class文件。按照原包名路径重新打包进android-plus.jar中。

    踩坑与填坑如何唯一区分一条通知?

    NotificationListenerService服务启动后,只要有任何通知更新,都会收到一条StatusBarNotification,很多应用发送通知的id都是一个,根据包名与id共同判断无法做到通知唯一性,这样就不能保证进入缓存的通知实体能保证不漏、不重cache住所有收到的通知。如何来区分呢?如何来区分呢?经过一些应用尝试,统计如下这些字段共同判断能解决绝大部分。

    1

    2

    3if (entity.id == this.id && entity.pkgName.equals(this.pkgName) && entity.title.equals(this.title) && entity.ticker.equals(this.ticker)) {

    ...

    }

    解决带进度的通知

    带进度的通知,每次刷新的时候,NotificationListenerService都会收到一条通知,一般应用会有一个进度条,有些应用没有进度条,只有不断变化的百分比数字(titlle字段),当然每次收到的通知按照上面的逻辑是区分不出来的,还有的进度条跟百分比都有,这就需要来抓进度条了。如何判断通知带进度条?

    前面留下一个actions的问题,这个action是我们用来抓取是否包含进度的关键。分析RemoteView源码,发现有一个mActions字段,记录了这个view包含的一些列操作,比如setText,setSize,setMax等。这个字段是隐藏的,需要反射来解析里面的数据,然后看是否包含setProgress方法,通过这个标记来确定是否包含进度条。

    展开全文
  • Shell 既是一种命令语言,又是一种程序设计语言。Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一...

    5d79f1a45a7ba849.jpg

    Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

    Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

    Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。

    Shell 脚本

    Shell 脚本(shell script),是一种为 shell 编写的脚本程序。

    业界所说的 shell 通常都是指 shell 脚本,但读者朋友要知道,shell 和 shell script 是两个不同的概念。

    由于习惯的原因,简洁起见,本文出现的 "shell编程" 都是指 shell 脚本编程,不是指开发 shell 自身。

    Shell 环境

    Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。

    Linux 的 Shell 种类众多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)

    Bourne Again Shell(/bin/bash)

    C Shell(/usr/bin/csh)

    K Shell(/usr/bin/ksh)

    Shell for Root(/sbin/sh)

    ……

    本教程关注的是 Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。

    在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。

    #! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序。

    第一个shell脚本

    打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh,扩展名为 sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用 php 写 shell 脚本,扩展名就用 php 好了。

    输入一些代码,第一行一般是这样:

    实例#!/bin/bash

    echo "Hello World !"

    #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。

    echo 命令用于向窗口输出文本。

    运行 Shell 脚本有两种方法:

    1、作为可执行程序

    将上面的代码保存为 test.sh,并 cd 到相应目录:chmod +x ./test.sh #使脚本具有执行权限

    ./test.sh #执行脚本

    注意,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。

    2、作为解释器参数

    这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:/bin/sh test.sh

    /bin/php test.php

    这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。

    展开全文
  • 数据库中的全表扫描是连续读IO,索引访问则是典型的随机读IO,日志文件是连续写IO,而数据文件则是随机写IO。数据库系统基于传统磁盘访问特性来设计,最大特点是日志文件采用sequential loggi...

    IO有四种类型:连续读,随机读,随机写和连续写,连续读写的IO size通常比较大(128KB-1MB),主要衡量吞吐量,而随机读写的IO size比较小(小于8KB),主要衡量IOPS和响应时间。数据库中的全表扫描是连续读IO,索引访问则是典型的随机读IO,日志文件是连续写IO,而数据文件则是随机写IO。

    数据库系统基于传统磁盘访问特性来设计,最大特点是日志文件采用sequential logging,数据库中的日志文件,要求必须在事务提交时写入到磁盘,对响应时间的要求很高,所以设计为顺序写入的方式,可以有效降低磁盘寻道花费的时间,减少延迟时间。日志文件的顺序写入,虽然是物理位置是连续的,但是并不同于传统的连续写类型,日志文件的IO size很小(通常小于4K),每个IO之间是独立的(磁头必须抬起来重新寻道,并等待磁盘转动到相应的位置),而且间隔很短,数据库通过log buffer(缓存)和group commit的方式(批量提交)来达到提高IO size的大小,并减少IO的次数,从而得到更小的响应延迟,所以日志文件的顺序写入可以被认为是“连续位置的随机写入”,更关注IOPS,而不是吞吐量。

    数据文件采用in place uddate的方式,意思是数据文件的修改都是写入到原来的位置,数据文件不同于日志文件,并不会在事务commit时写入数据文件,只有当数据库发现dirty buffer过多或者需要做checkpoint动作时,才会刷新这些dirty buffer到相应的位置,这是一个异步的过程,通常情况下,数据文件的随机写入对IO的要求并不是特别高,只要满足checkpoint和dirty buffer的要求就可以了。

    展开全文
  • 首先我们了解一下什么是源代码?源代码(也称源程序)是指未编译的按照一定的程序设计语言规范书写的文本文件,是一系列人类可读的计算机语言指令。在现代程序语言中,源代码可以是以书籍或者磁带的形式出现,但最为...

    首先我们了解一下什么是源代码?

    源代码(也称源程序)是指未编译的按照一定的程序设计语言规范书写的文本文件,是一系列人类可读的计算机语言指令。

    在现代程序语言中,源代码可以是以书籍或者磁带的形式出现,但最为常用的格式是文本文件,这种典型格式的目的是为了编译出计算机程序。计算机源代码的最终目的是将人类可读的文本翻译成为计算机可以执行的二进制指令,这种过程叫做编译,通过编译器完成。

    "源代码"在大多数时候等于"源文件".

    比如在这个网页上右键鼠标,选择查看源文件。出来一个记事本,里面的内容就是此网页的源代码."这句话就体现了他们的关系,此处的源文件是指网页的源文件,而源代码就是源文件的内容,所以又可以称做网页的源代码。

    源代码是指原始代码,可以是任何语言代码。

    源程序、源文件、源代码是一回事。

    那么php源代码是什么意思?

    php源代码(也称php源程序),是指未编译的按照一定的PHP脚本语言规范书写的文本文件、一段程序,是一系列人类可读的计算机语言指令。

    一个PHP网页中含有PHP代码,那么把这个网页的整个原始文件用编辑器打开,或者用记事本打开,看到的就是PHP源代码。

    更多PHP相关知识,请访问php中文网!

    展开全文
  • 的频率响应函数freqz()4.8.3 IIR数字滤波器的频率变换设计法 1. IIR数字滤波器的频率变换设计法的基本原理 根据滤波器设计要求,设计模拟原型低通... 图4.39 IIR数字滤波器MATLAB设计步骤流程图 1.MATLAB的典型...
  • 在计算机视觉和音频处理等领域,最先进的模式...这种设计的一个重要动机是在这些领域中突出的多尺度结构和极高的信号维数。例如,一个典型的图像包含数百万个像素,这些像素必须由模型进行一致的处理。诸如神经OD...
  • 什么是REST  REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移。 它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一。 他在论文...
  • 近些年,美业实体店发展遭遇瓶颈,竞争压力大...再加上宣传材料设计周期长、费用贵、时效慢等缺点,使得美业新客难拓展。稍微有一点运营思维的商家,还会在点评网等生活平台上发布信息。2、服务体验差美业作为典型的...
  • 现在的苹果也开始模仿国产手机了,最典型的就是iphone11pro后置三摄就是模仿华为mate30手机的浴霸设计。好了,回归正题,为什么以前没有国产手机模仿苹果的圆形HOME键呢?一、圆形home键是苹果手机的独有标志,谁...
  • Java-Decorator设计模式

    2018-05-14 01:05:34
    今天我们来介绍一种新的设计模式:Decorator(装饰器)设计模式。 什么是装饰器设计模式呢?装饰器模式的意思是:... 装饰器设计模式的一个典型的应用是Java类库中的输入输出流设计,举个例子:JavaIO中的}Output...
  • MDI窗体设计

    2017-05-18 00:31:00
    1、MDI窗体是什么?  程序的用户界面一般分为两大类:单文档界面和多文档界面。   MDI是Multiple Document Interface的缩写,就是文档窗体的意思。它是和单文档SDI相对的。   C#允许在单个容器窗体中创建...
  • 设计模式之代理模式

    2014-12-03 09:40:00
    代理,一般人都知道是什么意思,代理是一种行为,在客户不想或不能直接操作时,把操作交付给代理来处理,代理模式亦是如此,代理模式是一种典型的行为型设计模式,想完成的行为引出了代理模式,其实现方法倒是不拘泥...
  • 而符合开闭原则最典型设计模式就是装饰者模式。 一、什么是装饰者模式? 装饰者模式可以在不改变代码结构的前提下,对已有的对象添加新的功能。 如果不考虑装饰者模式,我们要扩展一个类,可以使用继承的方式来...
  • 20201026-成信大-C语言程序设计-20201学期《C语言程序设计B》C-关于static关键字的读解 字面意思:静态 可以作用的对象:变量,函数 作用于全局变量 - 强调作用域 这时,它的作用,主要是限定这个全局变量的作用域是...
  • 设计模式之reactor、proactor

    千次阅读 2012-07-04 16:43:11
    什么意思呢?我们在编写网络程序的时候很想把网络数据和网络通信本身分离,这样可以很好的调试和分块。 1.典型的reactor模式为当数据来时,通知用户读 2.典型的proactor表现为数据到达时,为上面把数据存好后(当然...
  • 单例模式主要作用是保证在应用...看完这个定义 仍然不知道到底是什么意思。 英文解释 ensures a class has only one instance, and provides a global point of access to it. The above solution has multithreadin
  • 典型的棋类游戏-象棋为例,象棋是一种完全知识博弈(Games of Perfect Information),意思是指参与双方在任何时候都完全清楚每一个棋子是否存在,位于何处。只要看看棋盘,就一清二楚了。跳棋、围棋、象棋、...
  • 二十三种设计模式【PDF版】

    热门讨论 2011-05-30 14:13:49
    如果你还不了解设计模式是什么的话? 那就先看设计模式引言 ! 学习 GoF 设计模式的重要性 建筑和软件中模式之异同 A. 创建模式 设计模式之 Singleton(单态/单件) 阎宏博士讲解:单例(Singleton)模式 保证...
  • 对这样设计出来的数据库,只需多问几个为什么——业务模型是如何体现的?数据完整性如何保证?性能是如何权衡的?——恐怕设计者就该崩溃了。.  这也难怪,设计、开发人员在学校中学习数据库时,理论书籍离实际...
  • 对这样设计出来的数据库,只需多问几个为什么——业务模型是如何体现的?数据完整性如何保证?性能是如何权衡的?——恐怕设计者就该崩溃了。.  这也难怪,设计、开发人员在学校中学习数据库时,理论书籍离实际...
  • REST中的无状态约束是什么意思?HTTP是无状态协议是什么意思?为什么将HTTP设计为无状态协议?为什么REST要包含无状态约束?(一)Web的需求(二)利大于弊违背无状态交互约束的典型例子:基于session的会话管理机制...
  • 健壮是什么意思? 在本文的上下文中,健壮性是指在不立即返回给调用者的情况下管理流中的异常条件的能力。 在某些处理方案中, n个 m个回答足以做出结论。 通常具有这些趋势的示例处理场景是: 财务,保险和...
  • JAVAWEB三剑客之Filter

    2020-04-18 20:35:58
    什么是Filter,看名字就是过滤器的意思,主要是针对用户发起的请求进行拦截预处理,常见的Filter应用有检查当前请求是否登录,记录请求日志,设置上下文信息等等,当然Filter也可以对请求的响应做处理,Filter的设计...
  • 坚固是什么意思? 在本文的上下文中,健壮性是指在不立即返回到调用者的情况下管理流中的异常条件的能力。 在某些处理方案中, n个 m个回答足以做出结论。 通常具有这些趋势的示例处理场景是: 财务,保险和...
  • 今日目标:聊聊表格设计那些事儿你知道什么是ERD吗?不知道没关系,太正常了,我的Excel学员也不知道。ERD是Entity-Relationship Diagram的英文缩写,中文意思是「实体关系图」,是一种数据库设计结构化方法。一看到...

空空如也

空空如也

1 2 3 4 5
收藏数 91
精华内容 36
关键字:

典型设计什么意思