如果我的应用程序正在运行并且按了主页按钮,则该应用程序将在后台运行。现在,如果长按主屏幕按钮并通过从最近的应用程序列表中滑动该应用程序来终止该应用程序,则不会发生像或那样的事件onPause(),而是终止该过程。因此,如果我希望我的服务停止,终止通知并取消注册侦听器,该怎么办?我读了很多文章和博客,但没有得到任何有用的信息,也没有找到任何有关它的文档。任何帮助,将不胜感激。提前致谢。onStop()onDestroy()
如果我的应用程序正在运行并且按了主页按钮,则该应用程序将在后台运行。现在,如果长按主屏幕按钮并通过从最近的应用程序列表中滑动该应用程序来终止该应用程序,则不会发生像或那样的事件onPause(),而是终止该过程。因此,如果我希望我的服务停止,终止通知并取消注册侦听器,该怎么办?我读了很多文章和博客,但没有得到任何有用的信息,也没有找到任何有关它的文档。任何帮助,将不胜感激。提前致谢。onStop()onDestroy()
Answers:
我刚刚解决了类似的问题。
如果只是通过从“最近使用的应用程序”列表中刷杀应用程序而停止服务,这就是您可以采取的措施。
里面你的清单文件,守旗stopWithTask的true维修。喜欢:
<service
android:name="com.myapp.MyService"
android:stopWithTask="true" />
但是正如您说的那样,您想注销注册侦听器并停止通知等,我建议使用这种方法:
里面你的清单文件,守旗stopWithTask的false维修。喜欢:
<service
android:name="com.myapp.MyService"
android:stopWithTask="false" />
现在在您的MyService服务中,重写method onTaskRemoved。(仅当stopWithTask设置为时才会触发false)。
public void onTaskRemoved(Intent rootIntent) {
//unregister listeners
//do any other cleanup if required
//stop service
stopSelf();
}
请参阅我的问题以获取更多详细信息,它也包含代码的其他部分。
希望这可以帮助。
找到了一种方法
像这样提供一项服务
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)在共享首选项中保存进程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
}
当您按下主屏幕时- onPause并且onStop您的Activity被调用,因此此时您必须进行所有保存和清理操作,因为Android平台无法进一步保证onDestroy会调用该方法或任何其他生命周期方法,因此该过程可能会被终止没有任何通知。
onPause()和onstop()他们只需要在用户退出应用程序,即注销被杀害。
开启时,您需要保存数据onPause()。看一下这个生命周期图:
Android Developer
您可以看到某个应用可以在onPause()或之后被杀死onStop()。
在此处处理您的数据,然后将其恢复到onRestart()\中onCreate()。
祝好运!
您无法处理滑动,因为系统只是从内存中删除您的进程而没有调用任何回调。
我已经检查过,在用户调用“最近的应用程序”屏幕之前,将始终调用onPause()。因此,您需要将所有数据保存在onPause方法中,而无需检查isFinishing()。
要检查后退按钮,请使用onBackPressed方法。
如果目标是在用户通过滑动而不是通过按“停止”或按钮执行意外退出时释放某些资源(也许是在网络上其他地方运行的系统),则ViewModel.onCleared()可能会很有用。[这是我最初提出这个问题的方式]。
应用程序没有收到通知,Activity.onDestroy()被要求进行配置更改(例如方向更改),因此答案不存在。但是,当滑动应用程序时(以及用户退出活动时),将调用ViewModel.onCleared。如果要使用的资源与堆栈中的多个活动相关联,则可以添加引用计数或其他某种机制来确定ViewModel.onClear是否应释放该资源。
这是使用ViewModel的许多很好的理由中的另一个。
-鲍勃
我真的不知道为什么即使我将上述方法设置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 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));
正如鲍勃·克拉姆(Bob Cram)在回答中提到的那样,View Model的onCleared()方法就是答案。它在两种情况下都有效:
当用户从后台滑动应用程序时,该服务的onTaskRemoved()将起作用,但是当使用“全部杀死”按钮清除该应用程序时,该服务将不起作用。
但是viewModel的onCleared()方法在两种情况下均有效。您可以使用是否停止远程服务器中的任何正在进行的进程或清除任何任务。
override fun onCleared() {
super.onCleared()
Log.d(TAG , "App Killed")
}