一直都有整理收集一些常见而自己不知道或常常不记得的词条,但是发现仅仅保存下来并没有汇总成档,反复查看至熟悉。所以要开始好好的整理一番,以下是之前看到关于“如何应对用户短时间内对控件快速并多次点击”时看到的一些英文,因为不懂技术,所以除了自学了解原理外,只能在实际工作中,查看相关经验分享时遇到不懂的就积累下来,慢慢形成属于自己的系统化知识咯。
toast
Android 中的 Toast 是一种简易的消息提示框。
Toast 是一个包含用户点击消息。Toast 类会帮助你创建和显示这些。
当视图显示给用户,在应用程序中显示为浮动。和 Dialog 不一样的是,它永远不会获得焦点,无法被点击。用户将可能是在中间键入别的东西。Toast 类的思想就是尽可能不引人注意,同时还向用户显示信息,希望他们看到。而且Toast 显示的时间有限,Toast 会根据用户设置的显示时间后自动消失。
使用这个类的最简单的方法是调用静态方法构造您所需要的一切,并返回一个新的 Toast 对象。
使用需引入包:
import android.widget.Toast;
例子:
在当前的 activity 中,为某点击事件加入下列代码:
Toast.makeText(getApplicationContext ( ) , “你想提示的信息”, Toast.LENGTH_SHORT).show ( ) ;
则点击时会出现浮框提示。
activity
Activity 是Android 组件中最基本也是最为常见用的四大组件(Activity,Service 服务,Content Provider 内容提供者,BroadcastReceiver 广播接收器)之一。
Activity 是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务。
Activity 中所有操作都与用户密切相关,是一个负责与用户交互的组件,可以通过 setContentView ( View ) 来显示指定控件。
在一个 android 应用中,一个 Activity 通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity 之间通过 Intent 进行通信。
基本状态
在 android 中,Activity 拥有四种基本状态:
- Active/Runing
一个新 Activity 启动入栈后,它显示在屏幕最前端,处理是处于栈的最顶端( Activity 栈顶 ),此时它处于可见并可和用户交互的激活状态,叫做活动状态或者运行状态( active or running )。
- Paused
当 Activity 失去焦点, 被一个新的非全屏的 Activity 或者一个透明的 Activity 被放置在栈顶,此时的状态叫做暂停状态( Paused )。此时它依然与窗口管理器保持连接,Activity 依然保持活力(保持所有的状态,成员信息,和窗口管理器保持连接),但是在系统内存极端低下的时候将被强行终止掉。所以它仍然可见,但已经失去了焦点故不可与用户进行交互。
- Stoped
如果一个 Activity 被另外的 Activity 完全覆盖掉,叫做停止状态( Stopped )。它依然保持所有状态和成员信息,但是它不再可见,所以它的窗口被隐藏,当系统内存需要被用在其他地方的时候,Stopped 的 Activity 将被强行终止掉。
- Killed
如果一个 Activity 是 Paused 或者 Stopped 状态,系统可以将该 Activity 从内存中删除, Android 系统采用两种方式进行删除,要么要求该 Activity 结束,要么直接终止它的进程。当该 Activity 再次显示给用户时,它必须重新开始和重置前面的状态。
状态转换
当一个 Activity 实例被创建、销毁或者启动另外一个 Activity 时,它在这四种状态之间进行转换,这种转换的发生依赖于用户程序的动作。下图说明了 Activity 在不同状态间转换的时机和条件:图1. Activity 的状态转换
如上所示,Android 程序员可以决定一个 Activity 的“生”,但不能决定它的“死”,也就是说程序员可以启动一个 Activity ,但是却不能手动的“结束”一个 Activity 。当你调用 Activity.finish ( ) 方法时,结果和用户按下 BACK 键一样:告诉 Activity Manager 该 Activity 实例完成了相应的工作,可以被“回收”。随后 Activity Manager 激活处于栈第二层的 Activity 并重新入栈,同时原 Activity 被压入到栈的第二层,从 Active 状态转到 Paused 状态。例如:从 Activity1 中启动了 Activity2 ,则当前处于栈顶端的是 Activity2 ,第二层是 Activity1 ,当我们调用 Activity2.finish ( ) 方法时, Activity Manager 重新激活 Activity1 并入栈, Activity2 从 Active 状态转换 Stoped 状态, Activity1. onActivityResult(int requestCode, int resultCode, Intent data) 方法被执行, Activity2 返回的数据通过 data 参数返回给 Activity1 。
Activity 栈
Android 是通过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 总是在栈的顶端,当前台的 Activity 因为异常或其它原因被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原 Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不同状态间的转换。 Activity 的状态与它在栈中的位置关系如下图所示:
图2. Activity 的状态与它在栈中的位置关系
如上所示,除了最顶层即处在 Active 状态的 Activity 外,其它的 Activity 都有可能在系统内存不足时被回收,一个 Activity 的实例越是处在栈的底层,它被系统回收的可能性越大。系统负责管理栈中 Activity 的实例,它根据 Activity 所处的状态来改变其在栈中的位置。
方法通知
下面的图显示了 Activity 的重要状态转换,矩形框表明 Activity 在状态转换之间的回调接口,开发人员可以重载实现以便执行相关代码,带有颜色的椭圆形表明 Activity 所处的状态。
图3. Activity 的状态转换的方法和实现
在上图中, Activity 有三个关键的循环:
- 整个的生命周期,从 onCreate(Bundle) 开始到 onDestroy ( ) 结束。 Activity 在 onCreate ( ) 设置所有的“全局”状态,在 onDestory ( ) 释放所有的资源。例如:某个 Activity 有一个在后台运行的线程,用于从网络下载数据,则该 Activity 可以在 onCreate ( ) 中创建线程,在 onDestory ( ) 中停止线程。
- 可见的生命周期,从 onStart ( ) 开始到 onStop ( ) 结束。在这段时间,可以看到 Activity 在屏幕上,尽管有可能不在前台,不能和用户交互。在这两个接口之间,需要保持显示给用户的 UI 数据和资源等,例如:可以在 onStart 中注册一个 IntentReceiver 来监听数据变化导致 UI 的变动,当不再需要显示时候,可以在 onStop ( ) 中注销它。onStart ( ),onStop ( ) 都可以被多次调用,因为 Activity 随时可以在可见和隐藏之间转换。
- 前台的生命周期,从 onResume ( ) 开始到 onPause ( ) 结束。在这段时间里,该 Activity 处于所有 Activity 的最前面,和用户进行交互。 Activity 可以经常性地在 resumed 和 paused 状态之间切换,例如:当设备准备休眠时,当一个 Activity 处理结果被分发时,当一个新的 Intent 被分发时。所以在这些接口方法中的代码应该属于非常轻量级的。
百度了下相关的一些文章,感谢博主,这篇比较简明易懂 :
关于开端提到的,如何应对用户短时间内多次并快速点击控件的问题如下:
Q问题:
前提:一个按钮,点击就会有提示
操作:当用户在极短的时间内快速并多次点击 “按钮”时,提示语会一个接一个出现,给用户感觉比较诡异,此时的“提示语”该如何处理?
A回答总结如下:
- 从设计上避免用户犯错:在产品设计上避免短时间内快速,多次点击的情况出现,避免用户会犯错。
方法1:每次点击的时候出现一个阻隔式的提示,告诉他在加载或者处理中。
如:用户点击时,如果有不能立即响应的情况,提示它你正在做的事情,最好的就是按钮上正在处理。用户没有理由进行2次点击,点击没有响应也是正常。
方法2:减少 toast 提示语的使用
如果所有的 toast 反应时间都在你的忍受范围之外,程序员没办法把这个通信性能提高,而且页面又需要大量反馈,建议,提交数据成功的结果不用 toast 显示,顶部状态栏提交数据的状态转换就可以,只 toast 不成功反馈。
- 从程序上采用阻塞式控制
通过程序代码对按钮点击事件做出限制,如:1.5 秒或 2 秒内不再进行点击的响应。(timer 计时或线限计时都行)
从程序的角度出发,在做 Toast 显示时,以阻塞的方式进行显示可以实现,但是完全没必要,这个不是问题,不必纠结!如果点击该按钮的是进行下载操作,则一定要注意防止极快速的点击,否则会有问题产生(如用户快速的点击了两次下载,然后对第一次的进行取消,如果这里有向存储器进行写操作的话,可能会有 BUG 产生)。所以像这种场景时,这个按钮一定要进行阻塞式的控制(下载任务当然采用异步线程去做操作会更好,不会阻塞前台的 UI 线程,造成界面卡主的情况,具体可百度异步线程处理逻辑或者消息的使用)。
以上是来自早读课1群的聊天记录,由大卫整理分享的。大卫哥是技术出身且现任要出发产品总监。
另外百度看了些,嗯,从自己显浅的理解看,这篇通过修改间隔判断的实施起来貌似比较简便,至于技术上的更优判断,还是留待给专业的技术来研究,我只 mark 一下,遇到的时候可以提上两句。
戳 → 《Android:防止过快点击造成多次事件》