Android JetPack is a collection of components, tools and architectural guidance to accelerate Android app development. It was announced during Google IO 2018. As of today, 80% of the top 1,000 apps in Google Play store are using JetPack. This year at Google IO, there have been many new updates and libraries announced. Most notably are CameraX and JetPack Compose. This talk with cover new libraries in detail with code demos.
4. CameraX (alpha)
- Backward compatible with L+ devices
- Consistent behavior across devices
- Easy to use APIs
- Based on Camera2 Apis but hides Hardware layer
5. CameraX - issues tackled
- Front/back camera switch crashes
- Optimized camera closures
- Orientation Incorrect
- Flash not firing
10. Preview API
val previewConfig = PreviewConfig.Builder().build()
val preview = Preview(previewConfig)
val textureView: TextureView = findViewById(R.id.textureView)
11. Preview API
val previewConfig = PreviewConfig.Builder().build()
val preview = Preview(previewConfig)
val textureView: TextureView = findViewById(R.id.textureView)
// The output data-handling is configured in a listener.
preview.setOnPreviewOutputUpdateListener { previewOutput ->
textureView.surfaceTexture = previewOutput.surfaceTexture
}
12. Preview API
val previewConfig = PreviewConfig.Builder().build()
val preview = Preview(previewConfig)
val textureView: TextureView = findViewById(R.id.textureView)
// The output data-handling is configured in a listener.
preview.setOnPreviewOutputUpdateListener { previewOutput ->
textureView.surfaceTexture = previewOutput.surfaceTexture
}
// The use case is bound to an Android Lifecycle with the following code.
CameraX.bindToLifecycle(this as LifecycleOwner, preview)
15. Image Analysis API
val imageAnalysisConfig = ImageAnalysisConfig.Builder()
.setTargetResolution(Size(1280, 720))
.build()
16. Image Analysis API
val imageAnalysisConfig = ImageAnalysisConfig.Builder()
.setTargetResolution(Size(1280, 720))
.build()
val imageAnalysis = ImageAnalysis(imageAnalysisConfig)
17. Image Analysis API
val imageAnalysisConfig = ImageAnalysisConfig.Builder()
.setTargetResolution(Size(1280, 720))
.build()
val imageAnalysis = ImageAnalysis(imageAnalysisConfig)
imageAnalysis.setAnalyzer({ image: ImageProxy, rotationDegrees: Int ->
// insert your code here.
})
18. Image Analysis API
val imageAnalysisConfig = ImageAnalysisConfig.Builder()
.setTargetResolution(Size(1280, 720))
.build()
val imageAnalysis = ImageAnalysis(imageAnalysisConfig)
imageAnalysis.setAnalyzer({ image: ImageProxy, rotationDegrees: Int ->
// insert your code here.
})
CameraX.bindToLifecycle(this as LifecycleOwner, imageAnalysis, preview)
19. Image Capture API (Simplified)
val imageCaptureConfig = ImageCaptureConfig.Builder()
.setTargetRotation(windowManager.defaultDisplay.rotation)
.build()
val imageCapture = ImageCapture(imageCaptureConfig)
CameraX.bindToLifecycle(this as LifecycleOwner,
imageCapture, imageAnalysis, preview)
20. Image Capture API (Advance)
val imageCaptureConfig = ImageCaptureConfig.Builder().apply {
setLensFacing(lensFacing)
setCaptureMode(CaptureMode.MIN_LATENCY)
// We request aspect ratio but no resolution to match preview config but letting
// CameraX optimize for whatever specific resolution best fits requested capture mode
setTargetAspectRatio(screenAspectRatio)
// Set initial target rotation, we will have to call this again if rotation changes
// during the lifecycle of this use case
setTargetRotation(viewFinder.display.rotation)
}.build()
21. Image Capture API (Take Photo)
fun onClick() {
val file = File(...)
imageCapture.takePicture(file,
object : ImageCapture.OnImageSavedListener {
override fun onError(error: ImageCapture.UseCaseError,
message: String, exc: Throwable?) {
// insert your code here.
}
override fun onImageSaved(file: File) {
// insert your code here.
}
})
22. Add in build.gradle
dependencies {
// CameraX core library.
def camerax_version = "1.0.0-alpha02"
implementation "androidx.camera:camera-core:${camerax_version}"
// If you want to use Camera2 extensions.
implementation "androidx.camera:camera-camera2:${camerax_version}"
}
38. ViewModel with SavedState
- ViewModel objects can handle UI configuration change
- In case of process death, we use onSaveInstanceState()
- With ViewModel SavedState
- We can save UI state in ViewModel after process death and recover it
40. ViewModel with SavedState
//In order to set up a ViewModel to receive a SavedStateHandle you need to
// create them using a Factory that extends AbstractSavedStateVMFactory.
val vm = ViewModelProvider(this, SavedStateVMFactory(this))
.get(SavedStateViewModel::class.java)
41. ViewModel with SavedState
//After that your ViewModel can have a constructor that receives a
SavedStateHandle:
class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() {
... }
42. ViewModel with SavedState
/* Storing and retrieving values
The SavedStateHandle class has the methods you expect for a key-value map:
*/
get(String key)
contains(String key)
remove(String key)
set(String key, T value)
keys()
// Code lab : https://codelabs.developers.google.com/codelabs/android-lifecycles/#6