代码之家  ›  专栏  ›  技术社区  ›  Jon Willis

Android:保持后台服务活动(防止进程死亡)

  •  51
  • Jon Willis  · 技术社区  · 16 年前

    public class SleepAccelerometerService extends Service implements SensorEventListener
    

    从本质上说,我正在制作一个应用程序,当用户在床上用手机/设备睡觉时,出于各种原因监控加速计的活动。这是一个长期运行的服务,不能在夜间被杀死。android有时会关闭我的进程,从而终止我的服务,这取决于晚上有多少后台应用程序和周期性进程。例子:

    10-04 03:27:41.673: INFO/ActivityManager(1269): Process com.androsz.electricsleep (pid 16223) has died.
    10-04 03:27:41.681: INFO/WindowManager(1269): WIN DEATH: Window{45509f98 com.androsz.electricsleep/com.androsz.electricsleep.ui.SleepActivity paused=false}
    

    有什么建议吗?源代码如下: http://code.google.com/p/electricsleep/

    7 回复  |  直到 10 年前
        1
  •  72
  •   David Webb    16 年前

    对于Android 2.0或更高版本,您可以使用 startForeground() method 在前台启动服务。

    这个 documentation says the following

    已启动的服务可以使用 startForeground(int, Notification)

    主要用于终止服务会对用户造成破坏的情况,例如,终止音乐播放器服务会停止音乐播放。

    你需要提供一个 Notification 显示在“正在进行”部分的通知栏中的方法。

        2
  •  16
  •   Witold Graca    15 年前

    当您使用bind\ u AUTO\ u CREATE将服务绑定到活动时,您的服务将在活动被销毁和解除绑定之后被终止。它并不取决于你如何实现你的服务解除绑定方法,它仍然会被杀死。

    另一种方法是从活动中使用startService方法启动服务。这样即使您的活动被销毁,您的服务也不会被销毁甚至暂停,但您必须在适当的时候使用stopSelf/stopService自行暂停/销毁它。

        3
  •  12
  •   Flow Matt McDonald    9 年前

    Dave already pointed out ,您可以运行 Service 前台优先。但这种做法应该只在绝对必要的时候才使用,也就是说,如果服务被Android扼杀,就会造成糟糕的用户体验。这就是“前台”的真正含义:你的应用程序不知何故在前台,如果它被杀死,用户会立即注意到它(例如,因为它播放了一首歌或一段视频)。

    在大多数情况下,为您的服务请求前台优先级会适得其反!

    为什么?当安卓决定杀死一个 ,因为它缺少资源(通常是RAM)。基于不同的优先级等级,Android决定终止哪些正在运行的进程,包括服务,以便释放资源。这是一个健康的过程,你希望发生这样的用户有一个平稳的体验。如果您请求前台优先级,而没有一个好的理由,只是为了防止您的服务被终止,那么它很可能会导致糟糕的用户体验。或者,您能保证您的服务保持在最小的资源消耗范围内,并且没有内存泄漏吗?

    sticky services

    服务 哪个包含XMPP连接?绝对没有,绝对没有理由这么做。但是你想用 START_STICKY 作为您服务的返回标志 onStartCommand 方法。这样,当资源紧张时,您的服务就会停止,一旦情况恢复正常,服务就会重新启动。

    1

        4
  •  5
  •   ivan    11 年前

    我也有类似的问题。在一些设备上,一段时间后,Android终止了我的服务,甚至 startForeground() 没有帮助。我的客户不喜欢这个问题。我的解决办法是 AlarmManager AlarmManager 创建一种看门狗计时器。它会不时检查服务是否应该运行并重新启动。 我也用 SharedPreferences 保留服务是否应运行的标志。

    创建/取消我的看门狗计时器:

    void setServiceWatchdogTimer(boolean set, int timeout)
    {
        Intent intent;
        PendingIntent alarmIntent;
        intent = new Intent(); // forms and creates appropriate Intent and pass it to AlarmManager
        intent.setAction(ACTION_WATCHDOG_OF_SERVICE);
        intent.setClass(this, WatchDogServiceReceiver.class);
        alarmIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager am=(AlarmManager)getSystemService(Context.ALARM_SERVICE);
        if(set)
            am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, alarmIntent);
        else
            am.cancel(alarmIntent);
    }
    

    从看门狗定时器接收和处理意图:

    /** this class processes the intent and
     *  checks whether the service should be running
     */
    public static class WatchDogServiceReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
    
            if(intent.getAction().equals(ACTION_WATCHDOG_OF_SERVICE))
            {
                // check your flag and 
                // restart your service if it's necessary
                setServiceWatchdogTimer(true, 60000*5); // restart the watchdogtimer
            }
        }
    }
    

    我确实用过 WakefulBroadcastReceiver BroadcastReceiver . 我给你广播接收器的代码只是为了简化它。

        5
  •  4
  •   18446744073709551615    12 年前

    http://developer.android.com/reference/android/content/Context.html#BIND_ABOVE_CLIENT

    在客户端上绑定 --加入 API 14级

    的标志 bindService(Intent, ServiceConnection, int) :表示绑定到此服务的客户端应用程序认为服务比应用程序本身更重要。设置后,平台将尝试让内存不足杀手在终止应用程序绑定的服务之前终止应用程序,尽管这种情况不能保证。

    同一组的其他标志有:BIND\u ADJUST\u WITH\u ACTIVITY、BIND\u AUTO\u CREATE、BIND\u IMPORTANT、BIND\u NOT\u fromment、BIND\u facide\u PRIORITY。

    注意,在ICS中BIND\u AUTO\u CREATE的含义已经改变,并且 未指定 BIND_AUTO_CREATE BIND_WAIVE_PRIORITY 和 BIND_ADJUST_WITH_ACTIVITY 准备好了。

        6
  •  2
  •   BeRecursive    16 年前

        7
  •  2
  •   Irfan Ul Haq    10 年前

    我正在开发一个应用程序,面临着一个问题,即通过应用程序kill来终止我的服务。我在google上做了研究,发现我必须让它成为前景。代码如下:

    public class UpdateLocationAndPrayerTimes extends Service {
    
     Context context;
    @Override
    public void onCreate() {
        super.onCreate();
        context = this;
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    
        StartForground();
        return START_STICKY;
    }
    
    @Override
    public void onDestroy() {
    
    
        super.onDestroy();
    }
    
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    
    
    private void StartForground() {
        LocationChangeDetector locationChangeDetector = new LocationChangeDetector(context);
        locationChangeDetector.getLatAndLong();
        Notification notification = new NotificationCompat.Builder(this)
                .setOngoing(false)
                .setSmallIcon(android.R.color.transparent)
    
                //.setSmallIcon(R.drawable.picture)
                .build();
        startForeground(101,  notification);
    
        }
    }
    

    希望它能有所帮助!!!!