服务在真实设备上运行一段时间后停止运行(> 40 分钟)在模拟器上运行
Posted
技术标签:
【中文标题】服务在真实设备上运行一段时间后停止运行(> 40 分钟)在模拟器上运行【英文标题】:Service stops running after a while on the real device ( > 40 minutes ) works on emulator 【发布时间】:2011-12-20 06:48:54 【问题描述】:朋友们,
我创建了一个每 2 分钟调用一次的 android 后台服务。当它被调用时,它开始监听 GPS 和 NETWORK 的 locationUpdates 40 秒。提取有用信息(纬度、经度、准确性、提供者……)并将数据发送到服务器。
当我在模拟器上运行应用程序时,它工作正常。 (嗯,我没有得到真正的 gps 信息,只是所有变量的默认值,但我知道我的服务每两分钟调用一次并将数据发送到服务器)
因此,当我在真实设备上运行该应用程序时,它可以完美运行大约 40 分钟。然后,我想,有些东西正在关闭我的服务。 (可能是由于内存消耗或其他原因导致的 android 本身)
有没有人知道我可以如何追踪错误,或者甚至可能是什么错误???
这里是我的一些代码:
private Runnable mUpdateTimeTask = new Runnable()
public void run()
Log.i(ctx.getString(R.string.app_name),
"HUJIDataCollectionService, mUpdateTimeTask1 start");
setuplistenerandrequestupdates();
mHandler.removeCallbacks(mUpdateTimeTask);
//! Log.i(ctx.getString(R.string.app_name),"HUJIDataCollectionService, mUpdateTimeTask stop");
;
private Runnable mUpdateTimeTask2 = new Runnable()
public void run()
Log.i(ctx.getString(R.string.app_name),"HUJIDataCollectionService, mUpdateTimeTask2 start");
// Send Data to Server here!!
sendDataToServer();
// Remove LocationUpdates here!!!
managerS.removeUpdates(listenerS);
mHandler.removeCallbacks(mUpdateTimeTask2);
//! Log.i(ctx.getString(R.string.app_name),"HUJIDataCollectionService, mUpdateTimeTask2 stop");
;
private TimerTask startServiceTask = new TimerTask()
@Override
public void run()
Log.i(ctx.getString(R.string.app_name),"HUJIDataCollectionService, startServiceTask, run()1");
// Start Locationupdates here!!!!
longitude = 0;
latitude = 0;
locationprovider = "";
locationproviderConverted = 0;
locationAccuracy = 100000;
// remove old updates from timer tasks
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.removeCallbacks(mUpdateTimeTask2);
mHandler.postDelayed(mUpdateTimeTask, 1000);
mHandler.postDelayed(mUpdateTimeTask2,
conf_LocationUpdatePeriodInSec * 1000);
;
@Override
public void onStart(Intent intent, int startId)
super.onStart(intent, startId);
//! Log.i(ctx.getString(R.string.app_name),"HUJIDataCollectionService, onStart");
ShowNotification();
LoadPreferences();
startDataCollectionServiceIntervallTimer = new Timer(
"HUJIDataCollectionServiceStartTimer");
startDataCollectionServiceIntervallTimer.schedule(startServiceTask,
1000L, conf_sampleTimeInMin * 60 * 1000L);
// Starting StopTimer(Thread) to stop listening for location updates
mHandler = new Handler();
private void setuplistenerandrequestupdates()
//! Log.i(ctx.getString(R.string.app_name),"HUJIDataCollectionService, setupListenerAndRequestUpdates");
managerS = (LocationManager) ctx
.getSystemService(Context.LOCATION_SERVICE);
//! Log.i(ctx.getString(R.string.app_name), "HUJIDataCollectionService, 1");
listenerS = new LocationListener()
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2)
@Override
public void onProviderEnabled(String arg0)
@Override
public void onProviderDisabled(String arg0)
@Override
public void onLocationChanged(Location location)
// storing data from the latest location update
float tempLocLongitude = (float) location.getLongitude();
float tempLocLatitude = (float) location.getLatitude();
float tempLocAccuracy = location.getAccuracy();
String tempLocProvider = location.getProvider();
//Log.i(ctx.getString(R.string.app_name),
// "HUJIDataCollectionService, setupListenerAndRequestUpdates, location Changed");
// if accuracy of new location is better than existing, store
// accuracy,latitude,longitude and location provider
if ((tempLocAccuracy < locationAccuracy)
&& (tempLocAccuracy != 0.0))
// store current latitude
latitude = tempLocLatitude;
// store current longitude
longitude = tempLocLongitude;
// store current provider
locationprovider = tempLocProvider;
// store current accuracy
locationAccuracy = (int) tempLocAccuracy;
// converts the String value of locationprovider to the
// required integer value for the server
convertLocationProvider();
;
非常感谢大家!!!
【问题讨论】:
没有日志不能说太多。 【参考方案1】:可能 Android 正在扼杀您的服务,因为您的服务寿命过长并在此过程中消耗了过多的资源。
如果您认为用户会高度评价您的应用(在编写您的应用时,如果他们让您的应用继续运行,他们的电池寿命将只有几个小时)请使用 startForeground()
向 Android 表明您的服务是前台用户体验的一部分。
就个人而言,我建议您重新考虑您的应用程序的工作方式,这样您就不会消耗太多电量。例如,每小时检查一次位置,使用AlarmManager
和类似于我的LocationPoller
的东西。这不仅会减少您保持 GPS 的频率和时间,而且还会在两次轮询之间使您的服务内存不足。
【讨论】:
Alarmmanager 到目前为止运行良好。 THX 的答案。 startForeground 让它变得更好。但还没有完全工作。手机闲置时出现一些问题... @Arnold:设备可能正在入睡。LocationPoller
使用自己的 WakeLock
来帮助确保不会发生这种情况。【参考方案2】:
您还应该使用:
@Override
public int onStartCommand(Intent intent, int flags, int startId)
// TODO Your code here or in onStart as you did...
return START_STICKY;
【讨论】:
除此之外,他的 onCreate 应该启动服务,这样当它被 android 框架重新创建时,它会自己启动。以上是关于服务在真实设备上运行一段时间后停止运行(> 40 分钟)在模拟器上运行的主要内容,如果未能解决你的问题,请参考以下文章