Jon*_*lis 51 service android process alarmmanager
我有一个定义为的服务:
public class SleepAccelerometerService extends Service implements SensorEventListener
Run Code Online (Sandbox Code Playgroud)
从本质上讲,我正在制作一个应用程序,可以在用户使用他或她的手机/设备睡在床上时,出于各种原因监控加速度计活动.这是一项长期服务,不得在夜间杀死.根据夜间有多少后台应用程序和定期进程,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}
Run Code Online (Sandbox Code Playgroud)
我不想强迫用户将"SleepActivity"或我的应用中的其他活动作为前景.我不能定期运行我的服务,因为它会不断拦截onSensorChanged.
有小费吗?源代码在这里:http://code.google.com/p/electricsleep/
Dav*_*ebb 72
对于Android 2.0或更高版本,您可以使用该startForeground()
方法在前台启动服务.
该文件说以下:
启动的服务可以使用
startForeground(int, Notification)
API将服务置于前台状态,其中系统认为它是用户主动意识到的东西,因此在内存不足时不是候选者.(从理论上讲,服务在当前前台应用程序的极端内存压力下被杀死仍然是可能的,但实际上这不应该是一个问题.)
主要用于当杀死服务对用户造成破坏时,例如,杀死音乐播放器服务将停止音乐播放.
您需要提供一个Notification
方法,该方法显示在Ongoing部分的Notifications Bar中.
小智 16
当您使用BIND_AUTO_CREATE将服务绑定到Activity时,您的服务将在您的活动被销毁和解除绑定后被杀死.它不依赖于你如何实现你的服务unBind方法它仍将被杀死.
另一种方法是使用Activity中的startService方法启动服务.这样即使您的Activity被销毁,您的服务也不会被销毁甚至暂停,但您必须在适当时使用stopSelf/stopService自行暂停/销毁它.
Flo*_*low 11
正如Dave已经指出的那样,你可以运行Service
前景优先级.但是这种做法只应在绝对必要时使用,即如果服务被Android杀死会导致糟糕的用户体验.这就是"前景"的真正含义:你的应用程序在某种程度上处于前台,如果它被杀死,用户会立即注意到它(例如因为它播放了一首歌或一段视频).
在大多数情况下,请求服务的前台优先级是反效果的!
这是为什么?当Android决定杀死a时Service
,它会这样做,因为它缺少资源(通常是RAM).基于不同的优先级类,Android决定终止哪些正在运行的进程以及此包含的服务以释放资源.这是一个您希望发生的健康过程,以便用户获得流畅的体验.如果您没有充分理由请求前台优先级,只是为了防止您的服务被杀,它很可能会导致糟糕的用户体验.或者,您能保证您的服务保持在最小的资源消耗范围内并且没有内存泄漏吗?1
Android提供了粘性服务来标记服务,如果它们被杀死,应该在一段宽限期后重新启动.这种重启通常在几秒钟内完成.
想要为Android编写XMPP客户端的图像.您是否应该为Service
包含XMPP连接的前台优先级请求?绝对没有,绝对没有理由这样做.但是您希望将其START_STICKY
用作服务onStartCommand
方法的返回标志.因此,当资源压力时您的服务会停止,并在情况恢复正常后重新启动.
1:我很确定很多Android应用都有内存泄漏.这是休闲(桌面)程序员不关心的东西.
我有类似的问题.在一些设备上一段时间后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);
}
Run Code Online (Sandbox Code Playgroud)
从看门狗定时器接收和处理意图:
/** 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
}
}
}
Run Code Online (Sandbox Code Playgroud)
实际上我使用WakefulBroadcastReceiver 而不是BroadcastReceiver.我给了你BroadcastReceiver的代码只是为了简化它.