android room

In this tutorial, we’ll be discussing and implementing the Room library introduced by Google. We’ll be using it to develop a Todo List Android Application.

在本教程中,我们将讨论和实现Google引入的Room库。 我们将使用它来开发Todo List Android应用程序。

安卓室 (Android Room)

Room is a library introduced by Google that acts as an Abstraction layer over SQLite and makes the database querying easier.

Room是Google引入的库,可作为SQLite上的抽象层,使数据库查询更加容易。

It does compile-time verification of SQL queries. Thus preventing runtime crashes.

它确实对SQL查询进行编译时验证。 从而防止运行时崩溃。

It reduces the boilerplate code. Instead of using SQLiteHelper and writing lengthy queries, we can use annotations to do the work for us.

它减少了样板代码。 代替使用SQLiteHelper和编写冗长的查询,我们可以使用注释为我们完成工作。

Following is the structure of Room library:

以下是Room库的结构:

Google Docs

谷歌文档

Typically, Room consists of the following three main components:

通常,Room由以下三个主要部分组成:

  • Entity: This is a model class in which we define the properties which act as column fields. We can alternatively set column names using the annotation @ColumnInfo We need to set the table name too. To ignore a property from the table, use the annotation @Ignore over it. At least one property must have @PrimaryKey. To set a column name that’s different from the field name, use @Embedded
    Entity :这是一个模型类,我们在其中定义充当列字段的属性。 我们也可以使用注释@ColumnInfo设置列名。我们也需要设置表名。 要忽略表中的属性,请@Ignore使用批注@Ignore 。 至少一个属性必须具有@PrimaryKey 。 若要设置与字段名称不同的列名称,请使用@Embedded
  • Database : This is an abstract class which must extend the RoomDatabase. We must set the Entity here. Also, we need to update the version number everytime we change the schema. Set exportSchema to true/false
    Database :这是一个抽象类,必须扩展RoomDatabase 。 我们必须在这里设置实体。 另外,每次更改架构时,我们都需要更新版本号。 将exportSchema设置为true / false
  • Dao: Data Access Object. This is the interface where we set our SQL queries. @Insert, @Query, @Update @Delete.
    @Insert cannot return an int.
    @Update and @Delete can return an int which represents the number of rows changed/deleted.
    Dao :数据访问对象。 这是我们设置SQL查询的接口。 @Insert@Query@Update @Delete
    @Insert无法返回int。
    @Update和@Delete可以返回一个整数,该整数表示已更改/删除的行数。
Room queries can’t be and should not be executed on the main thread. It’ll lead to a crash.
房间查询不能也不应在主线程上执行。 它将导致崩溃。

Let’s use Room library in our Todo List Android Application.

让我们在Todo List Android应用程序中使用Room库。

Android TODO App项目结构 (Android TODO App Project Structure)

Our application consists of inserting, updating, deleting todos.
We first need to import the following Room dependency in our build.gradle:

我们的应用程序包括插入,更新,删除待办事项。
我们首先需要在build.gradle中导入以下Room依赖项:

implementation 'android.arch.persistence.room:runtime:1.0.0'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'

Let’s create the Table for our Database using the Todo.java class as shown below:

让我们使用Todo.java类为数据库创建表,如下所示:

package com.journaldev.androidroomtodolist;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.Ignore;
import android.arch.persistence.room.PrimaryKey;import java.io.Serializable;@Entity(tableName = MyDatabase.TABLE_NAME_TODO)
public class Todo implements Serializable {@PrimaryKey(autoGenerate = true)public int todo_id;public String name;public String description;public String category;@Ignorepublic String priority;}

MyDatabase.java

MyDatabase.java

package com.journaldev.androidroomtodolist;import android.arch.persistence.room.Database;
import android.arch.persistence.room.RoomDatabase;@Database(entities = {Todo.class}, version = 1, exportSchema = false)
public abstract class MyDatabase extends RoomDatabase {public static final String DB_NAME = "app_db";public static final String TABLE_NAME_TODO = "todo";public abstract DaoAccess daoAccess();}

