Как предварительно заполнить базу данных в Android с помощью базы данных SQLite

Опубликовано: 4 Января, 2022

Часто возникает необходимость запустить приложение Android с уже существующей базой данных. Это называется предварительным заполнением базы данных . В этой статье мы увидим, как предварительно заполнить базу данных в Android с помощью базы данных SQLite. База данных, используемая в этом примере, может быть загружена как демонстрационная база данных.

Подход:

  1. Добавьте библиотеку поддержки в файл build.gradle и добавьте зависимость Recycler View в раздел зависимостей.
    dependencies{
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
    }
  2. Убедитесь, что вы добавили базу данных в папку с ресурсами. Чтобы создать папку с активами, щелкните правой кнопкой мыши каталог приложения-> новая-> Папка -> (выберите) Папку с активами . Затем просто вставьте файл .db в папку с ресурсами.
  3. В activity_main.xml добавьте следующий код.
    <? xml version = "1.0" encoding = "utf-8" ?>
    < LinearLayout
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:paddingStart = "5dp"
    android:paddingTop = "5dp" >
    < androidx.recyclerview.widget.RecyclerView
    android:id = "@+id/my_recycler_view"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:scrollbars = "vertical" />
    </ LinearLayout >
  4. Создайте новый файл custom_layout.xml со следующим кодом.
    <? xml version = "1.0" encoding = "utf-8" ?>
    < LinearLayout
    android:layout_width = "match_parent"
    android:layout_height = "wrap_content"
    android:layout_marginTop = "3dp"
    >
    < TextView
    android:textStyle = "bold"
    android:layout_margin = "5dp"
    android:textSize = "20sp"
    android:layout_width = "match_parent"
    android:layout_height = "wrap_content"
    android:id = "@+id/textView" />
    </ LinearLayout >
  5. Создайте класс DatabaseHelper и добавьте следующий код.
    package org.geeksforgeeks.dictionary;
    import android.app.Activity;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteException;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.util.Log;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    public class DatabaseHelper
    extends SQLiteOpenHelper {
    // The Android's default system path
    // of your application database.
    private static String DB_PATH = "" ;
    private static String DB_NAME = "database.db" ;
    private SQLiteDatabase myDataBase;
    private final Context myContext;
    private SQLiteOpenHelper sqLiteOpenHelper;
    // Table name in the database.
    public static final String
    ALGO_TOPICS
    = "algo_topics" ;
    /**
    * Constructor
    * Takes and keeps a reference of
    * the passed context in order
    * to access the application assets and resources. */
    public DatabaseHelper(Context context)
    {
    super (context, DB_NAME, null , 1 );
    this .myContext = context;
    DB_PATH = myContext.getDatabasePath(DB_NAME)
    .toString();
    }
    // Creates an empty database
    // on the system and rewrites it
    // with your own database.
    public void createDataBase()
    throws IOException
    {
    boolean dbExist = checkDataBase();
    if (dbExist) {
    // do nothing - database already exist
    }
    else {
    // By calling this method and
    // the empty database will be
    // created into the default system
    // path of your application
    // so we are gonna be able
    // to overwrite that database
    // with our database.
    this .getWritableDatabase();
    try {
    copyDataBase();
    }
    catch (IOException e) {
    throw new Error(
    "Error copying database" );
    }
    }
    }
    // Check if the database already exist
    // to avoid re-copying the file each
    // time you open the application
    // return true if it exists
    // false if it doesn't.
    private boolean checkDataBase()
    {
    SQLiteDatabase checkDB = null ;
    try {
    String myPath = DB_PATH;
    checkDB
    = SQLiteDatabase
    .openDatabase(
    myPath, null ,
    SQLiteDatabase.OPEN_READONLY);
    }
    catch (SQLiteException e) {
    // database doesn't exist yet.
    Log.e( "message" , "" + e);
    }
    if (checkDB != null ) {
    checkDB.close();
    }
    return checkDB != null ;
    }
    /**
    * Copies your database from your
    * local assets-folder to the just
    * created empty database in the
    * system folder, from where it
    * can be accessed and handled.
    * This is done by transferring bytestream.
    * */
    private void copyDataBase()
    throws IOException
    {
    // Open your local db as the input stream
    InputStream myInput
    = myContext.getAssets()
    .open(DB_NAME);
    // Path to the just created empty db
    String outFileName = DB_PATH;
    // Open the empty db as the output stream
    OutputStream myOutput
    = new FileOutputStream(outFileName);
    // transfer bytes from the
    // inputfile to the outputfile
    byte [] buffer = new byte [ 1024 ];
    int length;
    while ((length = myInput.read(buffer)) > 0 ) {
    myOutput.write(buffer, 0 , length);
    }
    // Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
    }
    public void openDataBase()
    throws SQLException
    {
    // Open the database
    String myPath = DB_PATH;
    myDataBase = SQLiteDatabase
    .openDatabase(
    myPath, null ,
    SQLiteDatabase.OPEN_READONLY);
    }
    @Override
    public synchronized void close()
    {
    // close the database.
    if (myDataBase != null )
    myDataBase.close();
    super .close();
    }
    @Override
    public void onCreate(SQLiteDatabase db)
    {
    // It is an abstract method
    // but we define our own method here.
    }
    @Override
    public void onUpgrade(SQLiteDatabase db,
    int oldVersion,
    int newVersion)
    {
    // It is an abstract method which is
    // used to perform different task
    // based on the version of database.
    }
    // This method is used to get the
    // algorithm topics from the database.
    public List<String> getAlgorithmTopics(
    Activity activity)
    {
    sqLiteOpenHelper
    = new DatabaseHelper(activity);
    SQLiteDatabase db
    = sqLiteOpenHelper
    .getWritableDatabase();
    List<String> list
    = new ArrayList<>();
    // query help us to return all data
    // the present in the ALGO_TOPICS table.
    String query = "SELECT * FROM " + ALGO_TOPICS;
    Cursor cursor = db.rawQuery(query, null );
    if (cursor.moveToFirst()) {
    do {
    list.add(cursor.getString( 1 ));
    } while (cursor.moveToNext());
    }
    list; return
    }
    }
  6. Создайте класс MyAdapter.java и добавьте следующий код.
    package org.geeksforgeeks.dictionary;
    import android.app.Activity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    import java.util.List;
    public class MyAdapter
    extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private List<String> data;
    Activity activity;
    public MyAdapter(Activity activity,
    List<String> data)
    {
    this .data = data;
    this .activity = activity;
    }
    // This method is used to attach
    // custom layout to the recycler view
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(
    @NonNull ViewGroup parent,
    int viewType)
    {
    LayoutInflater LI
    = activity.getLayoutInflater();
    View vw = LI.inflate(
    R.layout.custom_layout, null );
    return new ViewHolder(vw);
    }
    // This method is used to set the action
    // to the widgets of our custom layout.
    @Override
    public void onBindViewHolder(
    @NonNull ViewHolder holder,
    position) int
    {
    holder.topic_name
    .setText(data.get(position));
    }
    @Override
    public int getItemCount()
    {
    return data.size();
    }
    class ViewHolder
    extends RecyclerView.ViewHolder {
    TextView topic_name;
    public ViewHolder(View itemView)
    {
    super (itemView);
    this .topic_name
    = itemView.findViewById(R.id.textView);
    }
    }
    }
  7. Наконец, в MainActivity.java добавьте следующий код.
    package org.geeksforgeeks.algorithmTopics;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.recyclerview.widget.DefaultItemAnimator;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    import android.os.Bundle;
    import java.util.ArrayList;
    import java.util.List;
    public class MainActivity
    extends AppCompatActivity {
    private static RecyclerView.Adapter adapter;
    private static RecyclerView recyclerView;
    public static List<String> data;
    DatabaseHelper db;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
    super .onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    recyclerView
    = findViewById(R.id.my_recycler_view);
    db = new DatabaseHelper( this );
    recyclerView.setLayoutManager(
    new LinearLayoutManager( this ));
    data = new ArrayList<>();
    fetchData();
    }
    public void fetchData()
    {
    // Before fetching the data
    // directly from the database.
    // first we have to creates an empty
    // database on the system and
    // rewrites it with your own database.
    // Then we have to open the
    // database to fetch the data from it.
    db = new DatabaseHelper( this );
    try {
    db.createDataBase();
    db.openDataBase();
    }
    catch (Exception e) {
    e.printStackTrace();
    }
    data = db.getAlgorithmTopics( this );
    adapter = new MyAdapter( this , data);
    recyclerView.setAdapter(adapter);
    }
    }

Выход:

Вниманию читателя! Не прекращайте учиться сейчас. Получите все важные концепции теории CS для собеседований SDE с курсом теории CS по доступной для студентов цене и будьте готовы к отрасли.