热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用LiveData从网络刷新数据

如何解决《使用LiveData从网络刷新数据》经验,谁能帮忙解答一下?

我正在研究一个查询github API的应用程序以获取用户列表,而我正在遵循推荐的android 体系结构组件指南。从网络中获取数据后,我将使用Room DB将其存储在本地,然后使用在LiveData对象上观察到的ViewModel将其显示在UI上(这很好)。但是,我希望有一个按钮,当且仅当存在网络连接时,单击该按钮将触发刷新操作并执行网络请求以从API获取新数据。问题是,当我单击该按钮时,将触发两个网络调用,一个来自refreshUserData(),另一个来自已存在的LiveData(在onCreate()期间触发)。我应如何最好地处理这种情况,以使刷新按钮仅执行一个网络请求,而不执行两个网络请求。这是我的存储库类:

public class UserRepository {
private final UserDao mUserDao;
private LiveData> mAllUsers;
private LiveData mUser;
private final GithubUserService githubUserService;
private final AppExecutors appExecutors;
private final Application application;
private static String LOG_TAG = UserRepository.class.getSimpleName();
private RateLimiter repoListRateLimit = new RateLimiter<>(1, TimeUnit.MINUTES);

   public UserRepository(Application application, GithubUserService githubUserService, AppExecutors appExecutors) {
        this.application = application;
        UserRoomDatabase db = UserRoomDatabase.getDatabase(application);
        mUserDao = db.userDao();
        this.githubUserService = githubUserService;
        this.appExecutors = appExecutors;
    }

    public LiveData getUser(int userId) {
        LiveData user = mUserDao.loadUser(userId);
        Log.d(LOG_TAG, "retrieved user from database successful");
        return user;
    }

    public LiveData>> getAllUsers() {
        //ResultType, RequestType
        /**
         * List is the [ResultType]
         * GithubUser is the [RequestType]
         */
        return new NetworkBoundResource, GithubUser>(appExecutors) {

            @Override
            protected void saveCallResult(@NonNull GithubUser item) {
                Log.d(LOG_TAG, "call to insert results to db");
                mUserDao.insertUsers(item.getItems());
            }

            @Override
            protected boolean shouldFetch(@Nullable List data) {
                Log.d(LOG_TAG, "null?" + (data == null));
                Log.d(LOG_TAG, "empty? " + (data.isEmpty()));
                Log.d(LOG_TAG, "rate? " + (repoListRateLimit.shouldFetch("owner")));
                Log.d(LOG_TAG, "should fetch? " + (data.isEmpty() || repoListRateLimit.shouldFetch("owner")));
                return data.isEmpty() || data == null;

            }

            @NonNull
            @Override
            protected LiveData> loadFromDb() {
                Log.d(LOG_TAG, " call to load from db");
                return mUserDao.getAllUsers();
            }

            @NonNull
            @Override
            protected LiveData> createCall() {
                Log.d(LOG_TAG, "creating a call to network");
                return githubUserService.getGithubUsers("language:java location:port-harcourt");
            }

            @Override
            protected GithubUser processResponse(ApiResponse response) {
                return super.processResponse(response);
            }
        }.asLiveData();
    }


    public LiveData>> refreshUserData() {
        //ResultType, RequestType
        /**
         * List is the [ResultType]
         * GithubUser is the [RequestType]
         */
        return new NetworkBoundResource, GithubUser>(appExecutors) {

            @Override
            protected void saveCallResult(@NonNull GithubUser item) {
                Log.d(LOG_TAG, "call to insert results to db");
                mUserDao.insertUsers(item.getItems());
            }

            @Override
            protected boolean shouldFetch(@Nullable List data) {
                Log.d(LOG_TAG, "refreshUserData");
                return true;
            }

            @NonNull
            @Override
            protected LiveData> loadFromDb() {
                Log.d(LOG_TAG, "refreshUserData");
                Log.d(LOG_TAG, " call to load from db");
                return mUserDao.getAllUsers();
            }

            @NonNull
            @Override
            protected LiveData> createCall() {
                Log.d(LOG_TAG, "refreshUserData");
                Log.d(LOG_TAG, "creating a call to network");
                return githubUserService.getGithubUsers("language:java location:port-harcourt");
            }

            @Override
            protected GithubUser processResponse(ApiResponse response) {
                return super.processResponse(response);
            }
        }.asLiveData();
    }

    public Application getApplication() {
        return application;
    }
}

我的ViewModel类是:

public class UserProfileViewModel extends AndroidViewModel {
    private UserRepository mRepository;