This is an abstract class which contains the definition of the DaoAccess() interface.

这是一个抽象类,其中包含DaoAccess()接口的定义。

DaoAccess.java

DaoAccess.java

package com.journaldev.androidroomtodolist;import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Update;import java.util.List;@Dao
public interface DaoAccess {@Insertlong insertTodo(Todo todo);@Insertvoid insertTodoList(List<Todo> todoList);@Query("SELECT * FROM " + MyDatabase.TABLE_NAME_TODO)List<Todo> fetchAllTodos();@Query("SELECT * FROM " + MyDatabase.TABLE_NAME_TODO + " WHERE category = :category")List<Todo> fetchTodoListByCategory(String category);@Query("SELECT * FROM " + MyDatabase.TABLE_NAME_TODO + " WHERE todo_id = :todoId")Todo fetchTodoListById(int todoId);@Updateint updateTodo(Todo todo);@Deleteint deleteTodo(Todo todo);
}

Add the annotations and a few sql queries. And all the SQLite features are ready to be implemented in our Activity.

添加注释和一些sql查询。 并且所有SQLite功能都可以在我们的Activity中实现。

The code for the activity_main.xml layout is given below:

下面给出了activity_main.xml布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Spinnerandroid:id="@+id/spinner"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentTop="true" /><android.support.v7.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@+id/spinner"android:layout_marginTop="16dp" /><android.support.design.widget.FloatingActionButtonandroid:id="@+id/fab"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:layout_marginBottom="16dp"android:src="@android:drawable/ic_input_add"android:layout_marginEnd="16dp"android:layout_marginRight="16dp" /></RelativeLayout>

The code for the recyclerview_item_layout.xml is given below:

下面给出了recyclerview_item_layout.xml的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="wrap_content"><android.support.v7.widget.CardViewandroid:id="@+id/cardView"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_margin="16dp"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:padding="8dp"><TextViewandroid:id="@+id/txtNo"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_centerVertical="true" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_toRightOf="@+id/txtNo"android:orientation="vertical"><TextViewandroid:id="@+id/txtName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginTop="8dp"android:textAllCaps="true"android:textColor="@android:color/black" /><TextViewandroid:id="@+id/txtDesc"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginStart="8dp"android:layout_marginTop="8dp"android:ellipsize="end"android:maxLines="1" /><TextViewandroid:id="@+id/txtCategory"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:layout_marginStart="8dp"android:layout_marginTop="8dp"android:textColor="@android:color/holo_red_dark" /></LinearLayout></RelativeLayout></android.support.v7.widget.CardView>
</LinearLayout>

The code for the MainActivity.java class is given below:

MainActivity.java类的代码如下:

