首页 文章 精选 留言 我的

精选列表

搜索[按需加载],共10000篇文章
优秀的个人博客,低调大师

Android官方开发文档Training系列课程中文版:后台加载数据之使用CursorLoader进行查询

原文地址:http://android.xsoftlab.net/training/load-data-background/index.html 引言 在ContentProvider中查询数据是需要花点时间的。如果你直接在Activity进行查询,那么这可能会导致UI线程阻塞,并会引起”Application Not Responding”异常。就算不会发生这些事情,那么用户也能感觉到卡顿,这会非常恼人的。为了避免这样的问题,应该将查询的工作放在单独的线程中执行,然后等待它执行完毕后将结果显示出来。 你可以使用一个异步查询对象在后台查询,然后等查询结束之后再与Activity建立连接。这个对象就是我们要说的CursorLoader。CursorLoader除了可以进行基本查询之外,还可以在数据发生变化后自动的重新进行查询。 这节课主要会学习如何使用CursorLoader在后台进行查询。 使用CursorLoader进行查询 CursorLoader对象在后台运行着一个异步查询,当查询结束之后会将结果返回到Activity或FragmentActivity。这使得查询在进行的过程中Activity或FragmentActivity还可以继续与用户交互。 定义使用CursorLoader的Activity 如果要在Activity中使用CursorLoader,需要用到LoaderCallbacks接口。CursorLoader会调用该接口中的方法,从而使得与Activity产生交互。这节课与下节课都会详细描述该接口中的回调。 举个例子,下面的代码演示了如何定义一个使用了CursorLoader的FragmentActivity。通过继承FragmentActivity,你可以获得CursorLoader对Fragment的支持: public class PhotoThumbnailFragment extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor> { ... } 初始化查询 使用LoaderManager.initLoader()可以初始化查询。它其实初始化了后台查询框架。可以将初始化这部分工作放在用户输入了需要查询的数据之后,或者如果不需要用户输入数据,那么也可以将这部分工作放在onCreate()或onCreateView()中执行: // Identifies a particular Loader being used in this component private static final int URL_LOADER = 0; ... /* When the system is ready for the Fragment to appear, this displays * the Fragment's View */ public View onCreateView( LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle) { ... /* * Initializes the CursorLoader. The URL_LOADER value is eventually passed * to onCreateLoader(). */ getLoaderManager().initLoader(URL_LOADER, null, this); ... } Note: getLoaderManager()方法只对Fragment类可用。如果需要在FragmentActivity中获得LoaderManager,调用getSupportLoaderManager()方法即可。 开始查询 后台查询框架的初始化一旦完成,紧接着你所实现的onCreateLoader()就会被调用。如果要启动查询,需要在该方法内返回一个CursorLoader对象。你可以实例化一个空的CursorLoader,然后再使用它的方法定义查询,或者你也可以在实例化CursorLoader的时候定义查询。 /* * Callback that's invoked when the system has initialized the Loader and * is ready to start the query. This usually happens when initLoader() is * called. The loaderID argument contains the ID value passed to the * initLoader() call. */ @Override public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle) { /* * Takes action based on the ID of the Loader that's being created */ switch (loaderID) { case URL_LOADER: // Returns a new CursorLoader return new CursorLoader( getActivity(), // Parent activity context mDataUrl, // Table to query mProjection, // Projection to return null, // No selection clause null, // No selection arguments null // Default sort order ); default: // An invalid id was passed in return null; } } 一旦后台查询框架获得了该对象,那么它会马上在后台开始查询。当查询结果完成,后台查询框架会调用onLoadFinished(),该方法的具体内容会在下节课说明。

优秀的个人博客,低调大师

HVCI 与 Secure Boot 双重拦截下,为什么你的内核驱动必须通过 WHQL 认证才能正常加载?

