Room使用实例

Room基本使用

Entity

首先定义一个User类:

// 定义为Entity
@Entity
public class User {
    // 设置主键
    @PrimaryKey(autoGenerate = true)
    private int uid;
    private String name;
    // 提供setter和getter供Room框架调用
    public User(String name) {
        this.name = name;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User:" + name + ", uid=" + uid;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (uid != user.uid) return false;
        return name != null ? name.equals(user.name) : user.name == null;
    }

    @Override
    public int hashCode() {
        int result = uid;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        return result;
    }
}

Database

接下来是创建数据库:

// 声明为Database,指定表格、版本
@Database(entities = {User.class}, version = 1, exportSchema = false)
public abstract class MyDatabase extends RoomDatabase {

    private static MyDatabase sInstance;

    // 构造函数必须是public,否则报错
    public MyDatabase() {
    }

    // 单实例模式,节省资源
    public static MyDatabase getsInstance(Context context) {
        if (sInstance == null) {
            synchronized (MyDatabase.class) {
                if (sInstance == null) {
                    sInstance = Room.databaseBuilder(context.getApplicationContext(),
                            MyDatabase.class, "sampleDb").build();
                }
            }
        }
        return sInstance;
    }

    // 定义获取Dao的方法
    abstract UserDao userDao();
}

Dao

定义数据存取对象:

@Dao
public interface UserDao {
    @Insert
    void insert(User user);

    @Query("SELECT * FROM user")
    LiveData<List<User>> users();
}

ViewModel

然后ViewModel就可以从Dao中获取LiveData了:

public class MainViewModel extends AndroidViewModel {

    private final UserDao mUserDao;
    private static final String TAG = "MainViewModel";
    private final LiveData<List<User>> mUsers;

    public MainViewModel(@NonNull Application application) {
        super(application);
        mUserDao = MyDatabase.getsInstance(application).userDao();
        mUsers = mUserDao.users();
    }

    public UserDao getUserDao(){
        return mUserDao;
    }

    public LiveData<List<User>> getUsers() {
        return mUsers;
    }
}

RecyclerView

定义Holder和Adapter:

public class UserHolder extends RecyclerView.ViewHolder {

    public final TextView mText;

    public UserHolder(View itemView) {
        super(itemView);
        mText = itemView.findViewById(android.R.id.text1);
    }
}

public class UserAdapter extends RecyclerView.Adapter<UserHolder> {

    private static final String TAG = "UserAdapter";
    private List<User> mUsers = new ArrayList<>();

    public void setList(List<User> users) {
        mUsers = users;
    }

    @NonNull
    @Override
    public UserHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        return new UserHolder(inflater.inflate(android.R.layout.simple_list_item_1, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull UserHolder holder, int position) {
        holder.mText.setText(mUsers.get(position).toString());
    }

    @Override
    public int getItemCount() {
        return mUsers.size();
    }
}

UI

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="add"
        android:text="add"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <EditText
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/add"
        app:layout_constraintTop_toTopOf="parent"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layoutManager="android.support.v7.widget.LinearLayoutManager"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/et"/>
</android.support.constraint.ConstraintLayout>

MainActivity:

public class MainActivity extends AppCompatActivity {

    private EditText mInput;
    private RecyclerView mRecyclerView;
    private MainViewModel mViewModel;
    private UserAdapter mUserAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mInput = findViewById(R.id.et);
        mRecyclerView = findViewById(R.id.recycler);
        mUserAdapter = new UserAdapter();
        mRecyclerView.setAdapter(mUserAdapter);

        // 获取ViewModel
        mViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
        // 观察ViewModel中的LiveData的变化
        mViewModel.getUsers().observe(this, new Observer<List<User>>() {
            @Override
            public void onChanged(@Nullable List<User> users) {
                mUserAdapter.setList(users);
                mUserAdapter.notifyDataSetChanged();
                mRecyclerView.smoothScrollToPosition(mUserAdapter.getItemCount() - 1);
            }
        });
    }

    public void add(View view) {
        // 子线程中进行数据库插入
        final Disposable disposable = Completable.fromAction(new Action() {
            @Override
            public void run() {
                mViewModel.getUserDao().insert(new User(mInput.getText().toString()));
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action() {
                    @Override
                    public void run() throws Exception {
                        mInput.getText().clear();
                    }
                });
    }
}

Room结合Paging

在上一个例子的基础上进行修改:

Dao

首先是Dao类中数据列表不再直接返回LiveData,而是返回DataSource.Factory

@Dao
public interface UserDao {
    @Insert
    void insert(User user);

    @Query("SELECT * FROM user")
    DataSource.Factory<Integer, User> users();
}

ViewModel

public class MainViewModel extends AndroidViewModel {

    private final UserDao mUserDao;
    private static final String TAG = "MainViewModel";

    // LiveData的泛型不是单纯的User,还包装了一层PagedList
    private final LiveData<PagedList<User>> mUsers;

    public MainViewModel(@NonNull Application application) {
        super(application);

        // 根据Dao中返回的DataSource构造LiveData,可以在LivePagedListBuilder中添加回调
        mUsers = new LivePagedListBuilder<>(mUserDao.users(), 15)
                .build();
    }

    public UserDao getUserDao() {
        return mUserDao;
    }

    public LiveData<PagedList<User>> getUsers() {
        return mUsers;
    }
}

RecyclerView.Adapter

Adapter此时需要继承自PagedListAdapter,无需实现getItemCount()方法,也无需提供方法传入数据列表:

public class UserAdapter extends PagedListAdapter<User, UserHolder> {

    private static final String TAG = "UserAdapter";

    // 需要提供DiffUtil的实现来比对Item
    protected UserAdapter() {
        super(new DiffUtil.ItemCallback<User>() {
            @Override
            public boolean areItemsTheSame(User oldItem, User newItem) {
                return oldItem.getUid() == newItem.getUid();
            }

            @Override
            public boolean areContentsTheSame(User oldItem, User newItem) {
                return oldItem.equals(newItem);
            }
        });
    }

    @NonNull
    @Override
    public UserHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        return new UserHolder(inflater.inflate(android.R.layout.simple_list_item_1, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull UserHolder holder, int position) {
        holder.mText.setText(getItem(position).toString());
    }
}

UI

使用PagedListAdapter自带的submitList更新数据列表:

public class MainActivity extends AppCompatActivity {

    private EditText mInput;
    private RecyclerView mRecyclerView;
    private MainViewModel mViewModel;
    private UserAdapter mUserAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mInput = findViewById(R.id.et);
        mRecyclerView = findViewById(R.id.recycler);
        mUserAdapter = new UserAdapter();
        mRecyclerView.setAdapter(mUserAdapter);

        mViewModel = ViewModelProviders.of(this).get(MainViewModel.class);

        mViewModel.getUsers().observe(this, new Observer<PagedList<User>>() {
            @Override
            public void onChanged(@Nullable PagedList<User> users) {
                // 使用PagedListAdapter自带的submitList更新数据列表
                mUserAdapter.submitList(users);
            }
        });


    public void add(View view) {
        ...
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值