jetpack之paging源码解析

参考资料
源码:https://mp.weixin.qq.com/s/aoBAuiuSRvfyCpnHGYrpwA
设计思路:https://mp.weixin.qq.com/s/QoKwTm0x6hssCzocnDp_1A

如果没有现在这么爱较真的心情,直接查看以上地址完全能够理解,而且写得也很好,以下也是参考这篇文章的。(我就是个搬代码的瓦匠工,如有雷同,时间在我前都算我借鉴的,以下字是我一行行敲的)

非常重要的原理图(网上拷贝)以及源码结构(自行剪切)
在这里插入图片描述在这里插入图片描述在这里插入图片描述
原理图基本上说明了paging分页的工作原理。源码确实类名比较多,根据原理图以及实际操作来按顺序讲解。

类介绍
这里先不做介绍,按照PagingWithNetworkSample demo走一遍,这个有的手机因为某些你懂得原因访问网络失败,那就重新找个demo,或者用pagingsample demo将就下。

PagingWithNetWorkSample案例:( kotlin编写的代码)

在这里插入图片描述
这里面有三个:
1.network only(by item)以这条为主线进行讲解
2.network only (by page)不讲,雷同by item
3.db+network( roomdatabase)作为晋级来讲;

(1) network only(by item)
用户点击 NETWORK ONLY(BY ITEM) 按钮引发的血案…(我网络请求失败了,大爷的,那咱直接分析代码):

默认输入KEY_SUBREDDIT 值导致调用repository.postsOfSubreddit(it, 30)方法

SubRedditViewModel.kt:

 companion object {
        const val KEY_SUBREDDIT = "subreddit"
        const val DEFAULT_SUBREDDIT = "androiddev"
    }

    init {
        if (!savedStateHandle.contains(KEY_SUBREDDIT)) {
            savedStateHandle.set(KEY_SUBREDDIT, DEFAULT_SUBREDDIT)
        }
    }

    private val repoResult = savedStateHandle.getLiveData<String>(KEY_SUBREDDIT).map {
        repository.postsOfSubreddit(it, 30) *注释①*
    }

repository.postsOfSubreddit方法逻辑如下
先SubRedditViewModel 方法调用val repo = ServiceLocator.instance(this@RedditActivity).getRepository(repoType);

然后在ServiceLocator类中instance方法实例化DefaultServiceLocator(继承ServiceLocator)并且getRepository()方法,根据type调用InMemoryByItemRepository,其实以上代码注释①调用的就是这里的postsOfSubreddit方法。

RedditActivity.kt:

private val model: SubRedditViewModel by viewModels {
        object : AbstractSavedStateViewModelFactory(this, null) {
            override fun <T : ViewModel?> create(
                    key: String,
                    modelClass: Class<T>,
                    handle: SavedStateHandle
            ): T {
                val repoTypeParam = intent.getIntExtra(KEY_REPOSITORY_TYPE, 0)
                val repoType = RedditPostRepository.Type.values()[repoTypeParam]
                val repo = ServiceLocator.instance(this@RedditActivity)
                        .getRepository(repoType)
                @Suppress("UNCHECKED_CAST")
                return SubRedditViewModel(repo, handle) as T
            }
        }
    }
    
ServiceLocator.kt:

fun instance(context: Context): ServiceLocator {
            synchronized(LOCK) {
                if (instance == null) {
                    instance = DefaultServiceLocator(
                            app = context.applicationContext as Application,
                            useInMemoryDb = false)
                }
                return instance!!
            }
        }
        ...
        override fun getRepository(type: RedditPostRepository.Type): RedditPostRepository {
        return when (type) {
            RedditPostRepository.Type.IN_MEMORY_BY_ITEM -> InMemoryByItemRepository(
                    redditApi = getRedditApi(),
                    networkExecutor = getNetworkExecutor())
            RedditPostRepository.Type.IN_MEMORY_BY_PAGE -> InMemoryByPageKeyRepository(
                    redditApi = getRedditApi(),
                    networkExecutor = getNetworkExecutor())
            RedditPostRepository.Type.DB -> DbRedditPostRepository(
                    db = db,
                    redditApi = getRedditApi(),
                    ioExecutor = getDiskIOExecutor())
        }
    }
    