前阵子帮一个做安全软件的团队排查问题。他们的过滤驱动在自家测试机上一切正常,发给客户后设备管理器直接黄叹号,事件查看器 System 日志刷出 Event ID 219,应用层拿到的错误是 0xC0000428(STATUS_INVALID_IMAGE_HASH)。客户那台机器开着 Secure Boot,组策略又把 VBS / HVCI 打开了。团队负责人第一句话是"可我都用 EV 代码签名证书签过了啊"。问题就在这儿:在 64 位 Windows 上,内核驱动真不是你签了名就能跑,得微软签过、还得 HVCI 认,缺一样都白搭。

优秀的个人博客,低调大师

HTML5手机端弹窗、提示框、loading加载(多功能xwPop弹窗升级版)

手机移动端响应式动画弹窗提示框插件xwPop,原生JS实现,带CSS3动画效果,丰富的JS弹出框提示信息插件,支持基本信息提示、带图标loading信息提示、confirm提示、自定义信息提示图标,仿Ios信息提示,支持较现代的浏览器。 在没有压缩的情况下,代码大小只有6KB,功能强大不输网上其他一些弹窗插件。 调用方式: 代码展示: 效果图展示: xwPop.js插件已经在项目中有应用,而且兼容性还可以,可能还有些地方写的不够完善,欢迎大家指正并逐步的完善解决。 感兴趣可以一起讨论:QQ(282310962) wx(xy190310)

优秀的个人博客,低调大师

Gartner访谈:目前区块链普遍存在误读,甲方加载给区块链太多无法承载的东西

AI金融评论报道,前一段时间舆论大哗的ICO项目被央行紧急叫停,不过,大家心知肚明的是,叫停的背后是监管在遏制代币融资,区块链技术本身并没有被否定。 在共享经济时代,互联网以去中心化的形式演进,而区块链技术去中心化、不可篡改等特点,让人们对区块链重塑商业架构和场景充满各种想象,即使目前颇有质疑,区块链的前景依然可期。 截止2016年底,国内已有上百家区块链公司,各种区块链联盟应运而生。然而泥沙俱下,创新永远伴随泡沫,商业需求的多元是区块链发展的最大动力,同时也持续扩大了需求与技术实际发展水平之间的期待性落差。 Gartner近期发布了2017年新兴科技技术成熟度曲线,从全行业的角度分析了开发新技术组合时必须考虑的技术和趋势,区块链正在这条技术成熟曲线上快速移动,有望在未来五到十年内成为拥有高度竞争优势的技术。近日,Gartner公司研究

优秀的个人博客,低调大师

🏆【Alibaba中间件技术系列】「Nacos技术专题」配置中心加载原理和配置实时更新原理分析(上)