package com.journaldev.androidroomtodolist;import android.annotation.SuppressLint;
import android.arch.persistence.room.Room;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.ClickListener, AdapterView.OnItemSelectedListener {MyDatabase myDatabase;RecyclerView recyclerView;Spinner spinner;RecyclerViewAdapter recyclerViewAdapter;FloatingActionButton floatingActionButton;private String[] categories = {"All","Android","iOS","Kotlin","Swift"};ArrayList<Todo> todoArrayList = new ArrayList<>();ArrayList<String> spinnerList = new ArrayList<>(Arrays.asList(categories));public static final int NEW_TODO_REQUEST_CODE = 200;public static final int UPDATE_TODO_REQUEST_CODE = 300;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initViews();myDatabase = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, MyDatabase.DB_NAME).fallbackToDestructiveMigration().build();checkIfAppLaunchedFirstTime();spinner.setOnItemSelectedListener(this);spinner.setSelection(0);floatingActionButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {startActivityForResult(new Intent(MainActivity.this, TodoNoteActivity.class), NEW_TODO_REQUEST_CODE);}});}private void initViews() {floatingActionButton = findViewById(R.id.fab);spinner = findViewById(R.id.spinner);ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, spinnerList);adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);spinner.setAdapter(adapter);recyclerView = findViewById(R.id.recyclerView);recyclerView.setLayoutManager(new LinearLayoutManager(this));recyclerViewAdapter = new RecyclerViewAdapter(this);recyclerView.setAdapter(recyclerViewAdapter);}@Overridepublic void launchIntent(int id) {startActivityForResult(new Intent(MainActivity.this, TodoNoteActivity.class).putExtra("id", id), UPDATE_TODO_REQUEST_CODE);}@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {if (position == 0) {loadAllTodos();} else {String string = parent.getItemAtPosition(position).toString();loadFilteredTodos(string);}}@Overridepublic void onNothingSelected(AdapterView<?> parent) {}@SuppressLint("StaticFieldLeak")private void loadFilteredTodos(String category) {new AsyncTask<String, Void, List<Todo>>() {@Overrideprotected List<Todo> doInBackground(String... params) {return myDatabase.daoAccess().fetchTodoListByCategory(params[0]);}@Overrideprotected void onPostExecute(List<Todo> todoList) {recyclerViewAdapter.updateTodoList(todoList);}}.execute(category);}@SuppressLint("StaticFieldLeak")private void fetchTodoByIdAndInsert(int id) {new AsyncTask<Integer, Void, Todo>() {@Overrideprotected Todo doInBackground(Integer... params) {return myDatabase.daoAccess().fetchTodoListById(params[0]);}@Overrideprotected void onPostExecute(Todo todoList) {recyclerViewAdapter.addRow(todoList);}}.execute(id);}@SuppressLint("StaticFieldLeak")private void loadAllTodos() {new AsyncTask<String, Void, List<Todo>>() {@Overrideprotected List<Todo> doInBackground(String... params) {return myDatabase.daoAccess().fetchAllTodos();}@Overrideprotected void onPostExecute(List<Todo> todoList) {recyclerViewAdapter.updateTodoList(todoList);}}.execute();}private void buildDummyTodos() {Todo todo = new Todo();todo.name = "Android Retrofit Tutorial";todo.description = "Cover a tutorial on the Retrofit networking library using a RecyclerView to show the data.";todo.category = "Android";todoArrayList.add(todo);todo = new Todo();todo.name = "iOS TableView Tutorial";todo.description = "Covers the basics of TableViews in iOS using delegates.";todo.category = "iOS";todoArrayList.add(todo);todo = new Todo();todo.name = "Kotlin Arrays";todo.description = "Cover the concepts of Arrays in Kotlin and how they differ from the Java ones.";todo.category = "Kotlin";todoArrayList.add(todo);todo = new Todo();todo.name = "Swift Arrays";todo.description = "Cover the concepts of Arrays in Swift and how they differ from the Java and Kotlin ones.";todo.category = "Swift";todoArrayList.add(todo);insertList(todoArrayList);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK) {//reset spinnersspinner.setSelection(0);if (requestCode == NEW_TODO_REQUEST_CODE) {long id = data.getLongExtra("id", -1);Toast.makeText(getApplicationContext(), "Row inserted", Toast.LENGTH_SHORT).show();fetchTodoByIdAndInsert((int) id);} else if (requestCode == UPDATE_TODO_REQUEST_CODE) {boolean isDeleted = data.getBooleanExtra("isDeleted", false);int number = data.getIntExtra("number", -1);if (isDeleted) {Toast.makeText(getApplicationContext(), number + " rows deleted", Toast.LENGTH_SHORT).show();} else {Toast.makeText(getApplicationContext(), number + " rows updated", Toast.LENGTH_SHORT).show();}loadAllTodos();}} else {Toast.makeText(getApplicationContext(), "No action done by user", Toast.LENGTH_SHORT).show();}}@SuppressLint("StaticFieldLeak")private void insertList(List<Todo> todoList) {new AsyncTask<List<Todo>, Void, Void>() {@Overrideprotected Void doInBackground(List<Todo>... params) {myDatabase.daoAccess().insertTodoList(params[0]);return null;}@Overrideprotected void onPostExecute(Void voids) {super.onPostExecute(voids);}}.execute(todoList);}private void checkIfAppLaunchedFirstTime() {final String PREFS_NAME = "SharedPrefs";SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);if (settings.getBoolean("firstTime", true)) {settings.edit().putBoolean("firstTime", false).apply();buildDummyTodos();}}
}
  • myDatabase = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, MyDatabase.DB_NAME).fallbackToDestructiveMigration().build(); is used to initialise the database.
    myDatabase = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, MyDatabase.DB_NAME).fallbackToDestructiveMigration().build(); 用于初始化数据库。
  • fallbackToDestructiveMigration() provides seamless migration across database version without crashing.
    fallbackToDestructiveMigration()提供跨数据库版本的无缝迁移而不会崩溃。
  • We check if the app is launched for the first time or not using shared preferences.
    我们会检查应用程序是首次启动还是不使用共享首选项 。
  • Then we create a dummy ArrayList to populate our RecyclerView.
    然后,我们创建一个虚拟ArrayList来填充RecyclerView 。
  • We need to use asynchronous tasks to run queries. So either use AsyncTask or go for RxJava. In this tutorial, we’ve used AsyncTasks.
    我们需要使用异步任务来运行查询。 因此,可以使用AsyncTask或使用RxJava 。 在本教程中,我们使用了AsyncTasks。
  • We will have following operations in our app:
    • Updating a Todo Item from the list
    • Adding a new Todo Item to the list.

    我们的应用程序中将执行以下操作:

    • 从列表更新待办事项
    • 将新的待办事项添加到列表中。
  • For either of the cases, we use startActivityForResult to get back the data from the next activity and update the RecyclerView accordingly.
    对于这两种情况,我们都使用startActivityForResult从下一个活动中获取数据并相应地更新RecyclerView。
  • Our spinner is used to filter the RecyclerView based on category for which we Query the database.
    我们的微调器用于根据查询数据库的类别过滤RecyclerView。

