Principal Android Engineer @ Hinge. These are my own thoughts and opinions.
April 2019
Advanced & Practical MotionLayout
Preparing a talk about what I've been working on at Hinge
I'll give a quick introduction to MotionLayout concepts on ConstraintSets, Transitions, cubic Bézier curves, and KeyFrames before diving into the challenges and results I've found while working with it. We will cover how to go about practically using MotionLayout to deliver on complex design asks including transitions with cubic Bézier curves, reusing ConstraintSets between multiple Transitions, and switching out transitions and entire MotionScenes on the fly. Lastly I'll show how to manipulate MotionLayout ConstraintSets to achieve dynamic transitions paired with RecyclerViews.
January 2019
Vampire Android Architecture
The short version is it stands for Android ViewModel backed Presenters (VAMPS), Interactors, Routers, and Entities. The idea is to take advantage of Android's ViewModel library for data stream persistence in a single Activity app that heavily utilizes AndroidX (Navigation Component, Room, and more) to create a reactive and streamlined experience for users and developers.
- Flowables to manage streams of data and reduce the overall number of requests in the app.
Arrow's Try with Success and Failure states to manage responses and therefore have an easier time managing request results.
- ViewModel (which actually has nothing to do with MVVM, frustrating that they named it that), and has really useful properties that allow us to retain some form of state between application configuration changes including but not limited to rotation or partial or complete destruction of certain screens. Using the ViewModel library we can make the app more reactive with less code and not worry so much about the UI lifecycle.
- Room is a library meant for handling SQLite persistence and querying that evaluates SQL queries and generates performant code at compile time to ensure the validity and integrity of the Android app's local storage.
- Navigation Component is a library meant for modern Android navigation with a single Activity and many fragments. It takes care of the pain of using Fragments by handling the issues with back stack and providing a type safe way of declaring routes between Fragments.
- Scoped and autogenerated constructor injection of all subcomponent dependencies (Presenters, Interactors, Repositories, Gateways, etc). As Jake Wharton has recommended, the approach to using Dagger for dependency injection should be one where it permeates an entire application and influences its structure.
Benefits:
- Faster load times
- Faster transitions
- Better ability to code and write transitions and animations
- Much less overall code
- Far less memory usage
- Easy deep linking whether from warm or cold boot
- Less boilerplate
- Using more modern libraries to help onboard new devs in the future
Detail on VAMPIRE Components
Entity
These are the simplest building blocks of the app, and can also be referred to as Models. They can have ORM annotations, but should refrain from having any actual logic attached to them. They might implement the Comparable interface to make them easier to consistently sort.
VAMPs - ViewModel backed Presenters
These carry the presentation logic - how and what to display. If there is invalid data it knows what shade of red the view should be using. If there is an error it knows what text the view should be showing.
Interactors
These carry data or state requests from the Presenter and provide subscriptions to state or the state directly. Their job is to interact between Repositories and third party wrapper modules to fulfill such requests.
Router
The interface that allows VAMPs to navigate from one part of the app to another. The router's implementation must use fragment destinations to be consumed by the NavHost from Android's Navigation Component. Depending on the route there may be arguments that will be passed along to the receiving fragment. Some routes may refer to activities in other applications.
TravisCI & Android
CircleCI & Python
December 2014
Android MultiDex 1.0.0
TLDR;
Facebook's initial problem
Facebook's initial solution
Android Gradle 0.8.x MultiDexing
Android Gradle 1.x MultiDexing
Testing with MultiDexing
Lack of Incremental Builds
How to eliminate code
Beach creatures
StatsD Timer
Initial problem
Python context based solution
Overhead benchmark
November 2014
Testing pip requirements vs virtualenv
One of the first things most Python developers do when they have various projects going on is creating a virtualenv to isolate the development environment from the rest of the machine so that it can emulate production. This is great, except when working in a team where some people are remote or are just on the far side of the office as this can result in various developers adding, removing, or changing requirements possibly without communicating that change. Sometimes a feature requires a new dependency, or the team has decided to deprecate an old dependency. To make sure the current virtualenv installation has all the appropriate dependencies with the correct versions, I wrote a test:
Android Genymotion Testing
Android Testing
Android Facebook Login
Android GCM
jason++
I lived through 28 orbits around Sol!
Android UrbanAirship
Genymotion & Google Play
Testing iOS apps w/Jenkins
Graphite Timestack
I was reading Graphite's documentation about functions when I came across timeStack
.
Building signed iOS 8.1 apps with Jenkins
Use JNLP web start, not headless mode and not SSH with xctool. xcodebuild doesn't automatically kill or reset the iOS Simulator, which is necessary to make sure there are no leftover assets from previous builds.
October 2014
Cabot Setup
Android Genymotion Emulator
Facebook bug with test accounts
I found a bug in Facebook's API that allowed the creation of new test accounts but would return an error as a response. It was fixed within a day and resolved within 2 days.
September 2014
Graphite & Statsd Setup
Building networks with Facebook Test Accounts
Logging during tests
Testing a Django App
August 2014
Python Testing
July 2014
Android Product Flavors
- What are product flavors?
- Use cases
Android Gradle & Eclipse Compatibility
- What makes Android Studio, IntelliJ, and Android Studio incompatible
- Making Android Studio and IntelliJ play nice
- Generating .classpath for Eclipse
- Gradle plugin for Eclipse
Android Gradle Builds
- Android Gralde plugin
- Gradle Wrapper
- build.gradle
- settings.gradle
- Project structure
June 2014
Mailchimp Webhooks
- Read Mailchimp webhook spec
- Create web app
- Create url route in web app to handle HTTP POST to track unsubscribes:
- Required fields
- Persisting to database
- Required response
April 2014
Mailchimp Subscription Automation
When you're a small startup, you have zero email domain reputation. Therefore it makes sense to use email providers like Mailchimp to send out product communications to let users know about updates, new features, etcetera.
The very first thing to do is automating email subscriptions so that you're not uploading CSV dumps of your users' email addresses
Login to Mailchimp
Click here to goto the Mailchimp website and login.
Get API key
Once we're logged in we see the Mailchimp dashboard. We want to get into account settings so click on the account name on the left hand menu.
Click on Account
Click on Extras
Click on API keys
At this point if you haven't already created an API key, do so now. Select the full text of the API key and save it somewhere for later.
Create List
In Mailchimp you must specifically subscribe an email address to a list. Each list keeps track of the people who unsubscribe. Goto the Lists menu and create one. You'll be prompted for a name which users will see on confirmation emails as well as your company information and a short explanation to the user telling them why they're subscribed.
Get List ID
You should be able to find the ID of the list you just created by going to Settings and clicking on List name &s; defaults. This will take you to a page where List ID is a heading on the right side of the page.
Get Mailchimp client (Python)
$ pip install mailchimp
Subscribe a user through client
Check confirmation email
The email address you used to test the subscription API should have received a confirmation email. Only after clicking Yes, subscribe me to this list. will a record appear in the Mailchimp list you created.
The user should see a webpage with the title of your list after clicking subscribe. If you setup a link to your website the user should be able to reach it from this page.
At this point you have everything you need to automatically subscribe users to your Mailchimp lists. The best time to subscribe someone is as soon as they've signedup or registered for your product. In my experience the response time for any single Mailchimp subscribe API call can widely vary between 1-4 seconds, and therefore in applications I've added it to we make it an offline task that gets started once registration is complete.
Measuring Net Promoter Score with Delighted
There are lots of metrics to measure a startup by. Net Promoter Score is how a company can measure customer's loyalty and willingness to promote your product.
Etcetera