我正在尝试为Android上的应用程序实现一些自动注销代码。
我需要检测属于某个应用程序的所有活动是否已进入后台,而不是为每个单独的活动使用onPause()
和onResume()
。 iOS有一个我可以使用的有用的applicationDidEnterBackground:
方法,但我无法在Android的Application
类中找到类似的功能。
一种方法似乎是拥有一个AtomicInteger
计数器,并在活动变得可见时递增它,并在它完成时递减它或调用onStop()。因此,如果计数器变为零,我可以启动在后台运行的服务并处理注销。这是通常的做法吗?
答案 0 :(得分:18)
此处没有全局回调,但对于每个活动,它都是onStop()。你不需要乱用原子int。只需要一个包含已启动活动数的全局int,在每个活动中增加onStart()并在onStop()中递减它。
答案 1 :(得分:14)
当“应用程序”在后台运行时,您真的不想注销用户,当用户切换到另一个选项卡或最小化浏览器窗口时,您不会注销Web应用程序的用户时刻。如果您要在Web应用程序中执行上述任一操作,您的用户会认为您的Web应用程序是史诗般的失败。同样,如果用户拨打的电话号码错误,或者闹钟响起,如果他们必须立即返回并在5秒前使用您的应用时登录,他们会对您感到非常恼火。 。在这里,“烦恼”,我指的是市场上的一星评级和讨厌的评论。
Web应用程序自动注销基于不活动,使用服务器会话cookie。
同样,当我构建一个安全的Android应用程序时,我将实现一个基于非活动的机制,可能是这样的:
步骤1:使用静态单例实例创建Session
类。 Session
对象保存最后访问的时间戳。
步骤2:在每个活动的onResume()
中,查看Session
单身是否存在。如果没有,这是一个全新的流程,因此如果这不是身份验证活动,请立即执行startActivity()
以启动身份验证活动。
步骤3:返回每个活动的onResume()
,如果Session
对象存在,请调用extend()
之类的内容。这将返回boolean
,true
,表示会话仍然良好(时间戳已更新至现在),否则为false
。如果它返回false
,请执行与Session
对象null
相同的内容。
步骤#4:成功时,您的身份验证活动会使用当前时间戳设置单个Session
对象。
第5步:您的Session
班级extend()
方法可以确定会话是否过长。
无论用户如何进入您的应用程序,如果会话太旧(或者这是一个全新的流程),他们将被迫进行身份验证。然而,如果用户短暂中断 - 您和/或用户可以“简要”定义 - 他们不必重新进行身份验证。
答案 2 :(得分:1)
我认为你的建议可能是最好的方法。不幸的是,我认为没有API调用来检测您的应用是否在后台。您只需要操作onPause()和onResume()方法。请记住,您需要考虑活动之间的转换,所以一旦您的AtomicInteger达到0,我会等待很短的时间并重新检查它仍然是0以确保它不仅仅是转换活动。
答案 3 :(得分:0)
创建一个Application类并包含在清单
中<application
android:name="com.example.hello.MyApplication"
public class MyApplication extends Application implements
ActivityLifecycleCallbacks, ComponentCallbacks2
覆盖以下方法
@Override
public void onTrimMemory(int level) {
// this method is called when the app goes in background.
// you can perform your logout service here
super.onTrimMemory(level);
}
这适用于API级别14及以上版本。
您甚至可以根据应用在后台的时间执行注销,我建议这是一个更好的选择。以下是您可以创建的&#34;会话超时&#34;
将SharedPreferences
方法中的时间戳保存在onTrimMemory(int level)
在你的所有活动上onStrat()从sharedPref获取时间戳并将其与当前时间进行比较。基于此,您可以执行注销。
并清除onCreat of MyApplication