【问题标题】:Populate a RecyclerView using SQLiteAssetHelper使用 SQLiteAssetHelper 填充 RecyclerView
【发布时间】:2017-05-16 13:15:06
【问题描述】:

当我使用 SQLiteHelper 从本地数据库填充它时,我的 RecyclerView 工作正常,但现在我想使用 SQLiteAssetHelper 使用位于我的资产文件夹中的外部数据库来填充它,所以我遵循了这个 Github SQLiteAssetHelper example 中的示例但是我认为 SimpleCursorAdapter() 方法与 ListView 兼容,但与 RecyclerView 不兼容,因为它给了我“不兼容类型”的 IDE 错误。

他们是解决这个问题的方法还是我应该将我的 RecyclerView 转换为 ListView?非常感谢您的帮助。

public class DisplayActivity extends AppCompatActivity {

    DataSource mDataSource;
    List<Facility> facilityList = DataProvider.facilityList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_display);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mDataSource = new DataSource(this);
        mDataSource.open();                             // Open database
        mDataSource.seedDatabase(facilityList);

        List<Facility> listFromDB = mDataSource.getAllItems();
        FacilitiesAdapter adapter = new FacilitiesAdapter(this, listFromDB);
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.displayActivityRecyclerView);
        recyclerView.setAdapter(adapter);

    }   // End of onCreate()


    @Override
    protected void onPause() {
        super.onPause();
        mDataSource.close();                        // Close database connection when application is
    }                                               // paused to prevent database leaks.

    @Override
    protected void onResume() {
        super.onResume();
        mDataSource.open();                         // Open database connection when application is resumed
    }
}

SQLiteHelper 类:

public class DBHelper extends SQLiteOpenHelper {

    public static final String DB_FILE_NAME = "health.db";
    public static final int DB_VERSION = 1;

    public DBHelper(Context context) {
        super(context, DB_FILE_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(FacilitiesTable.SQL_CREATE);         // Execute SQL_CREATE statement;
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(FacilitiesTable.SQL_DELETE);         // delete old database
        onCreate(db);                                   // Create new database
    }
}

【问题讨论】:

  • “当我使用 SQLiteHelper 从本地数据库填充 RecyclerView 时,它工作正常”——你没有在那里使用 SimpleCursorAdapter。因此,如果它“工作正常”,请坚持使用该代码,将您的SQLiteOpenHelper 换成SQLiteAssetHelper。否则,请创建您自己的 RecyclerView.Adapter,使用您的 Cursor 作为其数据源。
  • @CommonsWare 再次感谢您的回复 :) 但是我需要使用外部数据库,或者以某种方式将数据库文件复制到我的 /data/data/package/databases 文件夹中,这将是完美的解决方案。
  • 请编辑您的问题并显示“工作正常,我使用 SQLiteHelper 从本地数据库填充它”的代码。
  • 所以,只需将extends SQLiteOpenHelper 替换为extends SQLiteAssetHelper,删除onCreate()onUpgrade() 方法,并调整构造函数以提供SQLiteAssetHelper 所需的内容。如果此代码与 extends SQLiteOpenHelper 的类一起使用,它将与 extends SQLiteAssetHelper 的类一起使用。
  • @CommonsWare,我不知道该说什么,经过 4 天的绝望,我几乎要放弃了。多亏了你,它终于奏效了。你解决了我一个巨大的问题。我非常感谢你,但仅仅感谢你是不够的。

标签: android listview android-recyclerview android-sqlite android-database


【解决方案1】:

SQLiteAssetHelperSQLiteOpenHelper 的即插即用替代品,因为SQLiteAssetHelper 本身扩展了SQLiteOpenHelper

因此,给定代码与 SQLiteOpenHelper 的子类一起使用,您需要做的就是:

  • 更改该子类以扩展 SQLiteAssetHelper

  • 远程 onCreate()onUpgrade() 方法

  • 如果需要,调整对超类构造函数的调用

然后,按照the documentation,将您的数据库打包到assets/,然后就可以开始了。

在您扩展 SQLiteOpenHelper 时有效的任何代码现在应该在您扩展 SQLiteAssetHelper 时继续有效。

【讨论】:

    【解决方案2】:

    您可以使用此方法将数据库从 Assets 文件夹复制到“默认”位置:

    public final String path = "/data/data/YourPackageName/databases/";
        public final String Name = "DataBaseName.db";
    
        public void copydatabase() throws IOException {
    
            OutputStream myOutput = new FileOutputStream(path + Name);
            byte[] buffer = new byte[1024];
            int length;
            InputStream myInput = getApplicationContext().getAssets().open("DataBaseName.db");
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myInput.close();
            myOutput.flush();
            myOutput.close();
    
        }
    

    不仅仅是打电话:

    copydatabase() 
    

    然后用 try/catch 包围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-13
      • 1970-01-01
      相关资源
      最近更新 更多