LifecycleAwareRssReader is simple app which
- reads rss files
- converts them to json using web api
- saves pojos to local SQLite database and
- allows browsing articles thru simple list.
App has been created as part of Coursera Android Programming Capstone Project.
See PlainRssReader if you are interested in using traditional approach to lifecycle controlling.
Repositorys docs directory contains resources which accompany this documentation, otherwise repository contains solely application artifacts.
Rss reading is implemented using http protocol and json payload. XML to Json conversion is done using rss2json service.
Example url of background service. rss_url query parameter defines source of rss feed.
https://api.rss2json.com/v1/api.json?rss_url=https%3A%2F%2Fwww.theguardian.com%2Finternational%2Frss
"Software architecture is those decisions which are both important and hard to change." - Martin Fowler.
Development is done using Android Studio, which is currently at 3.0. Newest versio is used 'cos it has Java 8 support and lambdas are pretty nice. Java 8 Streams are not used, since they doesn't exist before API-level 24.
Android devices with API-level 24 are still not commonly in use, but API-level 19 is safe choice for most users. I have used selected Android architecture components, escpecially Room for persistence and ViewModel and LiveData for lifecycle.
I try to keep in mind that 64K DEX limit can possibly make my life hard as I'm not willing to invest in learning bytecode optimization tricks with ProGuard in this phase of development.
PlantUml is used to illustrate high level structure of application. UML diagrams are written using textual DSL.
It's easy to write uml models with PlantUml when you have practiced it a bit. Here's source of components diagram.
@startuml
package "PlainRssReader" {
[SettingsActivity]
[FeedActivity]
[RecyclerView]
[PreferenceFragment]
}
package "AndroidServices" {
[AndroidBrowser]
}
cloud {
[RssToJsonConverter]
}
cloud {
[RssFeedProducer]
}
[FeedActivity] -up-> [SettingsActivity]:configure rss feeds url
[FeedActivity] - [RecyclerView]:browse feed
[SettingsActivity] - [PreferenceFragment]:edit url
[FeedActivity] --> [AndroidBrowser]:ask browser to show article
[AndroidBrowser] --> [RssFeedProducer]:get single artice as html
[FeedActivity] --> [RssToJsonConverter]:get rss feed as json
[RssToJsonConverter] --> [RssFeedProducer]:get rss feed as xml
@enduml
Use PlantUml testbench if you want to experiment with given source.
"there's no way to design the software in advance. Instead, you must design your software based on its current needs, and evolve the software design as the requirements change. This process is called evolutionary design." - James Shore.
It's tempting to think that there's a way to know all details in advance and one could start work once plan in finished. I have taken different stance. Design evolves as I have more information, knowledge or time, and implementation follows design immendiately. Some call this iterative software development or emergent design in contrast to Big Front Up or Plan Driven Desing. Simply put: I try to defer decisions to last responsible moment, but still steer my work with current knowledge.
Motivation for buffering results for offline use can be seen at Next Billion Users
yEd was used to draw simple diagram of use cases.
Reverse engineering UML model with Andoid studio was done with SimpleUMLCe.
Model classes store retrieved articles
It wouldn't be necessary to store all attributes of rss feed, but it's done here for completeness.
Mockups were prepared with marvel app
List of items
Selected item
settings
I did have trial versio in use, and for this reason I needed to take snapshots from screens instead of neatly exporting results to files.
Rss feed reading is proxied thru rss2json service, which converts feed to json on the fly.
Http requests are queued and processed using Volley.
Feed url is read from preferences. When no feed is defined Default feed is used.
Storing and changing settings is implemented using PreferefencesFragment as defined in use preferences
Gson is used to marshall returned JSON to Plain Java Pojos.
Browsing items is implemented using RecyclerView as defined in use recycler-view
Lifecycle is controlled using ViewModel and LiveData, which make programming model pretty simple.
Room is used for object-relational-mapping. Room testing explains how to test database operations.
Read Room tutorial and work thru Room codelab and Android lifecycles codelab for more details. When you have got this far you might be interested to read LiveData patterns and antipatterns and play with Android arhitecture blueprints. And don't miss Android architecture guide.
Due to limitations and interoperability issues with Room annotation processors AutoValue and Lombok aren't used to reduce boilerplate code of model classes, see AutoValue issue and [Room issue] for deeper discussion.
List of items
Selected item
settings
change url dialog
User given url is not checked, and when trying to use wrong url during startup app will not show anything.