Some notes on the design decisions and architecture of the Android app.
Catch up with your buddycloud channels using your Android device.
The Android client implements most of the features provided by the [buddycloud API] (http://buddycloud.org/w/index.php?title=Buddycloud_HTTP_API "buddycloud HTTP API"): create and read channels' content; create, delete and follow channels; search by content and metadata; recommentation and similarity features; channel summary synchronization; push notifications using GCM; API discovery via DNS TXT records; and much more.
Besides the Android SDK and the support library, we use:
- ActionBarSherlock to implement the action bar design pattern;
- SligingMenu to implement the side menu;
- picasso for displaying and transforming images; and
- dnsjava for DNS queries.
- GooglePlayServices setup google play services SDK for GCM.
- fab for material design floating action button in older android devices.
- image-chooser-library for selecting images/videos from gallery/photos/camera.
As we use HTTPS as default, we expect API server certificates to be valid so that we can start talking to them. If the API certificate is not valid, we prompt the user for confirmation, so that he becomes aware of unsafe connections. If the user agrees to do so (and ask the app to remember this decision), we store it as a preference, and we skip SSL for this server.
MainActivity --if not logged------> LoginActivity
---------------------> GenericChannelActity --pick a channel--> MainActivity
---------------------> SettingsActivity --save settings---> MainActivity
---------------------> SearchActivity --pick a channel--> MainActivity
---------------------> ChannelDetailsActivity --save or back-> MainActivity
MainActivity --back-menu-visible--> exit
LoginActivity --login-------------> MainActivity
--not registered----> CreateAccountActivity ------> MainActivity
--back--------------> exit
SettingsActivity -----------------> ChangePasswordActivity --save or back-> SettingsActivity
-----------------> AboutBuddycloudActivity --save or back-> SettingsActivity
ShareActivity --post created------> exit
���-----------���-------------------���
��� ��� ���
��� ��� ���
��� ��� ���
���Subscribed ��� Channel ���
��� Channels ��� Stream ���
��� Fragment ��� Fragment ���
��� ��� ���
��� ��� ���
��� ��� ���
���-----------���-------------------���
An Adapter object acts as a bridge between a View and the underlying data for that view. Adapters provide access to data items and are also responsible for making a View for each item in the data set. In our app, adapters also work as memory caches, since they fetch and store data items from the SQLite DB. In most of the cases, adapters are also responsible for the sorting of data items. Adapter classes can be found in the package com.buddycloud.fragments.adapter.
Models are the glue between adapters and the SQLite+HTTP layer. Models decide when to use the SQLite cache or when to hit the API. They are aware of the API endpoints and the DB helpers. Model classes can be found in the package com.buddycloud.model.
The SQLite cache makes the app feels faster, since we almost always have something to show before hitting the API. We have tables for channel metadata, posts, subscribed channels, threads' ids and unread counters. DB helper classes can be found in the package com.buddycloud.model.db. In order to access data stored in the SQLite cache, we use DAO classes. Those classes assemble SQL queries to read and update the database, thus, there is a corresponding DAO for each SQLite table. DAO classes can be found in the package com.buddycloud.model.dao.
Buddycloud android clients talks to the Buddycloud HTTP API. In that sense, the lower level of this app lives in the BuddycloudHTTPHelper. We use two Executors for HTTP requests, one for low priority requests and another for high ones. The low priority pool is expected to exhaust sooner, since it runs longer requests, while the high priority one is meant for quick requests updating the UI.
- since - Posts newer than this time
- max - Max posts count per channel (if a single channel is super active, we'd be overloading this endpoint or the client itself)
- First app launch (since=forever, max=5 (so that we fill the screen))
- Application launch (since=newest post in cache)
- Any push notification ** When notification are disabled in the preferences activity, the GCM should be still triggering sync.
- When we post (since=newest post in cache)
+-----------+ +-----------+ +-----------+
| Fragments | | SyncModel | | API |
+-----+-----+ +-----+-----+ +-----+-----+
| | |
| | sync(since=forever)|
| |------------------->|
| | +-|
| | posts + |
| |<-----------------+ |
| update +--+| |
| posts and | |sync(since=lastsync)|
| counters +-->|------------------->|
| | +-|
| | posts + |
| |<-----------------+ |
| update +--+| |
| posts and | | |
| counters +-->| |
| | |
| visitChannel | |
+------------------>|+--+ clear |
| | | counters |
| |<--+ |
| | |
v v v
After checking out the code, you need to download both ActionBarSherlock and SligingMenu and reference them as libraries in your project. Notice that SlidingMenu needs a small hack to work together with ActionBarSherlock.
Then, build: http://developer.android.com/tools/building/index.html. Life is easier if you are using Eclipse.
The main entry points of the app are the MainActivity and the ShareActivity. If the user is not logged yet, the MainActivity will start the LoginActivity, and handle its result.
Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly. Thus, we are using Oracle's code conventions for Java so that our code look beautiful.
We use GitHub issues to track our progress, so check our milestones page for release planning.
We are using JUnit and instrumentation to assemble our tests. Source code can be found at https://github.com/buddycloud/buddycloud-android-testing and PRs are welcome :)
Debugging TCP and HTTPS session reuse
sudo tcptrack -i eth0 port 443