InMemoryByItemRepository.kt:

@MainThread
    override fun postsOfSubreddit(subReddit: String, pageSize: Int): Listing<RedditPost> {
        val sourceFactory = SubRedditDataSourceFactory(redditApi, subReddit, networkExecutor)

        // We use toLiveData Kotlin ext. function here, you could also use LivePagedListBuilder
        val livePagedList = sourceFactory.toLiveData(
                // we use Config Kotlin ext. function here, could also use PagedList.Config.Builder
                config = Config(
                        pageSize = pageSize,
                        enablePlaceholders = false,
                        initialLoadSizeHint = pageSize * 2),
                // provide custom executor for network requests, otherwise it will default to
                // Arch Components' IO pool which is also used for disk access
                fetchExecutor = networkExecutor)
				...
    }

Config是配置文件:这里配置每页请求个数,占位符为false(一般都为false,这个对我而言目前用不上,而且用起来不复杂,这里不表),首次请求为page*2

(源码)PagedListConfig.kt
@Suppress("FunctionName")
fun Config(
    pageSize: Int,
    prefetchDistance: Int = pageSize,
    enablePlaceholders: Boolean = true,
    initialLoadSizeHint: Int =
            pageSize * PagedList.Config.Builder.DEFAULT_INITIAL_PAGE_MULTIPLIER,
    maxSize: Int = PagedList.Config.MAX_SIZE_UNBOUNDED
): PagedList.Config {
    return PagedList.Config.Builder()
            .setPageSize(pageSize)
            .setPrefetchDistance(prefetchDistance)
            .setEnablePlaceholders(enablePlaceholders)
            .setInitialLoadSizeHint(initialLoadSizeHint)
            .setMaxSize(maxSize)
            .build()
}

SubRedditDataSourceFactory继承 DataSource.Factory,工厂用于创建DataSource,

class SubRedditDataSourceFactory(
        private val redditApi: RedditApi,
        private val subredditName: String,
        private val retryExecutor: Executor) : DataSource.Factory<String, RedditPost>() {
    val sourceLiveData = MutableLiveData<ItemKeyedSubredditDataSource>()
    override fun create(): DataSource<String, RedditPost> {*注释②
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为AI助手,我无法直接安装nvidia-jetpack,但是我可以为您提供一些步骤,帮助您完成源码安装nvidia-jetpack的过程。 1.下载nvidia-jetpack源码 您可以从官方网站下载nvidia-jetpack源码包,下载后解压到本地目录。 2.安装依赖包 在安装nvidia-jetpack前,您需要安装一些必要的依赖包,可以使用以下命令安装: ``` sudo apt-get update sudo apt-get install build-essential cmake git unzip pkg-config sudo apt-get install libjpeg-dev libpng-dev libtiff-dev sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev sudo apt-get install libxvidcore-dev libx264-dev sudo apt-get install libgtk-3-dev sudo apt-get install libatlas-base-dev gfortran ``` 3.安装CUDA 由于nvidia-jetpack需要CUDA支持,因此您需要先安装CUDA。您可以从nvidia官网下载相应的CUDA版本并按照官方指南进行安装。 4.安装cuDNN 同样,您需要安装cuDNN以支持nvidia-jetpack,您可以从nvidia官网下载相应的cuDNN版本并按照官方指南进行安装。 5.编译nvidia-jetpack 打开终端,进入nvidia-jetpack源码目录,执行以下命令: ``` mkdir build cd build cmake .. make -j4 ``` 其中-j4表示使用4个线程进行编译,可以根据您的CPU核心数进行调整。 6.安装nvidia-jetpack 编译成功后,执行以下命令进行安装: ``` sudo make install ``` 安装完成后,您可以执行以下命令进行验证: ``` jetson_release -v ``` 如果输出了正确的版本信息,则表示安装成功。 希望这些步骤能够帮助到您。请注意,由于nvidia-jetpack的安装过程较为复杂,如果您不熟悉Linux操作,请谨慎操作,以免造成不必要的损失。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值