2

我有一个 Android 服务,它在该服务的成员变量中收集一些数据,这些数据偶尔(远非总是)变为 null。无论此服务在一系列 Android 设备上运行多长时间,我自己都无法生成此服务,因此我想知道是否有人在以下操作中看到任何错误(请注意,这是一个仅说明问题的精简示例):

public class CollectionService extends Service {
    private final CollectionServiceBinder binder = new CollectionServiceBinder();
    private PowerManager.WakeLock wakeLock;
    private UserData userData; // this is the object that sometimes becomes null

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        wakeLock = ((PowerManager) getSystemService(POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AppId");
    }

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

        if (wakeLock != null && wakeLock.isHeld()) {
            wakeLock.release();
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    public void startCollecting() {
        userData = new UserData();
        Notification notification = new Notification();
        // initializing notification variable

        startForeground(0xABCD, notification);

        // trigger logic that collects relevant data here, just imagine some Runnable that's triggered on a certain interval and adds data to the UserData value object.
    }

    public UserData finishCollecting() {
        try {
            userData.setFinishDate(new Date()); // throws NullPointerException every now and then.       return userData;
        } finally {
            if (wakeLock.isHeld()) {
                wakeLock.release();
            }
            stopForeground(true);
            userData = null;
        }
    }

    public boolean isCollecting() {
        return userData != null;
    }

    public class CollectionServiceBinder extends Binder {
        public CollectionService getService() {
            return CollectionService.this;
        }
    }
}

该服务是在使用...的活动中启动的

Intent i = new Intent(this, CollectionService.class);
getApplicationContext().startService(i);
getApplicationContext().bindService(i, serviceConnection, BIND_AUTO_CREATE); // just so the activity has a handle and can call startCollecting()/finishCollecting()

...并且在 onDestroy() 中使用 ...

getApplicationContext.unbindService(serviceConnection);

ServiceConnection 类如下所示:

public class MyServiceConnection implements ServiceConnection {
    private CollectionService service;

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder binder) {
        service = ((CollectionService.CollectionServiceBinder) binder).getService();
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        service = null;
    }

    public CollectionService getCollectionService() {
        return service;
    }
}

并且 startCollecting 在这样的 OnClickListener 中触发,以防止启动两次:

if (!serviceConnection.getCollectionService().isCollecting()) {
    serviceConnection.getCollectionService().startCollecting();
}    

我相信这一切都应该没问题,但有时 userData (如代码示例中所述)将为空。同样,这种情况很少发生(在 Google Play 上安装了 50.000 多个活动设备时,我在一年中刚刚收到 50 份报告,但我仍然希望每个人都能够享受该应用程序)。

有任何想法吗?

4

1 回答 1

1

我看不到你调用的地方startCollecting是相关的,因为那是你正在初始化的地方userData,但可能发生的是你的服务因任何原因被杀死然后重新启动。您需要做一些事情来根据需要或至少延迟加载来持久化/重新加载数据,userData以便它们重新开始。

您在这里没有所有代码,但还可能需要注意的是,您只在 onCreate 中获取了唤醒锁,但在finishCollecting. 如果您有可能调用startCollecting, finishCollecting,然后startCollecting再次调用相同的Service,您将在Service没有保持唤醒锁的情况下结束运行。

于 2013-02-21T00:30:54.977 回答