    public UserProfileViewModel(UserRepository mRepository) {
        super(mRepository.getApplication());
        this.mRepository = mRepository;
      }

    public LiveData>> getmAllUsers() {
        return mRepository.getAllUsers();
      }

    public LiveData>> refreshUserData() {
        return mRepository.refreshUserData();
      }

    public LiveData getUser(int userId) {
        return mRepository.getUser(userId);
      }
    }

我的MainActivity类:

    public class MainActivity extends AppCompatActivity implements GithubAdapter.ListItemClickListener {
    private RecyclerView mRecyclerView;
    private UserProfileViewModel mUserViewModel;
    public static final String USER_ID = "userId";
    private ConnectivityManager cm;
    private boolean isConnected;
    private UserRepository mRepository;
    private  GithubUserService mGithubUserService;

    private NetworkInfo activeNetwork;
    private Picasso mPicasso;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        mGithubUserService = GithubApplication.get(MainActivity.this).getGithubUserService();
        mPicasso = GithubApplication.get(MainActivity.this).getPicasso();

        mRepository = new UserRepository(getApplication(), mGithubUserService, new AppExecutors());


        // the factory and its dependencies instead should be injected with DI framework like Dagger
        ViewModelFactory factory = new ViewModelFactory(mRepository);

        mUserViewModel = ViewModelProviders.of(this, factory).get(UserProfileViewModel.class);

        //  initViews();
        mRecyclerView = findViewById(R.id.users_recycler);
        final GithubAdapter mAdapter = new GithubAdapter(this, this, mPicasso);
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);

        getUsers(mAdapter);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //check if there is a network connection
                // if there is a network connection the LoaderManager is called but
                //  displays a message if there's no network connection
                activeNetwork = cm.getActiveNetworkInfo();
                isCOnnected= activeNetwork != null && activeNetwork.isConnectedOrConnecting();
                if (isConnected) {
                    mUserViewModel.refreshUserData().observe(MainActivity.this, new Observer>>() {
                        @Override
                        public void onChanged(@Nullable Resource> listResource) {
//                            Toast.makeText(MainActivity.this, "second" + listResource.status, Toast.LENGTH_LONG).show();
                            Snackbar.make(view, "refresh:" + listResource.status, Snackbar.LENGTH_LONG)
                                    .setAction("Action", null).show();
                            mAdapter.setUsers(listResource.data);
                        }
                    });

                } else {
                    Snackbar.make(view, "no connection", Snackbar.LENGTH_LONG)
                            .setAction("Action", null).show();

                }

            }
        });


    }



 private void getUsers(GithubAdapter mAdapter) {
        mUserViewModel.getmAllUsers().observe(this, new Observer>>() {
            @Override
            public void onChanged(@Nullable Resource> listResource) {
                Toast.makeText(MainActivity.this, "" + listResource.status, Toast.LENGTH_LONG).show();
                mAdapter.setUsers(listResource.data);
            }
        });
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onListItemClick(int userId) {
        Intent detailIntent = new Intent(MainActivity.this, 
        DetailActivity.class);
        detailIntent.putExtra(USER_ID, userId);
        startActivity(detailIntent);
      }
    }

您可以在此处找到完整的代码


推荐阅读
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • FineReport平台数据分析图表显示部分系列接口的应用场景和实现思路
    本文介绍了FineReport平台数据分析图表显示部分系列接口的应用场景和实现思路。当图表系列较多时,用户希望可以自己设置哪些系列显示,哪些系列不显示。通过调用FR.Chart.WebUtils.getChart("chartID").getChartWithIndex(chartIndex).setSeriesVisible()接口,可以获取需要显示的系列图表对象,并在表单中显示这些系列。本文以决策报表为例,详细介绍了实现方法,并给出了示例。 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • Android系统源码分析Zygote和SystemServer启动过程详解
    本文详细解析了Android系统源码中Zygote和SystemServer的启动过程。首先介绍了系统framework层启动的内容,帮助理解四大组件的启动和管理过程。接着介绍了AMS、PMS等系统服务的作用和调用方式。然后详细分析了Zygote的启动过程,解释了Zygote在Android启动过程中的决定作用。最后通过时序图展示了整个过程。 ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
  • 推荐:看到如此多的MVP+Dagger2+Retrofit+Rxjava项目,轻松拿star,心动了吗?看到身边的朋友都已早早在项目中使用这些技术,而你还不会,失落吗?MVPArm ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
author-avatar
safadfdfdsfsd
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有