【发布时间】:2015-01-06 16:34:10
【问题描述】:
我有一个小问题。
在我的应用程序中,用户成功登录后会启动一个服务。以前,如果应用程序被终止,服务需要停止。 (比如说,通过滑动从最近的应用程序列表中删除。)所以我们使用了android:stopWithTask="true"。现在我们需要服务按原样运行,即使启动它的任务已从最近的应用程序列表中删除。所以我将服务更改为包含android:stopWithTask="false"。但这似乎不起作用。
相关代码:
这里是与Service相关的manifest部分:
<service
android:enabled="true"
android:name=".MyService"
android:exported="false"
android:stopWithTask="false" />
在 MyService.java 中:
public class MyService extends AbstractService {
@Override
public void onStartService() {
Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification notification = new Notification(R.drawable.ic_launcher, "My network services", System.currentTimeMillis());
notification.setLatestEventInfo(this, "AppName", "Message", pendingIntent);
startForeground(MY_NOTIFICATION_ID, notification);
}
@Override
public void onTaskRemoved(Intent rootIntent) {
Toast.makeText(getApplicationContext(), "onTaskRemoved called", Toast.LENGTH_LONG).show();
System.out.println("onTaskRemoved called");
super.onTaskRemoved(rootIntent);
}
}
AbstractService.java 是扩展Sevrice 的自定义类:
public abstract class AbstractService extends Service {
protected final String TAG = this.getClass().getName();
@Override
public void onCreate() {
super.onCreate();
onStartService();
Log.i(TAG, "onCreate(): Service Started.");
}
@Override
public final int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStarCommand(): Received id " + startId + ": " + intent);
return START_STICKY; // run until explicitly stopped.
}
@Override
public final IBinder onBind(Intent intent) {
return m_messenger.getBinder();
}
@Override
public void onDestroy() {
super.onDestroy();
onStopService();
Log.i(TAG, "Service Stopped.");
}
public abstract void onStartService();
public abstract void onStopService();
public abstract void onReceiveMessage(Message msg);
@Override
public void onTaskRemoved(Intent rootIntent) {
Toast.makeText(getApplicationContext(), "AS onTaskRemoved called", Toast.LENGTH_LONG).show();
super.onTaskRemoved(rootIntent);
}
}
现在,如果我登录应用程序,MyService 就会启动。之后我按下主页按钮,所以应用程序被移到后台。现在我从最近的应用程序列表中删除该应用程序。那时,我应该看到 Toast 和控制台消息,按照这个方法的描述:
public void onTaskRemoved (Intent rootIntent)
在 API 级别 14 中添加
如果服务当前正在运行并且用户拥有 删除了来自服务应用程序的任务。如果你有 设置 ServiceInfo.FLAG_STOP_WITH_TASK 那么你将不会收到这个 打回来;相反,服务将被停止。
参数 rootIntent 原来的根 Intent 用于 启动要删除的任务。
但我没有看到任何这些。服务在onStartCommand 中返回START_STICKY,所以我认为onTaskRemoved 应该与标志android:stopWithTask="false" 一起被触发。
我错过了什么吗?
如果我需要添加一些可能对找出问题很重要的代码,请告诉我。
P.S.:到目前为止,我在 4.2.2 上对此进行了测试。
P.S.:我刚刚在 4.1.2 中测试了相同的代码,Service 在该代码上继续运行,并且我也在日志中收到“onTaskRemoved called”消息。
我应该怎么做才能在所有版本中都能正常工作?
【问题讨论】:
-
以防万一,您是如何启动此服务的?如果通过
bindService(),那么当客户端(例如Activity)解除绑定时Service会自动销毁,除非你也显式调用了startService()。 -
AFAIK,只有一种方法可以从其
onStopService()再次启动服务 -
@matiash 在其他版本中工作。可能是 Karbonn 或 4.2.2 中的问题,谢谢。 :)
-
谢谢你,我确实解决了你的问题,得到了线索:)