我试图写一个应用程序,做一些具体的时候,它被带回前台后一段时间。是否有一种方法可以检测应用程序是被发送到后台还是被带到前台?
当前回答
这是我的解决方案https://github.com/doridori/AndroidUtils/blob/master/App/src/main/java/com/doridori/lib/app/ActivityCounter.java
基本上涉及到用计时器计算所有Activity的生命周期方法,以捕捉当前前台没有活动但应用程序(即在旋转)的情况
其他回答
这个解决方案呢
public class BaseActivity extends Activity
{
static String currentAct = "";
@Override
protected void onStart()
{
super.onStart();
if (currentAct.equals(""))
Toast.makeText(this, "Start", Toast.LENGTH_LONG).show();
currentAct = getLocalClassName();
}
@Override
protected void onStop()
{
super.onStop();
if (currentAct.equals(getLocalClassName()))
{
currentAct = "";
Toast.makeText(this, "Stop", Toast.LENGTH_LONG).show();
}
}
}
所有的Activity都需要扩展BaseActivity。
当一个活动调用另一个(A->B)时,currentAct不等于getLocalClassName(),因为第二个活动(B)的onStart()在第一个(A) (https://developer.android.com/guide/components/activities.html#CoordinatingActivities)的onStop()之前被调用。
当用户按下home键或应用程序之间的变化将只调用onStop(),然后currentAct等于getLocalClassName()。
编辑:新的体系结构组件带来了一些有希望的东西:ProcessLifecycleOwner,参见@vokilam的回答
实际解决方案根据谷歌I/O谈话:
class YourApplication : Application() {
override fun onCreate() {
super.onCreate()
registerActivityLifecycleCallbacks(AppLifecycleTracker())
}
}
class AppLifecycleTracker : Application.ActivityLifecycleCallbacks {
private var numStarted = 0
override fun onActivityStarted(activity: Activity?) {
if (numStarted == 0) {
// app went to foreground
}
numStarted++
}
override fun onActivityStopped(activity: Activity?) {
numStarted--
if (numStarted == 0) {
// app went to background
}
}
}
是的。我知道很难相信这个简单的解决方案有效,因为我们有这么多奇怪的解决方案。
但还是有希望的。
我们可以使用LiveData扩展这个解决方案:
class AppForegroundStateLiveData : LiveData<AppForegroundStateLiveData.State>() {
private var lifecycleListener: LifecycleObserver? = null
override fun onActive() {
super.onActive()
lifecycleListener = AppLifecycleListener().also {
ProcessLifecycleOwner.get().lifecycle.addObserver(it)
}
}
override fun onInactive() {
super.onInactive()
lifecycleListener?.let {
this.lifecycleListener = null
ProcessLifecycleOwner.get().lifecycle.removeObserver(it)
}
}
internal inner class AppLifecycleListener : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onMoveToForeground() {
value = State.FOREGROUND
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onMoveToBackground() {
value = State.BACKGROUND
}
}
enum class State {
FOREGROUND, BACKGROUND
}
}
现在我们可以订阅这个LiveData并捕获所需的事件。例如:
appForegroundStateLiveData.observeForever { state ->
when(state) {
AppForegroundStateLiveData.State.FOREGROUND -> { /* app move to foreground */ }
AppForegroundStateLiveData.State.BACKGROUND -> { /* app move to background */ }
}
}
在你的应用程序中添加回调并检查根活动,如下所示:
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if (activity.isTaskRoot() && !(activity instanceof YourSplashScreenActivity)) {
Log.e(YourApp.TAG, "Reload defaults on restoring from background.");
loadDefaults();
}
}
});
}
我所做的是确保所有应用程序内的活动启动startActivityForResult,然后检查onActivityResult是否在onResume之前被调用。如果不是,这意味着我们刚刚从应用程序之外的某个地方返回。
boolean onActivityResultCalledBeforeOnResume;
@Override
public void startActivity(Intent intent) {
startActivityForResult(intent, 0);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
onActivityResultCalledBeforeOnResume = true;
}
@Override
protected void onResume() {
super.onResume();
if (!onActivityResultCalledBeforeOnResume) {
// here, app was brought to foreground
}
onActivityResultCalledBeforeOnResume = false;
}
推荐文章
- 如何使梯度背景在android
- 列出一个Intent的所有附加项
- Android中使用的SQLite版本?
- 如何获得转轮价值?
- 在Wireshark上捕获手机流量
- 为开发设置设备(????????????)没有权限)
- 如何使用XML更改ActionBarActivity的ActionBar的背景颜色?
- 从Android模拟器访问localhost:端口
- Android应用程序中的“包”是什么
- 如何从代码中动态设置layout_weight属性?
- 更新列表后,滚动到列表的末尾
- Android Toast可以比Toast. length_long长吗?
- 如何从资源设置位图
- 是否有可能在线性布局的宽度上均匀分布按钮
- 我如何禁用方向改变在Android?