- Writing More Code by Writing Less Code with Android Studio Live Templates
- An Android Tool Time Pro Tip
- What is this magic I speak of? Live Templates!
- Android Studio Live Templates: A Handy Reference
- Create Your Own Live Templates
- a) Task Affinity:
- In general, what is affinity?
- Where can one define Task Affinity?
- b) Launch modes:
- 1. “standard”:
- 2. “singleTop”
- 3. “singleTask”
- 4. “singleInstance”
- General Note on using “singleTask” & “singleInstance”:
- 1. “FLAG_ACTIVITY_NEW_TASK”:
- Notes:
- 2. “FLAG_ACTIVITY_SINGLE_TOP”:
- 3. “FLAG_ACTIVITY_CLEAR_TOP”:
- Live coding tasks example android
- About
- Android WorkManager Tutorial: Getting Started
- Table of Contents
- When to use WorkManager while working with background processing?
- Creating a background work with Android WorkManager
- Working with WorkRequests
- OneTimeWorkRequest
- PeriodicWorkRequest
- Constraints in Android WorkManager
- Input Data, Worker Results, and Output Data in WorkManager
- Input Data
- Join our Network of Top Engineers and Work with Top Startups & Companies!
- Worker Results and Output Data
- Observing Worker state via LiveData in WorkManager
- Closing Thoughts
Writing More Code by Writing Less Code with Android Studio Live Templates
An Android Tool Time Pro Tip
If you’ve written much Android code, you’ve probably made this mistake at least once:
What if I told you there was a way to guarantee you can avoid this mistake, and also use fewer keystrokes?
What is this magic I speak of? Live Templates!
If you’re an experienced IntelliJ user, you’re probably already aware of Live Templates — in which case skip ahead to the Android-specific templates included in Android Studio
Unless you’re getting paid by the keystroke, no one wants to write repetitive boilerplate code. It’s easier to show than explain, so here’s how they work.
As you can see, Live Templates are shortcuts displayed as code-completion options that, when selected, insert a code snippet that you can tab through to specify any required arguments.
For example, as shown above — typing “Toast” then hitting the Tab key inserts the code for displaying a new Toast with argument placeholders that you can enter, before hitting tab and moving on to the next argument.
Android Studio Live Templates: A Handy Reference
IntelliJ includes over dozens of Live Templates, and Android Studio features another 48 specific for Android development. Here’s a few of my favorites for easy reference
Live templates can also insert larger code snippets; such as starter which creates a static start(…) helper method to start an Activity:
Similarly, newInstance that creates a new Fragment instance with arguments, and ViewConstructors, adds generic view constructors to your custom View.
You can use the File > Settings > Editor > Live Templates menu option to see the full list.
Of course, if your favorite boiler plate isn’t already there, remember that you can:
Create Your Own Live Templates
Go to File > Settings > Editor > Live Templates. Click the Android group, and press the plus button to add a new Live Template.
You’ll want to choose an abbreviation to use the template, a description to remember what it does, and of course the code you’d like it to insert — like this example for writing a boolean Shared Preference value.
Notice that we’re fully qualifying the class paths, and most importantly that we replace the parts of our code snippet that will be different each time with variables indicated by wrapping the names with matching $ symbols.
With our new Live Template defined, we can type the abbreviation — select it from the autocompletion hint by pressing tab — and it will paste in our code snippet!
What code are you going to Live Templatize?
Источник
a) Task Affinity:
In general, what is affinity?
Like all of you have affinity for Android App Development,
Activities also have affinity towards default package, that is the reason all the Activities in one App falls under one task, by default.
Where can one define Task Affinity?
You define affinity per activity in your AndroidManifest.xml.
Affinity of an Activity is defined by following attribute within tag:
This parameter accepts a String. By default, every activity has same affinity as your package attribute value of mainfest tag.
Affinity of a Task is defined by the affinity of its root Activity.
b) Launch modes:
It is used to instructs Android system on how to launch a particular activity.
Two ways to define launchMode for an Activity:
Defining launch modes in Manifest File:
1. “standard”:
This is the default mode. In case you don’t define any launchMode, the new activity is launched in standard mode.
Here, a new instance of the Activity will be created — everytime.
2. “singleTop”
This is just as same as “standard” mode, except for — Android will perform an extra check “whether this activity is already on the top of the Activity Stack.”
If YES, then it won’t create a new instance of the Activity but instead it will call the onNewIntent() of the same Activity.
Have a look at the Activity Stack for “standard” & “singleTop” launch modes. Consider the Activity Intent order as: A → B → B → B
3. “singleTask”
Here, the referred Activity will be launched in the new Task.
(PS: You can notice this in Recents window)
So, you just define “launchMode”: “singleTask” and it will all work magically, huh?
Your current activity has to have a “taskAffinity” value defined other than the default package name. Or else, even though you have tagged it as “singleTask” it will still open it in the same damn Task.
One last important point to note is:
You CAN still have other Activities coming on top of this Activity, even in the newly created Task.
4. “singleInstance”
Well, this is exactly same as “singleTask” with one teeny-tiny difference.
That is:
You CANNOT have other Activities coming on top of this Activity. This Activity is a lone warrior in the Tasks playground. 😎
General Note on using “singleTask” & “singleInstance”:
When you launch an activity with a launchMode defined in Manifest, the Android system looks for the taskAffinity first. Then in the main stack of Tasks (i.e. Recents screen), Android checks if there is a task already present with the root Activity having same taskAffinity as the one for intended Activity, if Yes , then the Activity is opened in that task, else a new task is created and with Intended Activity placed at its root .
Defining launch modes using Intent Flags:
1. “FLAG_ACTIVITY_NEW_TASK”:
Now, putting it straight — this is just as same behaviour as
launchMode — singleTask.
Here, you do the same thing programmatically while creating your Intent for new Activity. Your code will look something like this:
Notes:
a) If you haven’t defined taskAffinity value different from the default one, setting this flag will have no effect. (Just like you did when using launchMode — singleTask)
b) The default behaviour of back press on newly created activity in a new task is — GO TO HOMESCREEN. If you want to go back to the Activity in your main task, that started this new Activity, then you have to define it in Manifest of your app. See the following snippet:
2. “FLAG_ACTIVITY_SINGLE_TOP”:
Again, this is same as launchMode — singleTop. You have to set the Intent Flag as follows:
Now, if the Activity to be launched is on the Top of the Activity stack, then instead of creating a new Activity, it will call onNewIntent() of the already open Activity. A sample snippet is as follows:
3. “FLAG_ACTIVITY_CLEAR_TOP”:
There are two scenarios of use here:
a) All Activities in the same Task:
As expected, this flag will clear all the Activities on the top of Intended Activity in the stack and bring it to Foreground.
b) Activities spread across different tasks:
If this flag is set along with FLAG_ACTIVITY_NEW_TASK then the system will bring the required Task that contains the intended Activity to Foreground, and clear all the Activities on the top of that Activity.
That will be a wrap on Android Tasks from my side.
Источник
Live coding tasks example android
Android testing samples
A collection of samples demonstrating different frameworks and techniques for automated testing.
BasicSample — Basic Espresso sample
CustomMatcherSample — Shows how to extend Espresso to match the hint property of an EditText
DataAdapterSample — Showcases the onData() entry point for Espresso, for lists and AdapterViews
FragmentScenarioSample — Basic usage of FragmentScenario with Espresso.
IdlingResourceSample — Synchronization with background jobs
IntentsBasicSample — Basic usage of intended() and intending()
IntentsAdvancedSample — Simulates a user fetching a bitmap using the camera
MultiWindowSample — Shows how to point Espresso to different windows
RecyclerViewSample — RecyclerView actions for Espresso
ScreenshotSample — Screenshot capturing and saving using Espresso and androidx.test.core APIs
WebBasicSample — Use Espresso-web to interact with WebViews
BasicSampleBundled — Basic sample for Eclipse and other IDEs
MultiProcessSample — Showcases how to use multiprocess Espresso.
BasicSample — Basic UI Automator sample
AndroidJunitRunnerSample — Showcases test annotations, parameterized tests and testsuite creation
JUnit4 Rules Sample
**All previous samples use ActivityTestRule or IntentsTestRule but there’s one specific to ServiceTestRule:
BasicSample — Simple usage of ActivityTestRule
IntentsBasicSample — Simple usage of IntentsTestRule
ServiceTestRuleSample — Simple usage of ServiceTestRule
- Android SDK v28
- Android Build Tools v28.03
These samples use the Gradle build system. To build a project, enter the project directory and use the ./gradlew assemble command or use «Import Project» in Android Studio.
- Use ./gradlew connectedAndroidTest to run the tests on a connected emulator or device.
- Use ./gradlew test to run the unit test on your local host.
There is a top-level build.gradle file if you want to build and test all samples from the root directory. This is mostly helpful to build on a CI (Continuous Integration) server.
AndroidX Test Library
Many of these samples use the AndroidX Test Library. Visit the Testing site on developer.android.com for more information.
Experimental Bazel Support
Some of these samples can be tested with Bazel on Linux. These samples contain a BUILD.bazel file, which is similar to a build.gradle file. The external dependencies are defined in the top level WORKSPACE file.
This is experimental feature. To run the tests, please install the latest version of Bazel (0.12.0 or later) by following the instructions on the Bazel website.
For more information, check out the documentation for Android Instrumentation Tests in Bazel. You may also want to check out Building an Android App with Bazel, and the list of Android Rules in the Bazel Build Encyclopedia.
- Building of APKs is supported on Linux, Mac and Windows, but testing is only supported on Linux.
- android_instrumentation_test.target_device attribute still needs to be specified even if —config=local_device is used.
- If using a local device or emulator, the APKs are not uninstalled automatically after the test. Use this command to remove the packages:
- adb shell pm list packages com.example.android.testing | cut -d ‘:’ -f 2 | tr -d ‘\r’ | xargs -L1 -t adb uninstall
Please file Bazel related issues against the Bazel repository instead of this repository.
- Google+ Community: https://plus.google.com/communities/105153134372062985968
- Stack Overflow: http://stackoverflow.com/questions/tagged/android-testing
If you’ve found an error in this sample, please file an issue: https://github.com/googlesamples/android-testing
Patches are encouraged, and may be submitted by forking this project and submitting a pull request through GitHub. Please see CONTRIBUTING.md for more details.
Copyright 2015 The Android Open Source Project, Inc.
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the «License»); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an «AS IS» BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
About
A collection of samples demonstrating different frameworks and techniques for automated testing
Источник
Android WorkManager Tutorial: Getting Started
Table of Contents
Android WorkManager is a background processing library which is used to execute background tasks which should run in a guaranteed way but not necessarily immediately. With WorkManager we can enqueue our background processing even when the app is not running and the device is rebooted for some reason. WorkManager also lets us define constraints necessary to run the task e.g. network availability before starting the background task.
Android WorkManager is a part of Android Jetpack (a suite of libraries to guide developers to write quality apps) and is one of the Android Architecture Components (collection of components that help developers design robust, testable, and easily maintainable apps).
Exploring the Android Workmanager
When to use WorkManager while working with background processing?
With the evolution of Android OS over the years, there are restrictions placed on background processing, in order to optimize battery consumption and make use of device resources in an optimal way. Each new Android release, starting from android marshmallow (API 23), has added some restrictions. You can read about the specific details on the same in the Android developer guide.
Thus, it is important to choose the best background processing approach for your app per your needs. Let’s quickly talk about cases when you would choose to use WorkManager.
Android WorkManager can be a perfect background processing library to use when your task –
1. Does not need to run at a specific time
2. Can be deferred to be executed
3. Is guaranteed to run even after the app is killed or device is restarted
4. Has to meet constraints like battery supply or network availability before execution
The simplest example for this can be when your app needs to upload a large chunk of user data to the server. This particular use case meets the criteria we mentioned above to choose WorkManager because:
1. Results need not be reflected immediately in your Android app
2. Data needs to be uploaded even when the upload begins and the user kills the app to work on some other app, and
3. The network needs to be available in order to upload data on the server.
This blog by Pietro Maggi, Android Developer Advocate @Google gives a detailed explanation about when and how to use WorkManager.
Creating a background work with Android WorkManager
To get started with implementing WorkManager, we first need to create a work which defines the task we need to run in the background using WorkManager. For brevity, we will consider uploading user data to server as our use case throughout this article. To define work, we will create a class which extends the Worker class. The task to be performed in background is written in the overridden method doWork().
The code below shows an example of how to write a Worker class.
Working with WorkRequests
After we define our work, we now need to define how and when we should start the work. One of the advantages of using WorkManager is that we can define whether our work is a one-time task or the work needs to be called periodically.
OneTimeWorkRequest
OneTimeWorkRequest is a concrete implementation of the WorkRequest class which is used to run WorkManager tasks that are to be executed once. The code below shows how to create OneTimeWorkRequest in its simplest form:
In order to run this work request, we need to call enqueue() method on an instance of WorkManager and pass this WorkRequest as shown below:
The enqueue() method enqueues one or more WorkRequests to be run in the background.
PeriodicWorkRequest
PeriodicWorkRequest, as the name suggests is used to run tasks that need to be called periodically until cancelled.
A few important points to keep in mind when working with PeriodicWorkRequest:
1. The work is run multiple times
2. The work keeps on executing periodically until it is cancelled
3. The first execution happens immediately after the mentioned constraints are met and the next execution occurs after the mentioned period of time
4. Recurring execution doesn’t begin if the constraints mentioned with that work request are not met
5. The minimum repeat interval is 15 minutes
6. The work cannot be chained with other work requests
7. The time interval between 2 periodic intervals can differ based on OS optimization restrictions we saw earlier
A PeriodicWorkRequest can be executed as shown below:
The code above creates a periodic work request which is executed every 24 hours.
In order to stop the execution of periodic work, it needs to be explicitly cancelled:
Constraints in Android WorkManager
WorkRequests can also be built with some constraints that need to be satisfied in order to execute the task. Constraints in WorkManager are specifications about the requirements that must be met before the work request is executed. For our use case, if we need to upload user data on our server, having network availability is a must. Thus, through the work request constraints, we can make sure that our upload task is executed only when the network is available as shown below:
There are many other constraints available with Android WorkManager including ‘requires charging’, ‘storage is not low’, ‘device is not idle’, etc. A list of all these constraints can be found below:
One work request can have multiple constraints defined on it. In case of multiple constraints, the work is executed only when all the constraints are met. If any constraint is not satisfied, the work is stopped and resumed only when that constraint is met.
Input Data, Worker Results, and Output Data in WorkManager
Input Data
Running your background task often needs some data to work on. Like in our example, if we want to send user data to the server via a Worker, we need to pass that user data to the Worker task. In Android WorkManager, we can do so by using the Data class. The input data is nothing but a list of key-value pairs. The data can be passed to the WorkRequest as shown below:
As seen in the code above, the data can be constructed in 2 ways:
1. By using workDataOf() method which is part of KTX and which converts list of pairs as Data
2. By using the Data.Builder class which constructs a map from the passed key-value pairs and builds Data from this map
In order to access this input data inside the Worker, getInputData() is called inside the doWork() method to extract individual values from their keys like this:
Join our Network of Top Engineers and Work with Top Startups & Companies!
Worker Results and Output Data
Result class is used to return the status of our worker task. doWork() method of the Worker class which is overridden to do the background tasks, expects an object of class Result as its return type. Work Result can be of three types:
1. Result.success() – This result indicates that the work was completed successfully
2. Result.failure() – This result indicates that the work was permanently terminated and that if there is any chain of workers following this worker, all the following workers will also be terminated. So we should return Result.failure() only when our chain of workers is dependent on this worker’s output
3. Result.retry() – This result indicates that the work is terminated for some reason and that it should be retried/ re-executed
Great, so what if we also want to pass some output data back from the worker once our background processing is over?
The methods, success() and failure() of the Result class take in Data as an argument. This Data is same as the one used for Input Data and can constructed in the same manner, with a list of key-value pairs.
An example of passing output data from Worker is shown below:
But how do you access this output data from the Worker?
If you follow android developer’s official documentation, you might try to extract the output by using WorkInfo like this:
If you execute the code above, you will notice that the output data is never passed from the worker and the method getBoolean() on outputData will just resort to returning the default value i.e. false. We can double check if we have indeed passed output data from the worker but the behaviour still remains the same.
The reason behind not getting any output data is that the Worker executes all the tasks in background synchronously. When we attempt to fetch the output data from the WorkInfo, we try to fetch the output data before the worker is even executed. You can check this by running getStatus() method on the WorkInfo instance.
Calling the state immediately after enqueuing the WorkRequest will give the state as ENQUEUED and hence don’t get any output data.
To get the output data, we need to observe the WorkInfo via LiveData so that our app will attempt to retrieve the output data only when the worker is finished with its execution.
Observing Worker state via LiveData in WorkManager
Android WorkManager lets you observe the states of the Worker by returning LiveData for the requested WorkInfo and observing this LiveData for any changes. Thus, now to access the output data, we need to write an observer on the WorkInfo LiveData, check if its state is SUCCEEDED, and then extract the output data. Check the code below:
Closing Thoughts
To summarise, we looked at:
- What Android WorkManager is
- When exactly to use WorkManager (for background processing)
- How to execute it and applying constraints
- Passing data to and from the WorkManager workers
- Observing WorkManager task for output data
With these basics in mind, I hope you will now be able to implement deferrable background tasks on modern-day android devices running upgraded android OS after lollipop.
We cover basic and advanced programming concepts in simple language yet in a lot of detail. Do give it a look.
Источник