RecyclerViewAdapter.java

RecyclerViewAdapter.java

package com.journaldev.androidroomtodolist;import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;import java.util.ArrayList;
import java.util.List;public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {private List<Todo> todoList;private RecyclerViewAdapter.ClickListener clickListener;public RecyclerViewAdapter(ClickListener clickListener) {this.clickListener = clickListener;todoList = new ArrayList<>();}@Overridepublic RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_layout, parent, false);RecyclerViewAdapter.ViewHolder viewHolder = new RecyclerViewAdapter.ViewHolder(view);return viewHolder;}@Overridepublic void onBindViewHolder(RecyclerViewAdapter.ViewHolder holder, int position) {Todo todo = todoList.get(position);holder.txtName.setText(todo.name);holder.txtNo.setText("#" + String.valueOf(todo.todo_id));holder.txtDesc.setText(todo.description);holder.txtCategory.setText(todo.category);}@Overridepublic int getItemCount() {return todoList.size();}public void updateTodoList(List<Todo> data) {todoList.clear();todoList.addAll(data);notifyDataSetChanged();}public void addRow(Todo data) {todoList.add(data);notifyDataSetChanged();}public class ViewHolder extends RecyclerView.ViewHolder {public TextView txtName;public TextView txtNo;public TextView txtDesc;public TextView txtCategory;public CardView cardView;public ViewHolder(View view) {super(view);txtNo = view.findViewById(R.id.txtNo);txtName = view.findViewById(R.id.txtName);txtDesc = view.findViewById(R.id.txtDesc);txtCategory = view.findViewById(R.id.txtCategory);cardView = view.findViewById(R.id.cardView);cardView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {clickListener.launchIntent(todoList.get(getAdapterPosition()).todo_id);}});}}public interface ClickListener {void launchIntent(int id);}
}

