服务在真实设备上运行一段时间后停止运行(> 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 分钟)在模拟器上运行的主要内容,如果未能解决你的问题,请参考以下文章

应用程序暂停使用一段时间后,android服务停止工作

ios12后台定位服务停止

IOS:Firebase 电话身份验证在试飞中突然停止工作

一段时间后,adb 停止检测我的手机

java 如何让一个程序运行一段时间后就停止运行

java 如何让一个程序运行一段时间后就停止运行