2012-04-03 67 views
2

在前面的问题中,我建议我不需要维护数据库,因为设备因使用本地数据库而旋转。旋转设备时发生崩溃 - 生命周期问题

我认为我至少可以维护我的列表的数据源。我在尝试执行此操作时遇到了问题,因为我收到错误,说没有在数据库上调用close()。尽管我在onDestroy中调用close。

任何人都可以看到我在哪里错了吗?我只想通过维护数据以在旋转设备后重新填充列表来改善用户体验。

是困惑我的另一件事是我的日志报表中按以下顺序出来:

  • 的onCreate航班
  • 第一设置
  • 重复使用的数据源
  • 破坏活性

我希望在重新使用数据源之前销毁活动发生。

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' 
+0

当你有任何错误总是发表您的logcat – 2012-04-03 15:34:48

+0

@Samir - 我已经添加了错误 – Neil 2012-04-03 15:36:47

+0

尼尔,看看官方Android开发者博客,有一个整体上张贴。 – 2012-04-03 15:42:49

回答

1

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

+0

您的回答促使我更多地关注生命周期以及如何正确地做事 – Neil 2012-04-03 17:13:55

0

在manifeast文件中添加以下行的FlightListActivity

android:configChanges="keyboardHidden|orientation" 

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

+0

虽然这确实奏效,但我读过的文档却说它应该作为最后的手段使用。 – Neil 2012-04-03 17:11:00

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) { 

      } 

    } 
+0

我决定通过正确使用生命周期方法来处理这个问题 – Neil 2012-04-03 17:11:45