使用 Android BroadcastReceiver 触发 Room DB 操作的正确方法

Right way to use Android BroadcastReceiver to trigger Room DB Operation

我的应用程序有一个前台服务,我希望我的所有网络调用都发生在前台服务中,以保持一切正常。我还在服务中实现了一个房间数据库。

我的计划是让所有数据库操作都基于触发器在服务端进行。广播在 Intent 中以 Bundle 的形式将数据传递给服务。

但是,我的问题是:

  1. BroadcastListeners 在主线程上运行。
  2. Room DB 操作需要脱离主线程,这样应用才不会出现 ANR
  3. 当我在 BroadcastListener 中实现 HandlerThread 或带有 Runnable 的线程时,我无法传递数据,因为意图变量是'从内部 class 访问的并且需要宣布最终'

我的代码(目前)如下。

BroadcastReceiver houseCallCancelReceiver = new BroadcastReceiver () {
        @Override
        public void onReceive(Context context, Intent intent) {
            new Thread(new Runnable()  {
                @Override
                public void run() {
                    Bundle bundle = intent.getParcelableExtra ("housecall");
                    String email = bundle.getString("email");
                    String housecallid = bundle.getString("housecallid");
                    .
                    .
                    .
                    }
                }
            }).start();
        }
    }; 

atm我能想到几个方案,包括:

  1. 在函数中编写数据库逻辑(和线程)并传递 意图作为线程的参数。 - 这导致代码是 不是全部放在一起,这样更难阅读,因为我会有一个 每个操作的功能
  2. 在 AsyncTask 中进行调用 - 与上面相同加上大量一次性 AsyncTask 调用。另外,我可以在 ForegroundService 中调用 AsyncTask 吗?
  3. 升级到 Java 1.8 并使用 Lambdas - 我担心这可能会破坏与旧手机的兼容性。

非常感谢任何帮助!

我在这个帖子中找到了(某种程度上的)答案:Runnable with a Parameter

通过将 Room DB 逻辑移动到一个单独的函数,并在函数本身中声明一个 class 并在构造函数中调用该函数,我可以将 Intent 作为参数.

BroadcastReceiver refreshHousecallsReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "onReceive: In refreshHousecallsReceiver");
            class OneShotTask implements Runnable {
                // idea from 
                Intent intent;
                OneShotTask(Intent intent1) { intent= intent1; }
                public void run() {
                    refreshHouseCalls(intent);
                }
            }
            Thread t = new Thread(new OneShotTask(intent));
            t.start();
        }
    };

我试过了,很管用。但是,这不是一种可重复使用的做事方式,我正在寻找其他做同样事情的方式 - 请分享您的示例或想法!