官方资源 https://nacos.io/zh-cn/docs/quick-start.html Nacos之配置中心 动态配置管理是 Nacos的三大功能之一,通过动态配置服务,可以在所有环境中以集中和动态的方式管理所有应用程序或服务的配置信息。 动态配置中心可以实现配置更新时无需重新部署应用程序和服务即可使相应的配置信息生效,这极大了增加了系统的运维能力。 动态配置 Nacos的动态配置的能力,看看 Nacos是如何以简单、优雅、高效的方式管理配置,实现配置的动态变更的,接下来来了解下 Nacos 的动态配置的功能。 环境准备 首先我们要准备一个 Nacos 的服务端,现在有两种方式获取 Nacos 的服务端: 通过源码编译 下载Release包 注意:自己去编译可以了解一些过程也有可能会碰到一些问题,这些都是很重要的经验,好了那我们直接源码编译吧。 clone 一份 nacos 的代码到自己的 github 库,然后把代码 clone 到本地。 git clone https://github.com/alibaba/nacos.git 在项目的根目录下执行以下命令(假设我们已经配置好了 java 和 maven 环境): cd nacos/ mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U 执行成功之后你将会看到如下图所示的结果: 在项目的 distribution 目录下我们就可以找到可执行程序了,包括两个压缩包,这两个压缩包就是nacos 的 github 官网上发布的 Release 包。 ls -al distribution/target/ // change the $version to your actual path cd distribution/target/nacos-server-$version/nacos/bin 把编译好的两个压缩包拷贝出来,解压出来直接使用,这样就相当于我们下载了 Release 包了。 解压后文件结构和nacos-server一样,我们直接执行 startup.sh 即可启动一个单机的 Nacos 服务端了。 启动服务端 Linux/Unix/Mac 启动命令(standalone代表着单机模式运行,非集群模式): sh startup.sh -m standalone 如果您使用的是ubuntu系统,或者运行脚本报错提示[[符号找不到,可尝试如下运行: bash startup.sh -m standalone Windows 启动命令(standalone代表着单机模式运行,非集群模式): startup.cmd -m standalone 适用场景 动态配置管理的效果之后,我们知道了大概的原理了,Nacos 服务端保存了配置信息,客户端连接到服务端之后,根据 dataID,group可以获取到具体的配置信息,当服务端的配置发生变更时,客户端会收到通知。当客户端拿到变更后的最新配置信息后,就可以做自己的处理了,这非常有用,所有需要使用配置的场景都可以通过 Nacos 来进行管理。可以说 Nacos 有很多的适用场景,包括但不限于以下这些情况: 数据库连接信息 限流规则和降级开关 流量的动态调度 推还是拉 了解了 Nacos 的配置管理的功能了,但是有一个问题我们需要弄明白,那就是 Nacos 客户端是怎么实时获取到 Nacos 服务端的最新数据的。其实客户端和服务端之间的数据交互,无外乎两种情况: 服务端推数据给客户端 客户端从服务端拉数据 创建 ConfigService 首先是创建了一个 ConfigService。而 ConfigService 是通过 ConfigFactory 类创建的,如下图所示: 这里并没有通过单例或者缓存技术,也就是说每次调用都会重新创建一个 ConfigService的实例。 实例化 ConfigService 来看下 NacosConfigService 的构造方法,看看 ConfigService 是怎么实例化的,如下图所示: 实例化时主要是初始化了两个对象,他们分别是:HttpAgent和ClientWorker HttpAgent agent 是通过装饰着模式实现的,ServerHttpAgent 是实际工作的类,MetricsHttpAgent 在内部也是调用了 ServerHttpAgent 的方法,另外加上了一些统计操作,所以我们只需要关心 ServerHttpAgent 的功能就可以了。 ClientWorker agent 实际是在 ClientWorker 中发挥能力的,下面我们来看下 ClientWorker 类,以下是 ClientWorker 的构造方法,如下图所示: 可以看到 ClientWorker 除了将 HttpAgent 维持在自己内部,还创建了两个线程池: 第一个线程池是只拥有一个线程用来执行定时任务的 executor,executor 每隔 10ms 就会执行一次 checkConfigInfo() 方法,从方法名上可以知道是每 10 ms 检查一次配置信息。 第二个线程池是一个普通的线程池,从 ThreadFactory 的名称可以看到这个线程池是做长轮询的。 现在让我们来看下 executor 每 10ms 执行的方法到底是干什么的,如下图所示: checkConfigInfo方法是取出了一批任务,提交给 executorService 线程池去执行,执行的任务就是 LongPollingRunnable,每个任务都有一个 taskId。 LongPollingRunnable做了什么,主要分为两部分,第一部分是检查本地的配置信息,第二部分是获取服务端的配置信息然后更新到本地。 本地检查 首先取出与该 taskId 相关的 CacheData,然后对 CacheData 进行检查,包括本地配置检查和监听器的 md5 检查,本地检查主要是做一个故障容错,当服务端挂掉后,Nacos 客户端可以从本地的文件系统中获取相关的配置信息,如下图所示: 通过跟踪 checkLocalConfig 方法,可以看到 Nacos 将配置信息保存在了 ~/nacos/config/fixed-{address}_8848_nacos/snapshot/DEFAULT_GROUP/{dataId} 服务端检查 通过 checkUpdateDataIds() 方法从服务端获取那些值发生了变化的 dataId 列表, 通过 getServerConfig 方法,根据 dataId 到服务端获取最新的配置信息,接着将最新的配置信息保存到 CacheData 中。 调用 CacheData 的 checkListenerMd5 方法。 可以看到,在该任务的最后,也就是在 finally 中又重新通过 executorService 提交了本任务。 ConfigListener ConfigService 来添加一个 Listener 了,最终是调用了 ClientWorker 的 addTenantListeners 方法,如下图所示: 该方法分为两个部分,首先根据 dataId,group 和当前的场景获取一个 CacheData 对象,然后将当前要添加的 listener 对象添加到 CacheData 中去。 也就是说 listener 最终是被这里的 CacheData 所持有了,那 listener 的回调方法 receiveConfigInfo 就应该是在 CacheData 中触发的。 我们发现 CacheData 是出现频率非常高的一个类,在 LongPollingRunnable 的任务中,几乎所有的方法都围绕着 CacheData 类,现在添加 Listener 的时候,实际上该 Listener 也被委托给了 CacheData,那我们要重点关注下 CacheData 类了。 CacheData 首先让我们来看一下 CacheData 中的成员变量,如下图所示: 可以看到除了 dataId,group,content,taskId 这些跟配置相关的属性,还有两个比较重要的属性:listeners、md5。 listeners 是该 CacheData 所关联的所有 listener,不过不是保存的原始的 Listener 对象,而是包装后的 ManagerListenerWrap 对象,该对象除了持有 Listener 对象,还持有了一个 lastCallMd5 属性。 另外一个属性 md5 就是根据当前对象的 content 计算出来的 md5 值。 触发回调 ConfigService 的 Listener 是在什么时候触发回调方法 receiveConfigInfo 的。 在 ClientWorker 中的定时任务中,启动了一个长轮询的任务:LongPollingRunnable,该任务多次执行了 cacheData.checkListenerMd5() 方法,那现在就让我们来看下这个方法到底做了些什么,如下图所示: 该方法会检查 CacheData 当前的 md5 与 CacheData 持有的所有 Listener 中保存的 md5 的值是否一致,如果不一致,就执行一个安全的监听器的通知方法:safeNotifyListener,通知 Listener 的使用者,该 Listener 所关注的配置信息已经发生改变了。 safeNotifyListener 方法 Md5何时变更 那 CacheData 的 md5 值是何时发生改变的呢?我们可以回想一下,在上面的 LongPollingRunnable 所执行的任务中,在获取服务端发生变更的配置信息时,将最新的 content 数据写入了 CacheData 中,我们可以看下该方法如下: 可以看到是在长轮询的任务中,当服务端配置信息发生变更时,客户端将最新的数据获取下来之后,保存在了 CacheData 中,同时更新了该 CacheData 的 md5 值,所以当下次执行 checkListenerMd5 方法时,就会发现当前 listener 所持有的 md5 值已经和 CacheData 的 md5 值不一样了,也就意味着服务端的配置信息发生改变了,这时就需要将最新的数据通知给 Listener 的持有者。 至此配置中心的完整流程已经分析完毕了,可以发现,Nacos 并不是通过推的方式将服务端最新的配置信息发送给客户端的,而是客户端维护了一个长轮询的任务,定时去拉取发生变更的配置信息,然后将最新的数据推送给 Listener 的持有者。 客户端是通过一个定时任务来检查自己监听的配置项的数据的,一旦服务端的数据发生变化时,客户端将会获取到最新的数据,并将最新的数据保存在一个 CacheData 对象中,然后会重新计算 CacheData 的 md5 属性的值,此时就会对该 CacheData 所绑定的 Listener 触发 receiveConfigInfo 回调。 拉的优势 客户端拉取服务端的数据与服务端推送数据给客户端相比,优势在哪呢,为什么 Nacos 不设计成主动推送数据,而是要客户端去拉取呢?如果用推的方式,服务端需要维持与客户端的长连接,这样的话需要耗费大量的资源,并且还需要考虑连接的有效性,例如需要通过心跳来维持两者之间的连接。而用拉的方式,客户端只需要通过一个无状态的 http 请求即可获取到服务端的数据。 此外考虑到服务端故障的问题,客户端将最新数据获取后会保存在本地的 snapshot 文件中,以后会优先从文件中获取配置信息的值。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册