这是 “必须收听Android活动” 系列文章的 第2部分 ,如果您是本文的新手,请确保在继续阅读本部分之前,您已阅读本系列文章的前面部分,否则请不要拨打电话but…但是可以…因为您知道…观看次数:p
第1部分:Android方式
因此,在第1部分中,我们实现了我们的目标。 AuthenticationActivity
完成工作后,将在调用活动的 onActivityResult
方法中 通知我们,该 方法将在其中执行命令。 但这很混乱。
- 使用Android Studio第1部分使用Firebase开发Android WebApp
- 加快Android应用开发速度的5条惊人技巧
- Android和Firebase(第1部分)
- 缩小apk大小-(4)减少资源大小
- Android SQLite数据库单元测试很容易
因此,现在让我们尝试以另一种方式解决此问题。 与其使用异步活动调用,不如让我们举起横幅并宣战!
介绍信号量。
如果您需要有关信号量及其工作原理的一些新知识,请查看 ericliu撰写的 这篇很棒的 文章 。
无论如何,让我们推出一些代码。
AuthenticationService.java
文件的 相关位 。 好的,让我们来总结一下代码。
首先,我们声明一个信号量,并将其许可数量设置为0对其进行初始化。这样做是为了确保线程第一次尝试获取许可时,它不能,并且必须等到有人释放时它。
现在,在我们的 doWithAuthentication()
方法中,我们首先检查用户是否已经通过身份验证(如果如此)。 我们执行命令并返回控制。
否则,我们 通过调用 getAuthenticated()
启动 AuthenticationActivity
,我们在 其中进行简单的意图并通过 startActivity()
方法 启动该活动 。
现在,乐趣开始了。
我们开始一个新的 Thread
。 在此线程 Runnable
,信号量尝试获取许可。 由于我们的信号量允许0许可,因此会阻止。 然后,当“活动”结束时,我们释放锁,以允许该线程继续进行。
现在,在我们的UI线程中,我们检查用户是否已通过身份验证。 如果是这样,我们执行命令。
那么,为什么要创建一个新线程仅执行UI线程中的所有操作呢?
这是因为Android不允许我们暂停它的主UI线程,因为它不应该这样做。
试想一下会发生什么,如果在等待通过身份验证时,老板打来的电话要求您加班,但由于UI被阻止,您将无法接听。 在无法联系到您时,他将其提供给同事,他去后不洗手,但每天早晨总是为您握手。 试想一下 那会是 多么的 可悲 。
因此,我们无法阻止主线程。 但是话又说回来,我们不能在任何其他线程上执行任何会影响UI的操作,而最有可能执行的命令将这样做。 因此,我们必须在主线程内执行命令。
但是等等,我们在任何地方都不会释放信号量吗? 不,所以让我们做吧。
AuthenticationActivity.java
文件的 相关位 。 因此,我们要做的就是释放 AuthenticationActivity
的 onDestroy()
方法中 的锁定,仅此 而已。
那么,为什么要使用信号量?
Java提供了许多实现同步的方法。 是什么使信号量如此出色?
信号量没有所有权的概念。 信号灯锁可由所有者以外的其他线程释放。 这使我们可以从UI线程释放由另一个线程获取的锁。
因此,无阻塞UI线程的独特Android约束使信号量非常有用。
但是,应该注意,其他一些并发方法(例如 CountdownLatch
工作,但是需要从开发人员的角度进行更多管理。
问题
线程锁定-有很多原因导致许多android生命周期是异步的。 其中最重要的是这个。 不使用线程实现比不使用线程实现容易得多 。 使用正确的访问说明符和设计,死锁应该不会出现,但是鉴于我们在这里实际上并没有进行任何类型的同步,因此我们可以不使用线程,而如果可以不引入导致死锁的代码,不是吗?
实现不是显而易见的-编写身份验证活动的任何人都不会知道,当活动被销毁时必须释放锁,而不必检查调用。 因此,如果有人忘记了这一点,我们的线程就会被阻塞,换句话说,
人类的牺牲,猫和狗在一起生活,歇斯底里! -幽灵破坏者。
因此,让我们找出第三种方法,我们将在 第3部分“监听者的复仇”中进行操作。