The code for the activity_todo_note.xml layout is given below:

下面给出了activity_todo_note.xml布局的代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".TodoNoteActivity"><android.support.design.widget.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:theme="@style/AppTheme.AppBarOverlay"><android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" /></android.support.design.widget.AppBarLayout><include layout="@layout/content_todo_note" /></android.support.design.widget.CoordinatorLayout>

content_todo_note.xml

content_todo_note.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"tools:context=".TodoNoteActivity"tools:showIn="@layout/activity_todo_note"><EditTextandroid:id="@+id/inTitle"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginEnd="8dp"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginStart="8dp"android:layout_marginTop="16dp"android:ems="10"android:hint="Title"android:text="Sample Title"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><EditTextandroid:id="@+id/inDescription"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginEnd="8dp"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginStart="8dp"android:layout_marginTop="8dp"android:ems="10"android:hint="Description"android:minLines="3"android:text="Sample Description"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.0"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/inTitle" /><Spinnerandroid:id="@+id/spinner"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginEnd="8dp"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginStart="8dp"android:layout_marginTop="8dp"android:padding="16dp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/inDescription" /><Buttonandroid:id="@+id/btnDone"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginEnd="8dp"android:layout_marginLeft="8dp"android:layout_marginRight="8dp"android:layout_marginStart="8dp"android:layout_marginTop="16dp"android:text="DONE"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/spinner" /><Buttonandroid:id="@+id/btnDelete"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="8dp"android:text="DELETE"android:visibility="gone"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/btnDone" /></android.support.constraint.ConstraintLayout>

The code for the TodoNoteActivity.java class is given below

下面给出了TodoNoteActivity.java类的代码

package com.journaldev.androidroomtodolist;import android.annotation.SuppressLint;
import android.arch.persistence.room.Room;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;import java.util.ArrayList;
import java.util.Arrays;public class TodoNoteActivity extends AppCompatActivity {Spinner spinner;EditText inTitle, inDesc;Button btnDone, btnDelete;boolean isNewTodo = false;private String[] categories = {"Android","iOS","Kotlin","Swift"};public ArrayList<String> spinnerList = new ArrayList<>(Arrays.asList(categories));MyDatabase myDatabase;Todo updateTodo;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_todo_note);Toolbar toolbar = findViewById(R.id.toolbar);setSupportActionBar(toolbar);spinner = findViewById(R.id.spinner);inTitle = findViewById(R.id.inTitle);inDesc = findViewById(R.id.inDescription);btnDone = findViewById(R.id.btnDone);btnDelete = findViewById(R.id.btnDelete);ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, spinnerList);adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);spinner.setAdapter(adapter);myDatabase = Room.databaseBuilder(getApplicationContext(), MyDatabase.class, MyDatabase.DB_NAME).build();int todo_id = getIntent().getIntExtra("id", -100);if (todo_id == -100)isNewTodo = true;if (!isNewTodo) {fetchTodoById(todo_id);btnDelete.setVisibility(View.VISIBLE);}btnDone.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (isNewTodo) {Todo todo = new Todo();todo.name = inTitle.getText().toString();todo.description = inDesc.getText().toString();todo.category = spinner.getSelectedItem().toString();insertRow(todo);} else {updateTodo.name = inTitle.getText().toString();updateTodo.description = inDesc.getText().toString();updateTodo.category = spinner.getSelectedItem().toString();updateRow(updateTodo);}}});btnDelete.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {deleteRow(updateTodo);}});}@SuppressLint("StaticFieldLeak")private void fetchTodoById(final int todo_id) {new AsyncTask<Integer, Void, Todo>() {@Overrideprotected Todo doInBackground(Integer... params) {return myDatabase.daoAccess().fetchTodoListById(params[0]);}@Overrideprotected void onPostExecute(Todo todo) {super.onPostExecute(todo);inTitle.setText(todo.name);inDesc.setText(todo.description);spinner.setSelection(spinnerList.indexOf(todo.category));updateTodo = todo;}}.execute(todo_id);}@SuppressLint("StaticFieldLeak")private void insertRow(Todo todo) {new AsyncTask<Todo, Void, Long>() {@Overrideprotected Long doInBackground(Todo... params) {return myDatabase.daoAccess().insertTodo(params[0]);}@Overrideprotected void onPostExecute(Long id) {super.onPostExecute(id);Intent intent = getIntent();intent.putExtra("isNew", true).putExtra("id", id);setResult(RESULT_OK, intent);finish();}}.execute(todo);}@SuppressLint("StaticFieldLeak")private void deleteRow(Todo todo) {new AsyncTask<Todo, Void, Integer>() {@Overrideprotected Integer doInBackground(Todo... params) {return myDatabase.daoAccess().deleteTodo(params[0]);}@Overrideprotected void onPostExecute(Integer number) {super.onPostExecute(number);Intent intent = getIntent();intent.putExtra("isDeleted", true).putExtra("number", number);setResult(RESULT_OK, intent);finish();}}.execute(todo);}@SuppressLint("StaticFieldLeak")private void updateRow(Todo todo) {new AsyncTask<Todo, Void, Integer>() {@Overrideprotected Integer doInBackground(Todo... params) {return myDatabase.daoAccess().updateTodo(params[0]);}@Overrideprotected void onPostExecute(Integer number) {super.onPostExecute(number);Intent intent = getIntent();intent.putExtra("isNew", false).putExtra("number", number);setResult(RESULT_OK, intent);finish();}}.execute(todo);}}

