我试图写一个应用程序,做一些具体的时候,它被带回前台后一段时间。是否有一种方法可以检测应用程序是被发送到后台还是被带到前台?
当前回答
你可以使用:
onRestart ()
重新开始和重新开始的区别。
其他回答
这个解决方案呢
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()。
如果你的应用由多个活动和/或堆叠的活动组成,就像一个标签栏小部件,那么覆盖onPause()和onResume()将不起作用。例如,当启动一个新的活动,当前的活动将得到暂停之前,新的一个被创建。当完成一个活动(使用“后退”按钮)时,也同样适用。
我发现有两种方法似乎很有效。
第一个需要GET_TASKS权限,由一个简单的方法组成,通过比较包名来检查设备上运行最多的活动是否属于应用程序:
private boolean isApplicationBroughtToBackground() {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
return true;
}
}
return false;
}
这种方法是在Droid-Fu(现在称为Ignition)框架中发现的。
我自己实现的第二个方法不需要GET_TASKS权限,这很好。相反,它的实现有点复杂。
在MainApplication类中,有一个变量用于跟踪应用程序中正在运行的活动的数量。在onResume()中为每个活动增加变量,在onPause()中减少变量。
当正在运行的activity数量达到0时,如果满足以下条件,应用程序将被放入后台:
正在暂停的活动没有结束(使用了“后退”按钮)。这可以通过使用activity.isFinishing()方法来完成。 没有启动一个新活动(相同的包名)。你可以重写startActivity()方法来设置一个变量来指示这一点,然后在onPostResume()中重置它,这是创建/恢复活动时运行的最后一个方法。
当您可以检测到应用程序已经退出到后台时,当它被带回前台时也很容易检测到。
基于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);
}
}
您可以使用ProcessLifecycleOwner将生命周期观察者附加到它。
public class ForegroundLifecycleObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void onAppCreated() {
Timber.d("onAppCreated() called");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onAppStarted() {
Timber.d("onAppStarted() called");
}
@OnLifecycleEvent(Event.ON_RESUME)
public void onAppResumed() {
Timber.d("onAppResumed() called");
}
@OnLifecycleEvent(Event.ON_PAUSE)
public void onAppPaused() {
Timber.d("onAppPaused() called");
}
@OnLifecycleEvent(Event.ON_STOP)
public void onAppStopped() {
Timber.d("onAppStopped() called");
}
}
然后在你的Application类的onCreate()你调用这个:
ProcessLifecycleOwner.get().getLifecycle().addObserver(new ForegroundLifecycleObserver());
有了它,你将能够捕捉应用程序在后台运行时发生的ON_PAUSE和ON_STOP事件。
通过使用下面的代码,我能够得到我的应用程序的前台或后台状态。
更多关于它的工作细节,强文本点击这里
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Context context;
private Toast toast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
}
private void showToast(String message) {
//If toast is already showing cancel it
if (toast != null) {
toast.cancel();
}
toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
toast.show();
}
@Override
protected void onStart() {
super.onStart();
showToast("App In Foreground");
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
showToast("App In Background");
}
}
}
推荐文章
- 警告: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文件