当通过在android中刷卡杀死应用程序时,如何处理代码?


104

如果我的应用程序正在运行并且按了主页按钮,则该应用程序将在后台运行。现在,如果长按主屏幕按钮并通过从最近的应用程序列表中滑动该应用程序来终止该应用程序,则不会发生像或那样的事件onPause(),而是终止该过程。因此,如果我希望我的服务停止,终止通知并取消注册侦听器,该怎么办?我读了很多文章和博客,但没有得到任何有用的信息,也没有找到任何有关它的文档。任何帮助,将不胜感激。提前致谢。onStop()onDestroy()


我解决了我的问题。检查
MysticMagicϡ

@MysticMagic适用于服务,取消通知和注销侦听器该怎么办?
CodeWarrior 2014年

您可以在onTaskRemoved中取消注册侦听器。不能吗 而同为取消通知
MysticMagicϡ

@MysticMagicϡ如果我想在应用程序更新上做同样的事情怎么办?
reji

Answers:


149

我刚刚解决了类似的问题。

如果只是通过从“最近使用的应用程序”列表中刷杀应用程序而停止服务,这就是您可以采取的措施。

里面你的清单文件,守旗stopWithTasktrue维修。喜欢:

<service
    android:name="com.myapp.MyService"
    android:stopWithTask="true" />

但是正如您说的那样,您想注销注册侦听器并停止通知等,我建议使用这种方法:

  1. 里面你的清单文件,守旗stopWithTaskfalse维修。喜欢:

    <service
        android:name="com.myapp.MyService"
        android:stopWithTask="false" />
    
  2. 现在在您的MyService服务中,重写method onTaskRemoved。(仅当stopWithTask设置为时才会触发false)。

    public void onTaskRemoved(Intent rootIntent) {
    
        //unregister listeners
        //do any other cleanup if required
    
        //stop service
        stopSelf();  
    }
    

请参阅我的问题以获取更多详细信息,它也包含代码的其他部分。

希望这可以帮助。


谢谢。考虑是否可以使用此方法来识别刷杀。简单的空白服务?
Kiran 2014年

是的@Kiran您可以尝试。:)
MysticMagicϡ

1
@MysticMagicϡ嗨,一个问题,我尝试使用您的解决方案,但似乎长时间的操作(如将数据发送到服务器,将分析数据发送到google等)有时无法完全通过。难道是在该方法有机会完全完成其自身之前杀死了该过程?您还尝试过在华为设备上使用此方法吗?似乎从未在这些设备上调用过onTaskRemoved。有什么想法吗?
Alon Minski '16

2
@MysticMagicϡ公共无效onTaskRemoved(..)方法不是在Android的O.在Android中澳工作的罚款在其他操作系统,但得到的问题致电
杰伊帕特尔

2
由于后台服务限制,此代码不适用于AndroidO。有什么方法可以在所有Android设备中处理此问题吗?
Aanal Mehta

33

找到了一种方法

像这样提供一项服务

public class OnClearFromRecentService extends Service {

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d("ClearFromRecentService", "Service Started");
    return START_NOT_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.d("ClearFromRecentService", "Service Destroyed");
}

@Override
public void onTaskRemoved(Intent rootIntent) {
    Log.e("ClearFromRecentService", "END");
    //Code here
    stopSelf();
}

}

2)在manifest.xml中注册此服务

<service android:name="com.example.OnClearFromRecentService" android:stopWithTask="false" />

3)然后在您的启动活动中启动此服务

startService(new Intent(getBaseContext(), OnClearFromRecentService.class));

现在,只要您最近从android清除应用程序,此方法onTaskRemoved()就会执行。


1
从此答案中一对一复制并粘贴:stackoverflow.com/questions/21040339
Flot2011

17

我解决了类似的问题。如果您想从最近的任务中刷过并在下次启动时表现正常,请按照以下步骤操作:-

1)在共享首选项中保存进程ID:

SharedPreferencesUtils.getInstance().putInt(SharedPreferencesUtils.APP_PROCESS_ID, android.os.Process.myPid());

2)从最近的任务清除后从启动器启动应用程序时,请执行以下操作:

int previousProcessID = mSharedPreferencesUtils.getInt(SharedPreferencesUtils.APP_PROCESS_ID);

int currentProcessID = android.os.Process.myPid();

if ((previousProcessID == currentProcessID)) {
    // This ensures application not killed yet either by clearing recent or anyway
} else {
    // This ensures application killed either by clearing recent or by anyother means
}

已确认-在不带service.onTaskRemoved()的Android 8上使用-做得很好
Gal Rom '18

4
此解决方案仅检测应用程序是否已重启,但您无法检测到该应用程序被
终止

6

