While debugging one of my apps (one that sits in the background and
logs accelerometer data), I noticed that it would randomly and without
any prompt reset itself.  It would be running it's normal timer task
and suddenly it would stop, the create function would be called and
any running task would halt.  Here's the trace:

03-11 07:50:34.574: VERBOSE/AccelerLogService(29277):
0.088633,1.253072,1.103248,9.629586
03-11 07:50:34.584: VERBOSE/AccelerLogService(29277): History Size:
0.083333336
03-11 07:50:35.064: VERBOSE/AccelerLogService(29277):
0.096283,1.253072,1.035146,9.629586
03-11 07:50:35.084: VERBOSE/AccelerLogService(29277): History Size:
0.1
03-11 07:50:35.544: VERBOSE/AccelerLogService(29277):
0.104550,1.253072,1.007906,9.575105
03-11 07:50:36.044: VERBOSE/AccelerLogService(29277): History Size:
0.11666667
03-11 07:50:36.484: VERBOSE/AccelerLogService(29277):
0.120600,1.239452,1.035146,9.615966
03-11 07:50:37.024: VERBOSE/AccelerLogService(29277): History Size:
0.13333334
03-11 07:50:38.994: VERBOSE/AccelerLogService(29277):
0.136867,1.293933,1.035146,9.615966
03-11 07:50:39.014: VERBOSE/AccelerLogService(29277): History Size:
0.15
03-11 07:51:03.984: VERBOSE/AccelerLogService(29395): CREATED
03-11 07:52:41.624: VERBOSE/AccelerLogService(29502): CREATED

And here's the service code:

