【问题标题】:Android BroadcastReceiver Database Access with Room使用 Room 访问 Android BroadcastReceiver 数据库
【发布时间】:2018-08-30 13:44:18
【问题描述】:

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

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

“setAlarm”方法是我用来创建活动警报的方法。

问候

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);
    }

【问题讨论】:

  • 您在 Logcat 中的错误是什么?还是您只是退回了 0 件商品?从唤醒处理广播在至少可以运行的时间上有一些限制,可能还有互联网使用,但除非你能提供更多信息,否则不确定
  • logcat 中没有出现错误。我只得到一个空指针,因为“列表”变量为空。所以 NPE 出现在 for 循环中。
  • 嗯,从技术上讲,Room 会阻止某些线程的访问,但这应该显示为错误。因此,您可以尝试执行 async{} 调用来获取它并返回值。可能不会修复它,但值得一试。它是否会进入 DAO 进行调用,在您忽略正在发生的事情并需要添加日志记录之前,您可以调试多远?
  • 当我直接调用 DAO 时,我得到一个无法访问主线程上的数据库的错误。

标签: android broadcastreceiver android-room android-broadcastreceiver android-database


【解决方案1】:

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

解决方案 1:启动异步任务。创建一个 AsyncTask 类并在 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
        }
    }
}

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    相关资源
    最近更新 更多