我试图写一个应用程序,做一些具体的时候,它被带回前台后一段时间。是否有一种方法可以检测应用程序是被发送到后台还是被带到前台?
当前回答
我所做的是确保所有应用程序内的活动启动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;
}
其他回答
基于Martín marconcini的回答(谢谢!)我终于找到了一个可靠(而且非常简单)的解决方案。
public class ApplicationLifecycleHandler implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {
private static final String TAG = ApplicationLifecycleHandler.class.getSimpleName();
private static boolean isInBackground = false;
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
if(isInBackground){
Log.d(TAG, "app went to foreground");
isInBackground = false;
}
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
@Override
public void onConfigurationChanged(Configuration configuration) {
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(int i) {
if(i == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN){
Log.d(TAG, "app went to background");
isInBackground = true;
}
}
}
然后将其添加到Application类的onCreate()中
public class MyApp extends android.app.Application {
@Override
public void onCreate() {
super.onCreate();
ApplicationLifeCycleHandler handler = new ApplicationLifeCycleHandler();
registerActivityLifecycleCallbacks(handler);
registerComponentCallbacks(handler);
}
}
onPause()和onResume()方法在应用程序被带到后台并再次进入前台时被调用。但是,在应用程序第一次启动时和关闭之前也会调用它们。你可以在活动中阅读更多。
没有任何直接的方法来获得应用程序的状态,而在后台或前台,但即使我已经面临这个问题,并找到解决方案与onWindowFocusChanged和onStop。
更多细节请查看这里Android:解决方案检测当一个Android应用程序去后台,回到前台没有getRunningTasks或getRunningAppProcesses。
我喜欢ProcessLifecycleOwner方法,但实际上可以跳过所有这些,因为在Activity的onCreate()方法中,可以很容易地确定它是第一次运行还是后续运行:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
/* savedInstanceState is always null on first run */
} else {
/* it's a subsequent run */
}
}
正确答案
创建名为MyApp的类,如下所示:
public class MyApp implements Application.ActivityLifecycleCallbacks, ComponentCallbacks2 {
private Context context;
public void setContext(Context context)
{
this.context = context;
}
private boolean isInBackground = false;
@Override
public void onTrimMemory(final int level) {
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
isInBackground = true;
Log.d("status = ","we are out");
}
}
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
if(isInBackground){
isInBackground = false;
Log.d("status = ","we are in");
}
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
@Override
public void onConfigurationChanged(Configuration configuration) {
}
@Override
public void onLowMemory() {
}
}
然后,在你想要的任何地方(最好是在应用程序中启动的第一个活动),添加下面的代码:
MyApp myApp = new MyApp();
registerComponentCallbacks(myApp);
getApplication().registerActivityLifecycleCallbacks(myApp);
完成了!现在当应用程序在后台时,我们得到日志状态:我们退出 当我们进入app,我们得到log status,我们是out
这里有一个解决方案,通过使用deboning逻辑,确保我们不会得到连续的背景/前景事件。所以,它总是反映一种稳定的背景/前景状态。
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import java.util.Timer
import java.util.TimerTask
/**
* An observer class to listen on the app's lifecycle.
*/
class AppLifecycleObserver(
private val onAppGoesToBackground: () -> Unit = {},
private val onAppEntersForeground: () -> Unit = {}
) : LifecycleEventObserver {
private val debounce = DebouncingTimer(timeout = 10)
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
debounce.refresh {
when (event.targetState) {
Lifecycle.State.CREATED -> onAppGoesToBackground()
Lifecycle.State.RESUMED -> onAppEntersForeground()
else -> Unit
}
}
}
fun attach() {
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
fun detach() {
ProcessLifecycleOwner.get().lifecycle.removeObserver(this)
}
private class DebouncingTimer(private val timeout: Long) {
private var timer: Timer? = null
fun refresh(job: () -> Unit) {
timer?.cancel()
timer = Timer()
timer?.schedule(object : TimerTask() {
override fun run() = job.invoke()
}, timeout)
}
}
}
只需要创建一个AppLifecycleObserver实例:
private val appLifecycleObserver = AppLifecycleObserver(
onAppGoesToBackground = { // do whatever... },
onAppEntersForeground = { // do whatever... }
)
// Attach the observer when it is needed:
appLifecycleObserver.attach()
// Remove when there is no need to it:
appLifecycleObserver.detach()
不要忘记添加一个合适的依赖版本:
implementation("androidx.lifecycle:lifecycle-process:$lifecycle_version")
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件