android (Service & PhoneStateListener) - 当应用程序被任务管理器、杀手或内存不足杀死时,服务确实重新启动但不工作

Posted

技术标签:

【中文标题】android (Service & PhoneStateListener) - 当应用程序被任务管理器、杀手或内存不足杀死时,服务确实重新启动但不工作【英文标题】:android (Service & PhoneStateListener) - service does restart but not working when app is killed by task manager, killer or shortage of memory 【发布时间】:2012-03-20 12:58:08 【问题描述】:

这是 onStartCommand()

@Override
public int onStartCommand(Intent intent, int flags, int startId) 
    // Notification creation code

    telMgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
    telMgr.listen(new PSL(), PhoneStateListener.LISTEN_CALL_STATE);

    return super.onStartCommand(intent, flags, startId);

和PhoneStateListener类(在服务类下)

public class PSL extends PhoneStateListener 
    public void onCallStateChanged(int state, String incomingNum) 
        switch(state) 
        case TelephonyManager.CALL_STATE_IDLE:
        case TelephonyManager.CALL_STATE_OFFHOOK:
            //Work1
            break;
        case TelephonyManager.CALL_STATE_RINGING:
            //Work2
            break;
        
    

它们都在同一个 .java 文件中

我在一个服务类上有这些代码。

当我从主要活动中调用startService() 时,它运行良好。 但是当我的应用程序被任务管理器、杀手或设备上的内存不足自动杀死时,服务会重新启动但无法正常工作。 当我进入设置 - 应用程序 - 运行时,它显示进程 1 和服务 1,在被杀之前/之后。但在被杀之后,内存份额变为 1/10。我已经尝试 startForeground() 不要被我的通知轻易杀死 - 它没有用。 (不显示任何通知) 并尝试返回 onStartCommand(): START_STICKY, START_REDELIVER_INTENT - 显示相同的结果有什么办法可以完全重启或让它不被杀死?

【问题讨论】:

【参考方案1】:

花了几个小时后,我发现,对于 android 2.0 或更高版本,您可以使用 startForeground() 方法在前台启动您的服务。 Documentation provided by Android

已启动的服务可以使用 startForeground(int, Notification) API 将服务置于前台状态,系统认为它是用户主动意识到的,因此在内存不足时不适合杀死. (理论上,在当前前台应用程序的极端内存压力下,服务仍然可能被杀死,但实际上这不应该是一个问题。) 前台服务被操作系统杀死的机会非常少。但它工作正常。

public class ServicePhoneState extends Service 

@Override
public int onStartCommand(Intent intent, int flags, int startId) 

    Intent notificationIntent = new Intent(this, MainActivity.class);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    Notification notification = new NotificationCompat.Builder(this)
            .setContentTitle("Music Player")
           .setTicker("Google Music Player")
           .setContentText("My Music")
            .setSmallIcon(R.drawable.ic_bg_icon)
            .setPriority(Notification.PRIORITY_MAX)
            .setContentIntent(pendingIntent)
            .setOngoing(false)
            .build();
    startForeground(10, notification);
    return START_NOT_STICKY;

@Override
public void onDestroy() 
    super.onDestroy();
    stopForeground(true);

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

【讨论】:

【参考方案2】:

我通过 startForeground() 解决了它

它不起作用,因为我没有在通知上使用Notification.FLAG_FOREGROUND_SERVICE

【讨论】:

【参考方案3】:

花了几个小时后,我发现,对于 Android 2.0 或更高版本,您可以使用 startForeground() 方法在前台启动您的服务。 Documentation provided by Android

已启动的服务可以使用 startForeground(int, Notification) API 将服务置于前台状态,系统认为它是用户主动意识到的,因此不会在内存不足时被终止. (理论上,在当前前台应用程序的极端内存压力下服务仍然可能被杀死,但实际上这不应该是一个问题。)前台服务被操作系统杀死的机会非常罕见。但它工作正常.

public class ServicePhoneState extends Service 

@Override
public int onStartCommand(Intent intent, int flags, int startId) 

MyPhoneStateListener phoneListener = new 
MyPhoneStateListener(ServicePhoneState.this);
    TelephonyManager telephony = (TelephonyManager) 
    getSystemService(Context.TELEPHONY_SERVICE);
    telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);

Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
        .setContentTitle("Music Player")
       .setTicker("Google Music Player")
       .setContentText("My Music")
        .setSmallIcon(R.drawable.ic_bg_icon)
        .setPriority(Notification.PRIORITY_MAX)
        .setContentIntent(pendingIntent)
        .setOngoing(false)
        .build();
startForeground(10, notification);
return START_NOT_STICKY;
  @Override
public void onDestroy() 
super.onDestroy();
stopForeground(true);

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

【讨论】:

以上是关于android (Service & PhoneStateListener) - 当应用程序被任务管理器、杀手或内存不足杀死时,服务确实重新启动但不工作的主要内容,如果未能解决你的问题,请参考以下文章

android (Service & PhoneStateListener) - 当应用程序被任务管理器、杀手或内存不足杀死时,服务确实重新启动但不工作

Android:远程服务Service(含AIDL & IPC讲解)

Android:远程服务Service(含AIDL & IPC讲解)

Android Speech Recognition as a service on Android 4.1 & 4.2

71.sscanf数据挖掘

ph解码jsonp数据