setResult(RESULT_OK, intent); is used to pass back the result to the MainActivity.
We either pass the new todo task’s id or the number of rows deleted/updated and the RecyclerView is updated accordingly.

setResult(RESULT_OK, intent); 用于将结果传递回MainActivity。
我们要么传递新的待办任务的ID,要么传递删除/更新的行数,并相应地更新RecyclerView。

The output of the above application in action is given below.

android-room-todolist-output

下面给出了上面应用程序的输出。

This brings an end to this tutorial on Android Room. Using it we were able to create our first TodoList Application easily and quickly while reducing the boilerplate code of SQLite. You can download the final project from the link given below.

这样就结束了有关Android Room的本教程。 使用它,我们能够轻松快速地创建我们的第一个TodoList应用程序,同时减少了SQLite的样板代码。 您可以从下面给出的链接下载最终项目。

Download Android Studio Todo List App Code下载Android Studio Todo List应用代码
GitHub Repository.GitHub Repository下载代码。

翻译自: https://www.journaldev.com/20688/android-room-todo-list-application

android room

android room_Android Room –待办事项清单应用程序相关推荐

  1. 适用于Android的最佳免费待办事项列表应用程序以及如何使自己成才

    如果您没有组织任务,那么跟踪任务可能会很麻烦. 这就是待办事项清单的帮助. 在这篇文章中,我将向您展示一些适用于Android的最佳免费待办事项列表应用程序. 然后,我将为您提供一些有关如何创建自己的 ...

  2. 小狗钱钱_✅每次构建待办事项列表应用程序时,都会有一只小狗? 死了?

    小狗钱钱 by Hrishi Mittal 由Hrishi Mittal ✅每次构建待办事项列表应用程序时,都会有一只小狗 ? 死了? (✅ Every time you build a to-do ...

  3. 滴答清单 TickTick for Mac(待办事项清单)

    小编为大家推荐Mac平台上一款高效的待办事项清单软件滴答清单 TickTick for Mac,有了它你就能够将自己所有所需要的待办事件和任务记录下来.滴答清单 mac专注于为用户进行任务管理和日程提 ...

  4. 2021制定计划待办事项清单的记事便签

    2021年流行的制定计划和记录待办事项清单的记事便签有哪些呢?做事之前不列计划,不列出详细的待办清单,总觉得脑海里一团乱麻,临场发挥总会浪费好多时间,导致事倍功半. 研究表明,在设置目标上花费的时间, ...

  5. 为什么待办事项清单不管用

    为什么待办事项清单不管用 时间管理 November 22nd, 2012 本文原文来自 Harvard Business Review,由 @换装迷宫tayy 翻译. 停止制作你的待办事项清单吧.它 ...

  6. 待办事项列表应用程序Vikunja

    杨浦区防控办昨天傍晚发布了『 告杨浦居民书(二十二) 』,本周一.三.五.日晚间开展全区全员核酸筛查.比上周少了 2 次,说明情况应该是有所好转. 什么是 Vikunja ? Vikunja (/vɪ ...

  7. 如何建立工作待办事项?工作便签中的待办事项清单建立方法

    每一份工作都不容易,对于大多数人来说,每天的工作堆成了山,这里面有大事也有小事,有紧急的事情也有不紧急的事情.如果不分主次一起干,很难有良好的效果.如果能列出待办事项清单,可以很容易知道现在该做什么事 ...

  8. 待办事项清单和提醒软件有哪些 好用的每日待办提醒便签

    待办事项清单在我们日常的工作生活中非常的实用,我们每天要做的事情太多太杂,甚至经常会忘记做一些事情.为了避免遗忘,我们可以将每天要做的事情列成待办清单,将完成的待办事项打勾标记,这样就再也不用担心重要 ...

  9. 有没有可以跨平台的待办事项清单软件推荐?

    如果你还在使用纸质计划本记录处理待办事项,那真的是out了! 不单是我自己,我们团队目前的待办事项都就记录在飞项app上. ①.项目概览 可以在项目概览上直接导入已创建好的待办事项,或者在上面直接创建 ...

最新文章

  1. python 类-Python 类class定义 方法与属性教程
  2. Apache将整合Google Wave功能
  3. Uiautomator--Uiselector元素定位
  4. Qt 在designer 中给QToolBar 添加 action控件
  5. 网页空间 - 概念篇
  6. 解决SQL SERVER 2000挂起的问题
  7. python raw input用法_如何在 python raw_input 中使用 tab 键补全?
  8. C 语言基础——程序运行时间的计算
  9. Redis的两种持久化介绍与对比
  10. python扫描端口hack_一款集http端口扫描和目录批量扫描为一体的自动化工具
  11. java各个版本下载地址
  12. 最通俗易懂的JUC多线程并发编程
  13. 靶机渗透日记 responder
  14. JavaWeb图书馆管理系统
  15. 遗传算法调参 参数设置
  16. Opencv中使用ocl模块遇到的问题
  17. 【Docker】自定义dockerfile构建容器镜像并发布
  18. 奇瑞鲍思语畅谈奇瑞未来发展,前途一片光明
  19. 如何监控工程项目进度?
  20. js金额千分位 及 清除千分位

热门文章

  1. 2012-2-24 《数据结构》读书笔记2 线性表
  2. 三分钟免费搞定网站在线客服,利用PowerTalkBox控件制作而成,为大家提供比较好的示例...
  3. # 语音信号处理基础(十)——梅尔倒谱系数
  4. [转载] Python—urllib模块
  5. python基本操作(四)
  6. ArcGIS Engine开发基础总结(一)
  7. ActiveX控件安装和IE安全设置之间的关系
  8. CSS样式(三) - div盒子
  9. linux 开发板模拟u盘,ARM-Linux开发 - USB Gadget Storage 制作模拟U盘
  10. 修改拦截器里的请求头_OkHttp4 源码分析(1) 请求流程分析