web-dev-qa-db-ja.com

フォアグラウンドサービスからLiveDataを観察する

LiveDataオブジェクトを保持し、アクティビティとViewModelを介したフォアグラウンドサービスの両方で使用されるリポジトリがあります。アクティビティから観察を開始すると、すべてが期待どおりに機能します。ただし、サービスから監視しても、監視はトリガーされません。これは私が使用するコードです

class MyService: LifecycleService() {
     lateinit var viewModel: PlayerServiceViewModel

     override fun onCreate() {
          viewModel = MyViewModel(applicationContext as Application)
     }

     override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
          viewModel.getLiveData().observe(this, Observer { data ->
            // Do something with the data
        })
     }
}

なぜ機能しないのか、データを受け取っていないのですか?

11
Ilya Sosis

ViewModelLiveDataLifecycleActivityとともにFragmentsを使用しました。期待どおりに動作し、データを監視します。

あなたの問題に来て、あなたが作成するときnewViewModelからServiceまたは他のActivityを作成します新しいインスタンスViewModelがリポジトリ、最終的にはDAOからクエリを実行するために必要なすべてのLiveDataおよびその他の依存関係。両方のViewModelで同じDAOを使用していない場合、LiveDataは更新されない場合があります。これはdifferent DAOのインスタンス

プロジェクトでDagger2を使用して、DAOおよびその他の一般的な依存関係のシングルトンインスタンスを維持しました。そのため、アプリケーション全体で一貫性を保つために、リポジトリとDAO シングルトンを作成してみてください。

同じフローでServicesLifecycleServiceを使用して試してみましたが、うまくいきました。

データがnullからプルされたデータに変更されたときに次の出力が表示されました

D/ForegroundService: onStartCommand: Resource{status=LOADING, message='null', data=null}
D/ForegroundService: onStartCommand: Resource{status=SUCCESS, message='null', data=TVShow(id=14,...

ネットワークからデータを取得し、データベースObserverに自動的に更新されたデータを更新した後、データがデータベースに存在しなかったため、最初はnullデータを示しました。

次のコードを使用して解決しました

public class ForegroundService extends LifecycleService {

    private static final String TAG = "ForegroundService";

    private TVShowViewModel tvShowViewModel;
    private TVShow tvShow;

    @Inject TVShowDataRepo tvShowDataRepo;

    @Override
    public void onCreate() {
        super.onCreate();

        AndroidInjection.inject(this);
        tvShowViewModel = new TVShowViewModel(tvShowDataRepo);
        tvShowViewModel.init(14);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        tvShowViewModel.getTVShow().observe(this, tvShowResource -> {
            Log.d(TAG, "onStartCommand: " + tvShowResource);
        });
        return super.onStartCommand(intent, flags, startId);
    }
}
16
adityakamble49