Android 使用 Room 访问 BroadcastReceiver 数据库

Android BroadcastReceiver Database Access with Room

我设置了一个闹钟,每小时调用一个广播接收器。此接收器尝试从 sqlite 数据库加载数据。

问题是,提醒列表为空。相同的代码在 activity 中有效,但在接收器中无效。有什么我必须更改才能访问接收器中的数据库。这是 activity 和接收器中不同上下文的问题吗?

"setAlarm" 方法是我使用的方法,用于在 activity 上创建警报。

此致

public class AppReceiver extends BroadcastReceiver {

    private static final String TAG = "AppReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        ReminderRepository mRepository; = new ReminderRepository(context);
        List<Reminder> list = mRepository.getAllReminder();
        for(Reminder r : list) {
            // TODO
        }
    }
}


public class ReminderRepository {

    private ReminderDao mReminderDao;
    private List<Reminder> mAllReminder;

    public DisposalCalenderRepository(Context context) {
        ReminderRoomDatabase db = ReminderRoomDatabase.getDatabase(context);
        mReminderDao = db.reminderDao();
        mAllReminder = mReminderDao.getAll();
    }

    public List<Reminder> getAllReminder(){
        return mAllReminder;
    }

}

@Dao
public interface ReminderDao {

    @Query("SELECT * from reminder")
    List<Reminder> getAll();

}

public void setAlarm(){
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add(Calendar.HOUR, 1);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);

    AlarmManager alarmMgr = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
    Intent i = new Intent(mContext, AppReceiver.class);
    PendingIntent alarmIntent = PendingIntent.getBroadcast(mContext, 0, i, 0);

    alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_HOUR, alarmIntent);
    }

我为我的问题找到了两个可能的答案。

解决方案 1:启动异步任务。创建一个 AsyncTask class 并在 doBackground 方法中执行这些操作。访问数据库没有问题了。

@Override
public void onReceive(Context context, Intent intent) {
    new notifyAsyncTask().execute(context);
}

private static class notifyAsyncTask extends AsyncTask<Context, Void, Void> {

        private String CHANNEL_ID = "1a2b3c4d";

        private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        @Override
        protected Void doInBackground(Context... params) {
            Log.i(TAG, "Notify async started");
        ReminderRepository mRepository; = new ReminderRepository(context);
        List<Reminder> list = mRepository.getAllReminder();
        for(Reminder r : list) {
                // TODO
        }
    }
}

方案二:允许在主线程上查询。建立数据库时,使用 allowMainThreadQueries() 允许在主线程上进行查询。

!!!!注意力 !!!!不建议 !!!!注意!!!!