安卓:应用级别的暂停和恢复

16

我一直在尝试实现应用程序级别的暂停和恢复,类似于活动的onPause和onResume。我知道没有API具有此功能。

我尝试遵循这篇文章:http://curioustechizen.blogspot.com/2012/12/android-application-level-pause-and.html,但迄今为止我没有成功。

有人能够实现这一点吗?你使用了什么范式?

如果需要,让我知道是否需要将一些代码粘贴到此问题中。感谢帮助!


onPause和类似的方法有什么问题吗? - hichris123
1
它不存在于应用程序级别,而仅存在于活动中。 - TMacGyver
但是你不能只是在所有的活动中使用 onPause 并且拥有相同的代码吗? - hichris123
嘿,CuriousTechizen。你的博客文章写得非常好。我遇到的问题是服务方法没有被调用。我尽力按照你的帖子和类似的答案去做了,但可能出了点问题。我的安卓服务理解并不是很好。不过,我确实使用了另一个答案中的范例(使用计数器int)。我只是将其添加到应用程序子类中。它对我需要的目的有效。使用服务与计数器int相比有什么优势吗? - TMacGyver
我发布的库也使用了一个计数器 int(在一个应用程序子类中) :-) - curioustechizen
显示剩余4条评论
3个回答

7

解决该问题的另一个方法是跟踪每个活动的onStart()和onStop()调用次数。例如:

首先,创建一个类来保存计数:

public class ActiveActivitiesTracker {
    private static int sActiveActivities = 0;

    public static void activityStarted()
    {
        if( sActiveActivities == 0 )
        {
            // TODO: Here is presumably "application level" resume
        }
        sActiveActivities++;
    }

    public static void activityStopped()
    {
        sActiveActivities--;
        if( sActiveActivities == 0 )
        {
            // TODO: Here is presumably "application level" pause
        }
    }
}

然后在每个活动中,只需调用activityStarted()和activityStopped()方法:

@Override
public void onStart() {
    super.onStart();
    ActiveActivitiesTracker.activityStarted();
}

@Override
public void onStop() {
    super.onStop();
    ActiveActivitiesTracker.activityStopped();
}

5
也考虑使用registerActivityLifecycleCallbacks(this); - nutella_eater

5
我遇到了同样的问题。我的目标是,如果用户放弃使用应用程序,则锁定该应用程序。这看起来是一个简单的目标,但我认为很容易实现的所有解决方案都太复杂了。所以我想出了一个简单的解决方案:基于时间的锁定。
基本上它的工作原理如下:
  • 在onPause中开始倒计时以锁定应用程序
  • 在onResume中停止倒计时
  • 如果未及时调用onResume,则切换到锁定状态
因此,我创建了一个小类:
public class ApplicationLock {

private static final String TAG = ApplicationLock.class.getSimpleName();
private static final int LOCK_TIME = 1000; //lock after a second
private static boolean lock = true; //default is locked
private static Handler handler = new Handler();
private static Runnable runnable = new Runnable() {
    @Override
    public void run() {
        lock = true;
        Log.i("ActivityTracker", "App locked");
    }
};

public static boolean activityStarted()
{
    handler.removeCallbacks(runnable);
    if(lock)
    {
        Log.i(TAG, "App resumed - LOCKED");
        return true;
    }else{
        Log.i(TAG, "App resumed - NOT LOCKED");
        return false;
    }
}

public static void activityStopped()
{
    handler.postDelayed(runnable, LOCK_TIME);
    Log.i(TAG, "App paused - Starting countdown");

}

只需在您的活动onPause()中调用activityStopped(),并在onResume()中调用activityStarted()。检查activityStarted()的结果。如果返回true,请锁定您的应用程序。如果应用程序的方向发生变化,则会在onPause之后非常快地调用onResume,因此应用程序不会被锁定。

这种解决方案可能不适合每种情况,但在我的情况下,它是最好的解决方案。此外,您可以更改倒计时以增加用户体验(用户按错按钮并在几秒钟内返回应用程序,无需锁定应用程序)。希望这对其他人有用。


1
我曾在一个应用程序中做过与此非常相似的事情,该应用程序使用了一个提供GPS功能的服务来支持多个活动。其想法是只有当使用它的活动之一可见时,才有该服务,而当没有活动可见时则没有。在您的情况下,每个活动都将连接到一个服务,并通过连接到服务的onCreate()和onDestroy()方法来了解整个应用程序何时暂停或恢复。
以下是一个简化的示例:
所需组件(如果要重用它们,则可以将它们放入实用程序类中,或者我仅为每个活动类添加了它们):
private boolean mAppActiveServiceBound = false;
private AppActiveService mAppActiveService = null;
private ServiceConnection mAppActiveConnection = new ServiceConnection() {
    public void onServiceConnected( ComponentName className, IBinder service ) {
        mAppActiveService = ( (AppActiveService.AppActiveBinder) service ).getService();
    }
    public void onServiceDisconnected( ComponentName className ) {
        mAppActiveService = null;
    }
};

然后在每个活动的onStart()和onStop()方法中:

@Override
public void onStart() {
    super.onStart();
    mAppActiveServiceBound = bindService( new Intent( this, AppActiveService.class ), mAppActiveConnection, Context.BIND_AUTO_CREATE );
}

@Override
public void onStop() {
    super.onStop();
    if( mAppActiveServiceBound ) {
        unbindService( mAppActiveConnection );
        mAppActiveServiceBound = false;
    }
}

最后,服务本身:
public class  AppActiveService extends Service {
    // Receives interactions from clients:
    private final IBinder mBinder = new AppActiveBinder();

    /**
     * Provides a handle to the bound service.
     */
    public class  AppActiveBinder extends Binder {
        AppActiveService getService() {
            return AppActiveService.this;
        }
    }

    @Override
    public void onCreate(){
        // TODO: Here is presumably "application level" resume
    }

    @Override
    public void onDestroy(){
        // TODO: Here is presumably "application level" pause
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接