旋转设备时崩溃 - 生命周期问题

时间:2012-04-03 15:32:32

标签: android sqlite

我在之前的一个问题中被告知,如果设备在使用本地数据库时被旋转,我不需要维护数据库。

我认为我至少可以维护List的数据源。我在尝试这样做时遇到了问题,因为我收到错误,说没有在数据库上调用close()。我虽然在onDestroy上打电话。

谁能看到我在哪里错了?我只想通过在旋转设备后保持数据重新填充列表来改善用户体验。

令我困惑的另一件事是我的日志声明按以下顺序排列:

  • onCreate flight
  • 首次设置
  • 重用数据源
  • 销毁活动

我希望在重用数据源之前发生破坏活动。

package com.testing.flights;

import android.app.ListActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.util.Log;
import android.widget.SimpleCursorAdapter;

public class FlightListActivity extends ListActivity {

private SQLiteDatabase database;
private String fields[] = {BaseColumns._ID, "name", "flights", "distance"};
private SimpleCursorAdapter datasource;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v(ACTIVITY_SERVICE, "onCreate flights");

    datasource = (SimpleCursorAdapter) getLastNonConfigurationInstance();

    if (datasource == null) {
        database = getData();
        datasource = getCursor();
        Log.v(ACTIVITY_SERVICE, "first setup");
    }

    setListAdapter(datasource);
}

protected SQLiteDatabase getData() {
    DataBaseHelper myDbHelper = new DataBaseHelper(this.getApplicationContext());
    return myDbHelper.openDataBase();
}

protected CustomCursorAdapter getCursor() {
    Cursor data = database.query("pilots", fields, null, null, null, null, null);   
    final CustomCursorAdapter mysource = new CustomCursorAdapter(this, R.layout.row, data, fields, new int[] { R.id.id, R.id.name, R.id.flights, R.id.distance });
    return mysource;
}

@Override
public Object onRetainNonConfigurationInstance() {
    Log.v(ACTIVITY_SERVICE, "reusing datasource");
    final SimpleCursorAdapter myData = datasource;
    return myData;
}

@Override
protected void onDestroy() {
    Log.v(ACTIVITY_SERVICE, "destroying activity");
    database.close();
    super.onDestroy();
}

}

LogCat:

04-03 16:22:55.900: E/SQLiteDatabase(1860): close() was never explicitly called on database '/data/data/com.testing.flights/databases/club' 

3 个答案:

答案 0 :(得分:1)

我相信正在发生的事情是,操作系统正在优先创建新活动而不是破坏旧活动。因为不保证运行onDestroy(它可以被杀死),所以通常在onResume()中打开数据库,并在onPause()方法中自行清理。 (onPause不会被杀死,至少在蜂窝中+)。由于你现在拥有的,新活动正试图打开一个已经打开的数据库(我的猜测)。我没有试图保留这样的游标,我不是100%这将解决您的问题,但使用生命周期的那部分是非视图设置类型的正常情况。

答案 1 :(得分:0)

在FlightListActivity的表现文件中添加以下行

android:configChanges="keyboardHidden|orientation"  

现在尝试我认为应用程序不会崩溃,因为通过使用上面的设备从横向到纵向旋转,反之亦然,不会再次调用oncreate方法。

答案 2 :(得分:0)

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // TODO Auto-generated method stub

        super.onConfigurationChanged(newConfig);

          if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {

          } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {

          }

    }