public class AccelerLogService extends Service implements
SensorEventListener {
        private static final String LOG_TAG = AccelerLogService.class
                        .getSimpleName();
        private static final String base_dir = "/sdcard/";
        private static WakeLock wl;

        private long startTime;
        private volatile float[] lastData;
        private static Queue<float[]> lastFiveMinutes;

        private static BufferedWriter br;
        private static Timer timer;
        private static TimerTask tt;
        float threshold = 0.0f;
        int interval;

        private boolean getAccelerometer() {
                SensorManager sensorMgr = (SensorManager)
getSystemService(SENSOR_SERVICE);
                List<Sensor> sensorList = sensorMgr
                                .getSensorList(Sensor.TYPE_ACCELEROMETER);
                boolean addedListener = sensorMgr.registerListener(
                                (SensorEventListener) this, sensorList.get(0),
                                SensorManager.SENSOR_DELAY_UI);
                if (addedListener)
                        Log.v(LOG_TAG, "Listener Added");
                else
                        Log.v(LOG_TAG, "Listener Not Added");
                return addedListener;
        }

        @Override
        public void onCreate() {
                super.onCreate();
                if (timer == null)
                        timer = new Timer();
                if (lastFiveMinutes == null)
                        lastFiveMinutes = new LinkedList<float[]>();
                Log.v(LOG_TAG, "CREATED");
        }

        @Override
        public void onStart(Intent intent, int startid) {
                super.onStart(intent, startid);
                Log.v(LOG_TAG, "STARTED");
                if (intent.getExtras().containsKey("ms")) {
                        interval = intent.getExtras().getInt("ms");
                } else {
                        interval = 5000;
                }
                startNewLog();
        }

        private String getFileName() {
                return base_dir + getHardwareID() + "_"
                                + String.valueOf(System.currentTimeMillis()) + 
".csv";
        }

        public String getHardwareID() {
                TelephonyManager tm = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
                return tm.getDeviceId();
        }

        private void startNewLog() {
                try {
                        if (getAccelerometer()) {
                                // acquire a partial wake lock
                                wl = ((PowerManager) 
getSystemService(Context.POWER_SERVICE))
                                                
.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                                                                
AccelerLogService.class.getPackage().getName());
                                wl.acquire();

                                br = new BufferedWriter(new OutputStreamWriter(
                                                new 
FileOutputStream(getFileName())));
                                br
                                                
.write("time(mins),X,Y,Z,varX(last 5 minutes),varY(last 5
minutes),varZ(last 5 minutes),magVar(last 5 minutes)\n");
                                startTime = System.currentTimeMillis();
                                tt = new TimerTask() {
                                        @Override
                                        public void run() {
                                                float x = 
lastData[SensorManager.DATA_X];
                                                float y = 
lastData[SensorManager.DATA_Y];
                                                float z = 
lastData[SensorManager.DATA_Z];
                                                boolean recordVar = false;
                                                float[] var = new float[3];
                                                int maxSize = 5 * 60 * 1000 / 
interval;
                                                if (lastFiveMinutes.size() >= 
maxSize) {
                                                        recordVar = true;
                                                        var = calcVar();
                                                        lastFiveMinutes.poll();

                                                }
                                                lastFiveMinutes.add(lastData);
                                                Log.v(LOG_TAG, "History Size: "
                                                                + ((float) 
(lastFiveMinutes.size() * interval))
                                                                / 60000.0f);
                                                float timeInMinutes = (float) 
(System
                                                                
.currentTimeMillis() - startTime)
                                                                / (60.0f * 
1000.0f);
                                                try {
                                                        if (recordVar) {
                                                                float mag = 
(float) Math.sqrt((double) (var[0]
                                                                                
* var[0] + var[1] * var[1] + var[2]
                                                                                
* var[2]));
                                                                String value = 
String.format(
                                                                                
"%f,%f,%f,%f,%f,%f,%f,%f\n",
                                                                                
timeInMinutes, x, y, z, var[0], var[1],
                                                                                
var[2], mag);
                                                                Log.v(LOG_TAG, 
value);
                                                                
br.append(value);
                                                                br.flush();
                                                        } else {
                                                                String value = 
String.format("%f,%f,%f,%f\n",
                                                                                
timeInMinutes, x, y, z);
                                                                Log.v(LOG_TAG, 
value);
                                                                
br.append(value);
                                                                br.flush();
                                                        }
                                                } catch (IOException e) {
                                                        e.printStackTrace();
                                                }
                                        }
                                };
                                timer.scheduleAtFixedRate(tt, 0, 1000);
                        }
                } catch (FileNotFoundException e1) {
                        Log.v(LOG_TAG, "UNABLE TO CREATE FILE!");
                        e1.printStackTrace();
                } catch (IOException e) {
                        Log.v(LOG_TAG, "UNABLE TO WRITE TO FILE!");
                        e.printStackTrace();
                }
        }

        public float[] calcVar() {
                float[] ret = new float[3];
                for (int i = 0; i < 3; i++) {
                        float sum = 0.0f;
                        for (float[] f : lastFiveMinutes) {
                                sum += f[i];
                        }
                        float mean = sum / (float) lastFiveMinutes.size();

                        float sum_squares = 0.0f;
                        for (float[] f : lastFiveMinutes) {
                                sum_squares += f[i] * f[i];
                        }
                        float avg_sum_square = sum_squares / (float)
lastFiveMinutes.size();

                        float diff = avg_sum_square - mean * mean;

                        if (diff > 0)
                                ret[i] = (float) Math.sqrt(diff);
                        else
                                ret[i] = 0;
                }
                return ret;
        }

        public void stopLog() {
                try {
                        if (timer != null)
                                timer.cancel();
                        if (br != null)
                                br.close();
                        if (wl != null)
                                wl.release();
                } catch (IOException e) {
                        e.printStackTrace();
                }
        }

        @Override
        public void onDestroy() {
                stopLog();
                super.onDestroy();
        }

        @Override
        public IBinder onBind(Intent arg0) {
                return null;
        }

        @Override
        public void onAccuracyChanged(Sensor arg0, int arg1) {
}
        @Override
        public void onSensorChanged(SensorEvent arg0) {
                lastData = arg0.values;
        }
}


All my Activity does is just pass it a polling interval.  Is there a
reason the dalvik would simply restart a service like this?  I have a
wake lock and I thought that was enough to keep it from getting kicked
out of memory.

Thanks in advance for any replies, I've just discovered that this is a
recurring bug in several of my programs :/.

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to