CloudReader: an Android reading client built on the WanAndroid API
🗡️ 云阅:一款基于网易云音乐UI,使用玩Android Api,Retrofit2 + RxJava2 + Room + MVVM-databinding架构开发的Android客户端
At a glance
- What is it?
- CloudReader is an open source Android app that borrows the NetEase Cloud Music interface and pairs it with the WanAndroid API, using Retrofit2, RxJava2, Room and MVVM-databinding. It is a reference project for Android architecture more than a product you would ship to users.
- Who is it for?
- Adopt CloudReader if you want a working, licensed example of MVVM-databinding, Room and RxJava2 assembled into a real app, and you are willing to read Java and Kotlin side by side. Do not adopt it if you need a maintained product, a stable data source, or a dependency set you can upgrade without touching the code.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 113 days ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What CloudReader actually is, and who it is for
CloudReader is an Android client that reads content from the WanAndroid API and presents it in an interface modelled on NetEase Cloud Music. The README describes it as a reading class open source project that follows Google Material Design. It is not a general purpose reader for your own files. The content comes from a remote API, and the app is a front end for that API.
The audience is Android developers rather than readers. The feature list in the README is a list of implementation techniques: NavigationView with DrawerLayout, transparent status bars with version adaptation, RxBus instead of EventBus for cross component messaging, ToolBar usage, Glide loading with cache access, circular images and Gaussian blur, ripple click effects, Room basics, DataBinding based ViewHolder, BaseActivity and BaseFragment, Fragment lazy loading, SwipeRefreshLayout with RecyclerView, CoordinatorLayout with Behavior for a gradient title bar, and a dark mode. Each of those is a pattern a developer might want to see applied in a complete app rather than in an isolated sample.
The repository is not archived, and the last push was on 2026-06-09. That is recent enough that the project is not abandoned, but the release history tells a more uneven story: v3.7.0 shipped in November 2021, and the next release, v3.8.3_20250331, arrived on 2025-03-31, more than three years later. That gap is the honest signal about how much ongoing work to expect.
How the MVVM-databinding stack is wired together
The architecture named in the description is Retrofit2 for networking, RxJava2 for threading and streams, Room for local persistence, and MVVM with DataBinding for the presentation layer. The README confirms Room basics and DataBinding based ViewHolder, BaseActivity and BaseFragment as features, which means the binding layer is not limited to individual layouts: the base classes themselves are built around it.
A second module sits next to the app module. The repository root contains both app/ and bymvvm/, and the version history mentions bymvvm alongside AndroidX and ByWebView in the V3.4.2 entry. So the project is split between application code and a reusable MVVM layer, which is worth knowing before you go looking for a class: some of the base machinery is not in app/.
RxBus replaces EventBus for communication between components, per the feature list. That is a deliberate choice with a cost. RxBus keeps you inside the RxJava2 dependency you already have, but it gives up the explicit subscriber registry and event classes that EventBus provides, so tracing who receives an event means reading the Rx subjects yourself. For a reference project whose purpose is to demonstrate patterns, that trade is defensible. For a codebase several people maintain, it is the kind of decision you would want to revisit.
The README also states the build environment: targetSdkVersion 34, gradle-8.0-bin, JDK17, Android Studio Ladybug 2024.2.1, and a runtime on macOS. Those are the versions the author used, and the V3.8.3 release notes list upgrading gradle, JDK and targetSdkVersion as one of the three changes in that release.
Building CloudReader from source and opening the app
The README does not publish a download link in the visible text; the download block is commented out. What it does give is the runtime environment, so building from source is the documented path. The repository root has gradlew and gradlew.bat plus a gradle/ directory, which is a standard Gradle wrapper layout.
Clone the repository and use the wrapper rather than a locally installed Gradle, because the README pins gradle-8.0-bin:
git clone https://github.com/youlookwhat/CloudReader.git
cd CloudReader
./gradlew assembleDebugOn Windows, use gradlew.bat instead of ./gradlew. The build expects JDK17 and a targetSdkVersion of 34, both stated in the README, so a machine on an older JDK will fail before it reaches your code.
The project is a multi module build. settings.gradle at the root is where the included modules are declared, and the repository root shows app/ and bymvvm/ as directories, so a module rename or removal has to be reflected there.
Once the APK is installed, the first screen is the one the screenshots show: a NetEase Cloud Music style layout with a drawer. The README's feature list says the drawer uses NavigationView with DrawerLayout, and that content loads through SwipeRefreshLayout combined with RecyclerView for pull to refresh and pull up to load. If the app opens and the lists stay empty, the likely cause is the WanAndroid API rather than your build, since every content screen depends on it.
The API dependency is the project's real ceiling
CloudReader has no offline mode and no bundled content. Everything it displays comes from the WanAndroid API, and the version history shows what happens when an upstream API changes. V2.8.0 hides the book category because the API failed. V2.9.0 hides the Douban movie page for the same reason. V3.5.0 removes the movie module entirely, and the release note says the API was invalid and calls it a shame. V3.7.0 removes the Gank module.
That is four separate removals of user facing features because a third party endpoint stopped working. It is not a bug in CloudReader; it is the structural consequence of being a client for someone else's service. If you fork this project to learn from it, understand that a meaningful part of the feature list is contingent on endpoints the project does not control.
The same applies to the login and collection features. The README mentions a WanAndroid points system module and login with article collection, and the older notes mention logging in with a GitHub account. Those flows depend on the WanAndroid service accepting the requests, and the README does not document what happens when it does not.
One more boundary: this is an Android application, not a library. There is no published artifact to depend on. Reusing the bymvvm module means copying it into your own project, not adding a coordinate to a build file.
How CloudReader differs from a plain Android architecture sample
Google's own architecture samples and the many MVVM templates on GitHub usually isolate one concern per module and keep the UI deliberately plain, so the pattern is the only thing on screen. CloudReader goes the other way. It is a full application with a styled interface, animations, a drawer, a dark mode and a WebView, and the architecture is demonstrated under the pressure of those requirements.
That difference matters when you are deciding what to read. A minimal sample tells you how DataBinding works. CloudReader tells you what it looks like when DataBinding has to support a gradient title bar driven by CoordinatorLayout and Behavior, a lazy loaded Fragment, and a RecyclerView that both refreshes and paginates. The README links to ByRecyclerView, a separate project by the same author, and V3.1.0 states that every list in the app was replaced with it. So the list behaviour is not hand rolled here; it comes from that companion library.
If your goal is to learn a single API in isolation, a small official sample will be faster. If your goal is to see the pieces coexist, CloudReader is the more useful artifact, at the price of more code to read. The language mix adds to that cost: the primary language is Java, the topics list both kotlin and kotlin-android, and the version history notes that V3.4.4 moved part of the code to Kotlin and V3.5.0 added the square, Q&A and article sharing features in Kotlin. Expect to switch between the two.
Licence and the cost of keeping a fork current
The repository carries Apache-2.0, and the LICENSE file sits at the root alongside README.md and build.gradle. Apache-2.0 permits commercial use and modification and requires that you keep the licence and attribution. It also includes a patent grant, which some permissive licences omit. That is the shape of the licence as the repository presents it; whether it fits your situation is a question for your own legal review, not something this article can settle.
Upgrade cost is the more practical concern. The pinned environment is gradle-8.0-bin, JDK17 and targetSdkVersion 34, and the release cadence is sparse: v3.6.0 and v3.7.0 landed within a month of each other in late 2021, then nothing until v3.8.3 on 2025-03-31. A fork that tracks the upstream will spend most of its time on dependency migrations rather than features, because the upstream does not do them often. The V3.8.3 notes list exactly three changes, and one of them is upgrading gradle, JDK and targetSdkVersion, which tells you how much of a release can be consumed by housekeeping alone.
If you fork, the modules in app/ and bymvvm/ are the parts you will actually maintain, and settings.gradle is where their inclusion is declared. Nothing in the README describes a rollback or downgrade procedure, so pinning a known good commit is your own responsibility.
Editorial conclusion
Adopt CloudReader if you want a working, licensed example of MVVM-databinding, Room and RxJava2 assembled into a real app, and you are willing to read Java and Kotlin side by side. Do not adopt it if you need a maintained product, a stable data source, or a dependency set you can upgrade without touching the code. Verify first that the WanAndroid endpoints the app calls still respond, and check the Apache-2.0 LICENSE file in the repository root before you reuse any of the code.
Frequently asked questions
What is CloudReader?
It is an open source Android reading client that uses the WanAndroid API and an interface modelled on NetEase Cloud Music, built with Retrofit2, RxJava2, Room and MVVM-databinding. The README presents it as a Material Design reading project, and the feature list is largely a catalogue of Android patterns it demonstrates.
How do I install CloudReader?
The README's download block is commented out, so the documented path is building from source with the Gradle wrapper. The stated environment is JDK17, gradle-8.0-bin and targetSdkVersion 34.
Does CloudReader work offline?
The README does not describe an offline mode. Content is fetched from the WanAndroid API, and the version history records several features being hidden or removed when their upstream API stopped working.
What licence does CloudReader use?
Apache-2.0, with the LICENSE file at the repository root next to README.md and build.gradle. The licence permits modification and commercial use and requires attribution and retention of the licence text.
Is CloudReader still maintained?
The repository is not archived and the last push was on 2026-06-09. The release history is uneven, with v3.7.0 in November 2021 followed by v3.8.3_20250331 on 2025-03-31, so the project sees occasional updates rather than steady development.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/youlookwhat-cloudreader)