当您按下主屏幕时- onPause并且onStop您的Activity被调用,因此此时您必须进行所有保存和清理操作,因为Android平台无法进一步保证onDestroy会调用该方法或任何其他生命周期方法,因此该过程可能会被终止没有任何通知。


12
感谢您的建议,但我不想杀死我的通知,服务和听众,就onPause()onstop()他们只需要在用户退出应用程序,即注销被杀害。
CodeWarrior 2013年

1

开启时,您需要保存数据onPause()。看一下这个生命周期图: Android Developer

您可以看到某个应用可以在onPause()或之后被杀死onStop()

在此处处理您的数据,然后将其恢复到onRestart()\中onCreate()

祝好运!


1

您无法处理滑动,因为系统只是从内存中删除您的进程而没有调用任何回调。

我已经检查过,在用户调用“最近的应用程序”屏幕之前,将始终调用onPause()。因此,您需要将所有数据保存在onPause方法中,而无需检查isFinishing()。

要检查后退按钮,请使用onBackPressed方法。


1
我相信这是所有Android版本的唯一安全方法。
塞尔吉奥

@Sergio是的,这是最安全的方法,我在大规模应用程序中对其进行了测试。
艾哈迈德(Ahmad)

1

如果目标是在用户通过滑动而不是通过按“停止”或按钮执行意外退出时释放某些资源(也许是在网络上其他地方运行的系统),则ViewModel.onCleared()可能会很有用。[这是我最初提出这个问题的方式]。

应用程序没有收到通知,Activity.onDestroy()被要求进行配置更改(例如方向更改),因此答案不存在。但是,当滑动应用程序时(以及用户退出活动时),将调用ViewModel.onCleared。如果要使用的资源与堆栈中的多个活动相关联,则可以添加引用计数或其他某种机制来确定ViewModel.onClear是否应释放该资源。

这是使用ViewModel的许多很好的理由中的另一个。

-鲍勃


1

我真的不知道为什么即使我将上述方法设置android:stopWithTask="false"onTaskRemoved()未调用,上述方法也无法解决我的问题。

另一个好的方法是使用AndroidViewModel。当用户按下返回按钮退出应用程序时,这一功能甚至可以解决。

只需将ViewModel类绑定到您,MainActivity然后执行任务onCleared()回调即可。

例:

public class MainViewModel extends AndroidViewModel {
    public MainViewModel(@NonNull Application application) {
        super(application);
    }

    @Override
    protected void onCleared() {
        // Do your task here
        Log.e("MainViewModel", "OnCleared mainViewModel");
        super.onCleared();
    }
}

然后将其绑定到您的MainActivity:

MainViewModel viewModel = new ViewModelProvider(this).get(MainViewModel.class);

〜瞧!


如其他评论者所述,由于Android O及更高版本,它可能无法使用服务方法。这似乎是使用视图模型的有趣解决方案。如果应用程序被强制终止(在应用程序切换器屏幕上滑动),这是否仍会触发?编辑:鲍勃的答案表明它确实适用于这些情况
威廉·里德

是的,它确实有效,我遇到的就是这种情况
droidhs

0

这为我在android 6,7,8,9上工作。

像这样进行一项服务:

 public class OnClearFromRecentService extends Service {

 @Override public IBinder onBind(Intent intent) {
     return null; }

 @Override public int onStartCommand(Intent intent, int flags, int
 startId) {
     Log.d("ClearFromRecentService", "Service Started");
     return START_NOT_STICKY; }

 @Override public void onDestroy() {
     super.onDestroy();
     Log.d("ClearFromRecentService", "Service Destroyed"); }

 @Override public void onTaskRemoved(Intent rootIntent) {
     Log.e("ClearFromRecentService", "END");
     //Code here
     stopSelf(); } }

2)在manifest.xml以下位置注册此服务:

<service android:name="com.example.OnClearFromRecentService"
 android:stopWithTask="false" />

3)然后在您的启动活动中启动此服务

 startService(new Intent(getBaseContext(),
 OnClearFromRecentService.class));

1
为何您的服务将继续在Android 8及更高版本上运行?您意识到Android 8之后的Started Services受到限制,对吧?
rahil008

0

正如鲍勃·克拉姆(Bob Cram)在回答中提到的那样,View Model的onCleared()方法就是答案。它在两种情况下都有效:

  1. 当用户通过从后台滑动应用程序删除该应用程序时。
  2. 当用户使用清除列表按钮清除所有应用程序时。

当用户从后台滑动应用程序时,该服务的onTaskRemoved()将起作用,但是当使用“全部杀死”按钮清除该应用程序时,该服务将不起作用。

但是viewModel的onCleared()方法在两种情况下均有效。您可以使用是否停止远程服务器中的任何正在进行的进程或清除任何任务。

 override fun onCleared() {
        super.onCleared()
        Log.d(TAG , "App Killed")
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.