Java 如何使活动显示从服务获取的数据?

Java 如何使活动显示从服务获取的数据?,java,android,kotlin,android-livedata,android-mvvm,Java,Android,Kotlin,Android Livedata,Android Mvvm,我需要写一个服务,它将更新MainActivity中的列表,每30秒更新一次。我将MVVM与ViewModel和LiveData一起使用,因此我的服务类如下所示: public class ArticleJobService extends JobService { public static String TAG = "ArticleJobService"; private Context context = this; @Override public

我需要写一个服务,它将更新MainActivity中的列表,每30秒更新一次。我将MVVM与ViewModel和LiveData一起使用,因此我的服务类如下所示:

public class ArticleJobService extends JobService {

    public static String TAG = "ArticleJobService";

    private Context context = this;

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        Log.d(TAG, "onStartJob");
        MainActivity.PAGE_NUMBER++;
        LiveData<List<Article>> liveArticles = ArticleRepository.getInstance(getApplication()).getArticles(MainActivity.PAGE_NUMBER);

        liveArticles.observeForever(new Observer<List<Article>>() {
            @Override
            public void onChanged(@Nullable List<Article> articles) {
                Log.d(TAG, "onStartJob - onChanged!!!!!!");
                liveArticles.removeObserver(this);
                NotificationUtils.showNotification(context, articles.get(0).getSectionName(), articles.get(0).getWebTitle());
                jobFinished(jobParameters, true);
            }
        });
        return true;
    }
}
当JobService中的Onchanged工作时,我会得到列表并显示通知。通知打开MainActivity,它会像往常一样对api进行新调用。为了使MainActivity显示我从服务中获得的列表,我必须进行哪些更改???我真的不能把这件事联系起来。 我听说过IPC,但不会这么做,我想要一些简单的实践,我确实存在,但我不知道。 此外,还有两种情况:通知发出,MainActivity打开;应用程序打开,但MainActivity不在前台;应用程序在后台或关闭。我应该如何处理这些案件

另请参见MainActivity onCreate中的一段代码:

 mArticleViewModel = ViewModelProviders.of(this).get(ArticleViewModel.class);
    mArticleViewModel.getArticleList(PAGE_NUMBER).observe(this, articles -> {
        Log.d(TAG, "List<Result> onChanged!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
        mProgressBar.setVisibility(View.GONE);
        mProgressBarMain.setVisibility(View.GONE);
        mIsLoading = false;
        mArticles = articles;
mArticleViewModel=ViewModelProviders.of(this.get)(ArticleViewModel.class);
mArticleViewModel.getArticleList(页码)。观察(此,文章->{
Log.d(标签“列表一旦更改;
mProgressBar.setVisibility(View.GONE);
mProgressBarMain.setVisibility(View.GONE);
错误加载=错误;
材料=物品;
请提供这项任务的最佳实践,我知道这是很常见的,我只是第一次做,使用LiveData会使它更加复杂

以下是存储库代码:

public static ArticleRepository getInstance(Application application){
        if(INSTANCE == null){
            return  new ArticleRepository(application);
        }

        return INSTANCE;
    }

    private ArticleRepository(Application application) {
        Log.d(TAG, "ArticleRepository constructor");
        mContext = application;
        mArticles = new MutableLiveData<>();
        ArticleRoomDatabase db = ArticleRoomDatabase.getInstance(application);
        mArticleDao = db.articleDao();
    }

    public LiveData<List<Article>> getArticles(int page) {
        Log.d(TAG, "getArticles");
        if (NetworkUtils.isOnline(mContext)) {
            Log.d(TAG, "isOnline");
            mArticles = loadFromNetwork(page);
        } else {
            Log.d(TAG, "is NOT Online");
            mArticles = loadFromDB(page);
        }
    }
公共静态ArticleRepository getInstance(应用程序){
if(实例==null){
返回新的ArticleRepository(应用程序);
}
返回实例;
}
专用ArticleRepository(应用程序){
Log.d(标记“ArticleRepository构造函数”);
mContext=应用程序;
mArticles=新的可变LiveData();
ArticleRoomDatabase db=ArticleRoomDatabase.getInstance(应用程序);
mArticleDao=db.articleDao();
}
公共LiveData getArticles(整版页){
Log.d(标签“getArticles”);
if(NetworkUtils.isOnline(mContext)){
Log.d(标签“isOnline”);
mArticles=从网络加载(第页);
}否则{
Log.d(标签“未联机”);
mArticles=loadFromDB(第页);
}
}

您遇到此问题的具体原因是您的存储库实现不正确

public LiveData<List<Article>> getArticles(int page) {
    Log.d(TAG, "getArticles");
    if (NetworkUtils.isOnline(mContext)) {
        Log.d(TAG, "isOnline");
        mArticles = loadFromNetwork(page);
    } else {
        Log.d(TAG, "is NOT Online");
        mArticles = loadFromDB(page);
    }
}

public LiveData
我将MVVM与ViewModel和LiveData一起使用,因此我的服务类看起来是这样的:
我不明白为什么您的服务类看起来是这样的,如果我可以做得更好,我不会问这个问题并征求建议,所以要么提出建议和更正,非常具体,要么不发表任何评论。请说什么我的意思是,除了获取服务中的项目列表,然后显示通知之外,您的服务到底做了什么?我可以想象“更新列表”意味着获取写入文件室的数据,一旦完成,订阅
LiveData
将自动更新列表,而无需在后台线程上执行写入操作。您的要求不明确。因此,要求运行后台服务,每3个月从webservice获取数据0秒并显示通知,打开通知显示更新的主屏幕。我的服务现在只从服务器获取数据,我不知道如何将其与MainActivity联系起来。关于room,它不是我应用程序中的真实来源,我在使用LiveData插入room时遇到问题,因此我使用room和common List,我将提供代表o代码删除了问题并添加了回复代码非常感谢,我曾考虑单独调用db和webservice,但您将其说得更清楚,我也更自信了。我唯一关心的是我应该如何组织寻呼,目前每次到达列表末尾时它都会从网络加载,每次重新调用时我都会清除dbaches page size*2如果涉及分页,您可能希望从DAO中公开
DataSource.Factory
,并在LivePagedListBuilder上设置BoundaryCallback(使用分页AAC)。这样,当你滚动到页面底部时,你就可以开始后台获取任务。我担心我花了3-4天的时间在分页库上,无法让它工作,我的截止日期是明天,所以我想我会手动实现分页库的概念。嗯,如果你放弃分页,那么你可以使用
object:RecyclerView.OnScrollListener(){override fun onScrolled(recyclerView:recyclerView,dx:Int,dy:Int){if(!recyclerView.CanScrollVertical(1)){OnScrolletToBottom()}
检测您何时处于页面底部,并启动后台提取任务(如果尚未进行)我已经完成了这一部分,到达底部并从网络获取数据,我的api确实提供了页码和页面大小,我关心的是从db逐页获取数据,就像在分页库中一样。
public LiveData<List<Article>> getArticles(int page) {
    Log.d(TAG, "getArticles");
    if (NetworkUtils.isOnline(mContext)) {
        Log.d(TAG, "isOnline");
        mArticles = loadFromNetwork(page);
    } else {
        Log.d(TAG, "is NOT Online");
        mArticles = loadFromDB(page);
    }
}