Profile

Cover photo
Joanna Smith
Works at Google
4,721 followers|894,669 views
AboutPostsCollections

Stream

Joanna Smith

Shared publicly  - 
 
 
SharedPreferences is your answer to simple storage
Pro-tip by +Joanna Smith

Most apps have some sort of user state that they’d like to keep track of. But many apps don’t store a lot of information. So if you don’t need to worry about internal/external storage, and you don’t want to put yourself through that, then you’ve got a friend in SharedPreferences. Check out the blog post (https://goo.gl/c8KUAF) to learn everything you need about those key-value pairs!
9 comments on original post
11
Stacy Devino's profile photoHossein Kurd (Kurdia)'s profile photoChris P's profile photo
3 comments
Chris P
 
what is the reason for not using primitive integer or resource ids for the keys? a persistent SparseArray..
Add a comment...

Joanna Smith

Shared publicly  - 
 
 
Snackbar: The appropriate interruption

Alerts are pretty critical for communicating with your user. But it helps to know what is appropriate so that your users don’t hate you. Fortunately, there’s a simple answer: use a Snackbar (http://goo.gl/u2Znrv)!

But, for those nuanced cases where you want to choose between a Toast and a Snackbar, the design docs (http://goo.gl/AHUuwR) have pretty much every detail you could need. And if you really like being wrong, there’s always a Dialog! (http://goo.gl/eC306F)
But you’re better than that.

So watch the video, and read the blog post (https://goo.gl/zDEss9), and continue to #BuildBetterApps.
10 comments on original post
15
1
Sergey Nn's profile photo
Add a comment...

Joanna Smith

Shared publicly  - 
 
It's happening!
 
What’s better than Android Development Patterns? How about even more Android Development Patterns! Season 2 is coming soon!

#BuildBetterApps

https://goo.gl/ObMeAI
14 comments on original post
12
Add a comment...

Joanna Smith
moderator

Development Patterns  - 
 
Audio Focus is clearly your BFF.
 
How to properly handle audio interruptions
Pro-tip by +Joanna Smith

The system will never let your super-awesome podcast app play over a phone call (obviously), but you can bet your users will hate you if you don’t pause audio playback when they take a phone call. If that user hangs up to discover that they missed the last 12 minutes of the story, that’s on you.

So, use audio focus to communicate with the system. Let it know when you’re playing that podcast, and let it tell you when something higher-priority may be interrupting. Learn everything you’ll need to react to those audio focus states and create the best podcast app ever in our blog post (https://goo.gl/lyw4p5). (Or whatever audio makes your heart flutter.) Because that’s how you #BuildBetterApps.
15 comments on original post
7
1
Evan Halley's profile photo
Add a comment...

Joanna Smith

Shared publicly  - 
 
 
Up your app’s sharing game with Direct Share
Pro-tip by +Joanna Smith

Marshmallow’s Direct Share feature (http://goo.gl/lMYaJX) made it easy to create a custom Share experience without too much hassle. Your app can specify direct share targets that will be displayed in the Share dialog presented to the user. So instead of launching your app, you can now launch a specific conversation in response to a Share intent.

Read our full blog post (https://goo.gl/6Rv2o8) to learn how to adapt your app for Direct Share. Because it's a pretty great way to #BuildBetterApps.

This week, as you send pictures, messages, goofy drawings, and humble-brags about your sweet gifts, sharing will suddenl…
29 comments on original post
9
2
Matthew Garbett's profile photoDavid Corrado's profile photoNick Martens's profile photo
 
+Joanna Smith ​it would be great if hangouts used this.
Add a comment...

Joanna Smith
moderator

Development Patterns  - 
 
Remember the real goal: build an app you'd want to use. Your architecture should support that.
 
Design for Offline: Android App Architecture Best Practices
Pro-tip by +Joanna Smith

Having a solid code base to work off of can make it so much easier to build better apps. +yiğit boyar and +Adam Powell talked at #AndroidDevSummit about Android Application Architecture patterns and best practices (https://goo.gl/CXjzY8). Their main point? Design your app to work offline, and it’ll work beautifully all the time. And, as promised, they released their sample code (https://goo.gl/QiBbgD), so that you can see it for yourself.

Adam and Yigit illustrated these best practices by walking the audience through some common scenarios to avoid, by offering clear and actionable advice, and by showing off a true use case with a client-server demo. But ultimately, everything circled back to the idea that your app should be offline-capable first, and cloud-synced second. Because users don’t care if the network is bad. They just see your app “freezing up” and they uninstall you.

Is your app UI dependent on the network?
This is a great opportunity for something to go wrong. For example, if you’ve got a progress dialog while you kick off that background process or, even worse, until the network responds, then you are doing it wrong. The suggested solution? Have a Model between your ViewController and any network access. When there’s new data from the server or for the server, use events and callbacks to let your ViewController know to check in with the Model. That way you can act locally, but sync globally. You never want your app to look like it forgot something or is stuck.

Does your app distinguish between local and network tasks?
Offloading work to threads is a great idea, but you want to avoid spinning up too many threads. The question now is are you spinning up enough? It’s important to have a separate queue for local tasks vs network tasks. Because if the network queue gets hung up, the local one can continue to update the UI, get data from the user, and add to the network queue without your app showing any signs of distress. Especially since it’ll all catch up when the network signal is strong again.

Other too-obvious-to-consider architecture advice:
Design your backend for your client. Not the other way. Users only see your client.
Send your client metadata about large chunks of data, like a photo. Sending the size of an image lets you set up the UI with a placeholder, for example, while waiting on the larger download.
Activities vs fragments. It’s not either-or. Choose an approach that works for your app, and use fragments to organize so that you don’t have monster-activities.
Ugly code is okay, if it helps your users.

All of this feeds into the idea of designing for offline. Events and callbacks allow you to build an app that will succeed in a good environment anyway, but also in a bad one where the network hates you. So if you want to hear more of what Adam and Yigit had to say, check out their talk, run the sample, and then shamelessly copy all of the parts you like in order to #BuildBetterApps .
7 comments on original post
10
1
Alvyn Silou's profile photo
Add a comment...
Have her in circles
4,721 people
Andrei Catinean's profile photo
Haitham Abdel Kawy's profile photo
Sreenatha Reddy K R (Sree)'s profile photo
bikram nayak's profile photo
Banz ai's profile photo
Vithyakaran Apputhurai's profile photo
Joseph Kenner's profile photo
Oleg Semen's profile photo
Jonathan Yaniv's profile photo

Joanna Smith
moderator

Development Patterns  - 
 
Using SharedPreferences for simple storage will make your life so much easier.
 
SharedPreferences is your answer to simple storage
Pro-tip by +Joanna Smith

Most apps have some sort of user state that they’d like to keep track of. But many apps don’t store a lot of information. So if you don’t need to worry about internal/external storage, and you don’t want to put yourself through that, then you’ve got a friend in SharedPreferences. Check out the blog post (https://goo.gl/c8KUAF) to learn everything you need about those key-value pairs!
9 comments on original post
6
Add a comment...

Joanna Smith
moderator

Development Patterns  - 
 
We're back! Season 2 is here! So here's a post about interruptions.
 
Snackbar: The appropriate interruption

Alerts are pretty critical for communicating with your user. But it helps to know what is appropriate so that your users don’t hate you. Fortunately, there’s a simple answer: use a Snackbar (http://goo.gl/u2Znrv)!

But, for those nuanced cases where you want to choose between a Toast and a Snackbar, the design docs (http://goo.gl/AHUuwR) have pretty much every detail you could need. And if you really like being wrong, there’s always a Dialog! (http://goo.gl/eC306F)
But you’re better than that.

So watch the video, and read the blog post (https://goo.gl/zDEss9), and continue to #BuildBetterApps.
10 comments on original post
10
Barry Irvine's profile photo
2 comments
 
Also, how can you advise us to use Toasts when this fundamental framework issue has apparently existed for 3 years... https://code.google.com/p/android/issues/detail?id=35013
Add a comment...

Joanna Smith
moderator

Development Patterns  - 
 
 
How to properly handle audio interruptions
Pro-tip by +Joanna Smith

The system will never let your super-awesome podcast app play over a phone call (obviously), but you can bet your users will hate you if you don’t pause audio playback when they take a phone call. If that user hangs up to discover that they missed the last 12 minutes of the story, that’s on you.

So, use audio focus to communicate with the system. Let it know when you’re playing that podcast, and let it tell you when something higher-priority may be interrupting. Learn everything you’ll need to react to those audio focus states and create the best podcast app ever in our blog post (https://goo.gl/lyw4p5). (Or whatever audio makes your heart flutter.) Because that’s how you #BuildBetterApps.
15 comments on original post
11
2
杨明诚's profile photoMD JUWEL's profile photoDARSHAN PATEL's profile photo
 
beautiful
Add a comment...

Joanna Smith
moderator

Development Patterns  - 
 
You know, the holidays are actually the best time to get some dev work done. It’s a great excuse for “quiet time” when your family is getting a bit rambunctious. So take a look at Direct Share to make your app stand out as a share target.
 
Up your app’s sharing game with Direct Share
Pro-tip by +Joanna Smith

Marshmallow’s Direct Share feature (http://goo.gl/lMYaJX) made it easy to create a custom Share experience without too much hassle. Your app can specify direct share targets that will be displayed in the Share dialog presented to the user. So instead of launching your app, you can now launch a specific conversation in response to a Share intent.

Read our full blog post (https://goo.gl/6Rv2o8) to learn how to adapt your app for Direct Share. Because it's a pretty great way to #BuildBetterApps.

This week, as you send pictures, messages, goofy drawings, and humble-brags about your sweet gifts, sharing will suddenl…
29 comments on original post
5
1
Brian Pow's profile photo
Add a comment...

Joanna Smith

Shared publicly  - 
 
Remember the real goal: build an app you'd want to use. Your architecture should support that.
 
Design for Offline: Android App Architecture Best Practices
Pro-tip by +Joanna Smith

Having a solid code base to work off of can make it so much easier to build better apps. +yiğit boyar and +Adam Powell talked at #AndroidDevSummit about Android Application Architecture patterns and best practices (https://goo.gl/CXjzY8). Their main point? Design your app to work offline, and it’ll work beautifully all the time. And, as promised, they released their sample code (https://goo.gl/QiBbgD), so that you can see it for yourself.

Adam and Yigit illustrated these best practices by walking the audience through some common scenarios to avoid, by offering clear and actionable advice, and by showing off a true use case with a client-server demo. But ultimately, everything circled back to the idea that your app should be offline-capable first, and cloud-synced second. Because users don’t care if the network is bad. They just see your app “freezing up” and they uninstall you.

Is your app UI dependent on the network?
This is a great opportunity for something to go wrong. For example, if you’ve got a progress dialog while you kick off that background process or, even worse, until the network responds, then you are doing it wrong. The suggested solution? Have a Model between your ViewController and any network access. When there’s new data from the server or for the server, use events and callbacks to let your ViewController know to check in with the Model. That way you can act locally, but sync globally. You never want your app to look like it forgot something or is stuck.

Does your app distinguish between local and network tasks?
Offloading work to threads is a great idea, but you want to avoid spinning up too many threads. The question now is are you spinning up enough? It’s important to have a separate queue for local tasks vs network tasks. Because if the network queue gets hung up, the local one can continue to update the UI, get data from the user, and add to the network queue without your app showing any signs of distress. Especially since it’ll all catch up when the network signal is strong again.

Other too-obvious-to-consider architecture advice:
Design your backend for your client. Not the other way. Users only see your client.
Send your client metadata about large chunks of data, like a photo. Sending the size of an image lets you set up the UI with a placeholder, for example, while waiting on the larger download.
Activities vs fragments. It’s not either-or. Choose an approach that works for your app, and use fragments to organize so that you don’t have monster-activities.
Ugly code is okay, if it helps your users.

All of this feeds into the idea of designing for offline. Events and callbacks allow you to build an app that will succeed in a good environment anyway, but also in a bad one where the network hates you. So if you want to hear more of what Adam and Yigit had to say, check out their talk, run the sample, and then shamelessly copy all of the parts you like in order to #BuildBetterApps .
7 comments on original post
16
6
dineout cheap's profile photoNithin Raja's profile photo
Add a comment...

Joanna Smith
moderator

Development Patterns  - 
 
Read this, try it out, and then you'll never again have to do that slow backward walk when your Android friends start talking about JobScheduler. You'll be able to argue with the best of them.
 
How to name-drop JobScheduler like a pro
Pro-tip by +Joanna Smith

If you have some heavy work to do, and it doesn’t need to be done RIGHT NOW OMG NOW NOW, then I’m going to kindly ask you to use JobScheduler (http://goo.gl/1mVGiv). Because it’ll get your job done, while using other jobs to intelligently schedule the work to minimize use of the radio, which is a clear battery win. So just do it. Please.

JobScheduler was introduced in Lollipop, and is pretty cool because it doesn’t perform work solely based on time, but rather based on conditions. You can define those conditions when you are creating the job, through the JobInfo object (http://goo.gl/UNma9K). For example, you can use setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) for jobs that you want to execute when the user is on WiFi. Or you can use setPersisted(true) for jobs that you want to persist across a potential reboot. Or you can read the documentation to see how to play with other criteria you might care about, from back-off policies to time limits for scheduling the job. (Basically, this is where the magic happens, so spend some time getting this right.)

To build that JobInfo object, though, you need two things every time (the criteria are the bonus bits): a job number - to help you distinguish which job this is - and a JobService (http://goo.gl/svz1hR). Your JobService is actually going to be a Service that extends the JobService class. Which means you need to implement a few methods:

+onStartJob() is called by the system when it is time for your job to execute. This is where the one tricky part about JobScheduler exists. Your JobService runs on the main thread. That’s right, the main thread. So use onStartJob() to either perform simple work, or to kick off a background service for complicated work. If you kick off another service, you’ll need to return true, but if you’re done with everything, go ahead and return false.

+onStopJob() is called by the system if the job is cancelled before being finished. Perhaps because the conditions are no longer being met, like the device has been unplugged. So use this for safety checks and clean up. And then return true if you’d like the system to reschedule the job, or false if it doesn’t matter and the job will be dropped._

+_jobFinished() is not a method you override, and the system won’t call it. That’s because you need to be the one to call this method once your service or thread has finished working on the job. This is how to system knows to release your wakelock. If you forget, your app is going to look pretty guilty in the battery stats lineup. jobFinished() takes two parameters: the current job, so that it knows which one we are talking about, and a boolean indicating whether you’d like to reschedule the job. Perhaps your work failed for some reason. This will kick off the JobScheduler’s exponential backoff logic for you (or else the logic you specified in JobInfo).

As with any service, you’ll need to add this to your AndroidManifest.xml. What’s different, though, is that you need to add a permission that will allow this service to be a JobService.
<service
       android:name=".TotallyRealJobService"
       android:permission=“android.permission.BIND_JOB_SERVICE" >
   </service>

Finally, you schedule a job using JobScheduler (http://developer.android.com/reference/android/app/job/JobScheduler.html), which you can get from the system. Then, call schedule() using that super perfect JobInfo object that you created, and you are good to go.

Not so scary, is that? There are a lot of pieces, to be sure, and you’ll need to think carefully about when and what should trigger your job. But it’s actually pretty easy to work with. And that means you can now bring it up in conversation without fearing that you’ll suddenly seem uninformed. You go, you! (But, specifically, go #BuildBetterApps.)
13 comments on original post
8
2
Connor Mc's profile photoTim Rae's profile photoOdivar Campos's profile photoBrian Pow's profile photo
2 comments
Tim Rae
 
The main goo.gl link is pointing to the wrong place (the API page), it should be pointing to here:
https://plus.google.com/u/0/+AndroidDevelopers/posts/cEuiekwpTjU
Add a comment...
Joanna's Collections
People
Have her in circles
4,721 people
Andrei Catinean's profile photo
Haitham Abdel Kawy's profile photo
Sreenatha Reddy K R (Sree)'s profile photo
bikram nayak's profile photo
Banz ai's profile photo
Vithyakaran Apputhurai's profile photo
Joseph Kenner's profile photo
Oleg Semen's profile photo
Jonathan Yaniv's profile photo
Work
Employment
  • Google
    DPE, present
Links
Story
Tagline
You had me at "Hello, World!"
Introduction
I am a Developer Programs Engineer at Google, working with the Google+ development community.

I recently graduated from the University of Texas at Austin, having studied Computer Science, with a thesis based in CS Education.

I love learning new trivia, and trying to challenge (read: scare) myself.
Bragging rights
avid reader, adequate bowler
Basic Information
Gender
Female