先看经典的处理方法: 我们需要更新进度时,将其切换到主线程,并更新进度显示。我们测试显示用了32735ms,也就是说100万次进度更新,用了约33秒。 接下来我们来看下优化后的代码: 对的,你没看错,我们将 FProgress.Update 直接在后台线程调用了。我们对其代码进行了逻辑隔离,实测 100 万次进度更新,
[教程] Delphi Android aab 转换为 apk 工具
这个工具是基于官方的 bundle-tool 工具,然后通过批处理方式脚本实现。 1、下载工具文件。 2、解压到你工程文件目录下 3、用记事本打开 android64.bat ,然后设置 FileName 等参数的值 4、将你的 Android 程序发布为 Android64 -> Application Store
[教程]FMX for Android 使用自定义字体
步骤1:找到相应的字体文件 步骤2:在部署页面,将字体部署到 assets\internal\,保证文件为名为 字体名称.ttf 或者是 字体名称.otf,注意这个字体名称必需与在控件的 TextSettings.Font.Family 的设置一致 步骤3:设置对应控件的字体属性名称为文件名中的 字体名称 部分 步骤4
[FMX]修正 FMX 组件嵌套时 Tab 顺序不正常的问题
问题发生在 FMX.Forms.AdvanceTabFocus,检测 Tab 顺序时,没有做深入测试,造成无法正确的处理。 下面的代码用于解决这个一问题,在窗体中增加: 在对应的实现中,增加如下代码: 注意:上面的代码为免费版本代码,付费版本代码支持自动注入和焦点循环,付费金额:99元 付费方式
[教程]Delphi 函数的内部函数在匿名回调函数中无法使用的一种解决办法
这个问题很简单,将对应的函数改写赋值到一个匿名函数变量即可。 上面的代码改写成: 然后在后面的直接调用 add 即可。
[教程]Delphi Android应用启动画面详解
很多人在吐嘈Delphi Android Splash 的设定(包括我在内),确实设计的很糟糕。不过话说回来了,也不是不能用,所以大家研究之后,八仙过海,各显神通。对于这些教程,大家可以参考。 首先说一下 Delphi 自带的 Android Splash 实现的限制: 如果你注意到上面的限制,那么如果不修改系统的 S
【教程】QJSON 创建根结点为数组的 JSON 内容
默认情况下,QJson创建后的实例是 jdtNull 类型(空类型),当向其添加子元素,会自动调整为 jdtObject (对象类型),如果是用 AsXXX赋值时,会自动根据接口改变结点类型。 如果我们在 QJson 中,要将根结点改变数组类型,就需要明确指定这一点: 在明确这一点以后,后面的代码写法就和普通的 JSO
[教程]一种在应用中判断动态链接库是否与当前应用兼容的方法
代码终结者: 如果仅仅判断DLL或程序是不是64位的,可以直接用 GetBinaryType 函数来判断,具体信息参与微软官方 API 文档
[FMX]教程:运行时动态修改 FMX 样式
简单说几个点: 1、FMX 框架下,样式是通过名称来标志的。 2、GetStyleObject 默认是克隆原始的样式,所以直接修改对象自身的 FResourceLink 实例,不会影响其它样式,如果要修改全部同一类型控件的样式,手动调用控件的 GetStyleObject(false) 来获取样式的原始实例即可,进行调
[ZAsync]TZAsync.Queue
[功能说明] 此函数是一个简单的封装,以便在主线程中异步执行一些操作。而操作关联的组件如果释放的话,可以保证操作不会发生。 [函数参数] AOwner :异步操作依赖的宿主组件 AOnExecute : 要执行的操作代码 AOnCancel :当用户取消或宿主组件被释放时触发 AOnCleanup :无论操作是否被取消
[ZBar]CalcPerf 函数
所在单元:zbar.common 函数功能:计算当前代码段的执行时长(单位为纳秒) 函数参数: AHint:输出性能日志时的提示字符串 ACallback:当前代码执行完成时的回调函数,如果不指定,则调用 DefaultPerformanceCallback 输出日志。 返回值:返回当前用于计算应用性能的对象实例接口,
[杂谈]Microsoft Visual C++ Redistributable合集
官方下载地址: 32 位版本 64 位版本
[教程]DBGridEh 中获取当前鼠标位置的记录内容
第一步:在 OnMouseMove 事件中,调用 MouseCoord 函数,计算鼠标当前所在的行列信息。 第二步:用得到的行号(Y)减去当前表格选中的行号(Row)计算出两者的差值 (Distance)。 第三步:设置表格 DataLink.ActiveRecord 的值为 DataLink.ActiveRecord
[教程]ZAsync 异步编程教程之七:在后台线程中 async/await
在上一节中,我们做了一个简单的 async/await 的例子,这一节我们继续对其进行更详细的解析。 前面我们已经说过,async/await 模式是一种协同式的多任务执行机制,要求处理代码在等待一个操作时(如磁盘IO、网络IO等),显式调用对应的接口(对于 ZAsync ,为 TZAsync.Yield)。否则使用
[教程]ZAsync 异步编程之四:关于匿名函数和线程变量
[匿名函数] 在 Delphi 中,匿名函数实际上是一个接口,这一点我们在前面的文章中已经做出了明确的提示。从前面的分析我们可以看出: 1、在匿名函数中使用的局部变量,实际内存是对应的结构成员的位置,而不是当前函数栈上的位置。 2、如果一个接口局部变量被匿名函数引用,那么应该在用完后,设置为空,以便减小引用计数,避免内
[教程]ZAsync 异步编程之六:在主线程中使用async/await
async/await 是一种协同式的异步执行机制,它要求长时间执行的作业,主动去释放当前线程的控制权,从而让其它同一线程的函数获得执行机会,从而充分利用CPU资源。 要在你的程序中支持 async/await 模式,需要 : 1、引用 zbar.async 和 vcl.zbar.async/fmx.zbar.asyn
[教程]ZAsync异步编程之五:IZAsyncInvoker的执行链条
ZAsync 简化了异步编程模型的设计,做了以下强制约定: 异步作业执行可以在主线程或后台线程中执行 异步作业执行函数退出后的操作,如果是用 async/await 调用,则其在原线程中执行,而其它后台线程的异步作业,只能在主线程中运行,以方便访问主线程界面元素,减少出错的几率。 为了方便大家了解 ZAsync 异步编
[教程]ZAsync 异步编程之三:我们对异步编程的一些观点
异步编程对于开发人员来说,实际上是一个又爱又恨的东西,用好了很舒服,用不好很麻烦。异步编程中,异步操作代码的本身是在一个后台线程或当前线程中延迟调用。而大家说异步编程的几种不同的处理方式,实际上是指对异步处理完成后,如何处理后续的步骤,本质上都是回调处理函数,但操作各有不同: 直接设置回调函数 订阅机制:订阅异步作业通
[教程]使用 TZAsync 进行异步编程教程之二:TZAsync 解决了什么问题
在上一节教程的例子中,我们演示了一个简单的异步编程的例子。 我们请大家首先阅读 Delphi 自带的异步编程模型,那么它存在的问题: 生命周期问题: 没有和现有的组件体系结合,如果 BeginInvoke 引发的异步调用,返回回调时异步作业的创建者被释放,那么如果我们在其中访问创建者相关的实例,就有可能出现问题。 异步
[异步编程] 使用 ZAsync 进行异步编程教程之一:Hello,world
ZAsync 是由吉林省左右软件开发有限公司开发的一套异步编程框架,目标是用来简化异步编程模型。 在异步编程时,我们要解决几个问题: 1、异步操作的生命周期: 开启一个异步操作 在后台执行异步操作 异步操作执行完成 回调通知异步执行结果 异步操作结束清理释放 2、异步参数传递: 参数的生命周期管理 参数值修改问题 3、