Blog

Android

Android’s Camera2

The android.hardware.camera2 package provides an interface to individual camera devices connected to an Android device. It replaces the deprecated Camera class.

This package models a camera device as a pipeline, which takes in input requests for capturing a single frame, captures the single image per the request, and then outputs one capture result metadata packet, plus a set of output image buffers for the request. The requests are processed in-order, and multiple requests can be in flight at once. Since the camera device is a pipeline with multiple stages, having multiple requests in flight is required to maintain full framerate on most Android devices.

To enumerate, query, and open available camera devices, obtain a CameraManager instance.

Individual CameraDevices provide a set of static property information that describes the hardware device and the available settings and output parameters for the device. This information is provided through the CameraCharacteristics object, and is available through getCameraCharacteristics(String)

To capture or stream images from a camera device, the application must first create a camera capture session with a set of output Surfaces for use with the camera device, with createCaptureSession(List, CameraCaptureSession.StateCallback, Handler). Each Surface has to be pre-configured with an appropriate size and format (if applicable) to match the sizes and formats available from the camera device. A target Surface can be obtained from a variety of classes, including SurfaceViewSurfaceTexture via Surface(SurfaceTexture)MediaCodecMediaRecorderAllocation, and ImageReader.

Generally, camera preview images are sent to SurfaceView or TextureView (via its SurfaceTexture). Capture of JPEG images or RAW buffers for DngCreator can be done with ImageReader with the JPEG and RAW_SENSOR formats.

The application then needs to construct a CaptureRequest, which defines all the capture parameters needed by a camera device to capture a single image.

Once the request has been set up, it can be handed to the active capture session either for a one-shot capture or for an endlessly repeating use. Both methods also have a variant that accepts a list of requests to use as a burst capture / repeating burst. Repeating requests have a lower priority than captures, so a request submitted through capture() while there’s a repeating request configured will be captured before any new instances of the currently repeating (burst) capture will begin capture.

After processing a request, the camera device will produce a TotalCaptureResult object, which contains information about the state of the camera device at time of capture, and the final settings used. These may vary somewhat from the request, if rounding or resolving contradictory parameters was necessary. The camera device will also send a frame of image data into each of the output Surfaces included in the request. These are produced asynchronously relative to the output CaptureResult, sometimes substantially later.

 

Advertisements
Android

:Picasso

Picasso is the best image library I have used for Android. Picasso is best used for displaying remote images. The library handles every stage of the process, from the initial HTTP request to the caching of the image. This can be quite verbose when writing code to perform these actions yourself.

With just a line of code,
Picasso.with(this).load(“your_image_url”).into(imageview);
you can load a remote image.

Right, so what are the reasons to use Picasso?

  1. It simplifies the process of loading images from external urls and display on your application. For example, downloading an image from server, is one of the most common task in any application. And it needs quite a larger amount of code to achieve this via android networking API’s. By using Picasso, you can achieve this with a few lines of code.
  2. It is always not about downloading image from remote location. You also have to think of implementing image caching logic in order to provide a seamless user experience. Picasso provides automatic image caching.
  3. Image transformation is a costly affair. If your application need deal with such runtime image transformation, you must be watchful about OutOfMemoryException. Picasso deals with it, so you don’t have to do it yourself.
Android

RxJava2 for Android: part 4

Operators do three things:

  • Manipulate or combine data in some way.
  • Manipulate threading in some way.
  • Manipulate emissions in some way.

In the reactive world, you would have an Observable and you would apply an operation via an operator. For example, map is the operator, which allows you to take data being emitted and apply some operation to it to create a new type of that data.

Using operators, you can also decide on which thread you want your code to get executed on. The order that you apply these operators really matters.

If you are doing a network request, that network request is still going to be done synchronously, but you don’t want it to happen on the main thread. You can apply an operator that changes where you subscribe to the Observable, which is where the work ultimately happens.

OkHttpClient client = // …
Request request = // …
Observable<Response> response = Observable.fromCallable(() -> {
    return client.newCall(request).execute();
}).subscribeOn(Schedulers.io())
.map(response -> response.body().string()) // Ok!
.observeOn(AndroidSchedulers.mainThread());

I/O is just a thread pool of threads you can use, and it will do work on that thread pool, and then send out the notification to whoever is listening. subscribeOn here being the operator to change where the work happens.

It’s nice that these all return a new Observable, because you can compose them and chain them together. What you normally see is that you don’t have intermediate variables for these. You are just applying the operators in a certain order. You want to request to execute on the background thread. You want to observe the result of that request on the main thread. You want to change the response into a string. You want to read the string. Order here matters.

Because I applied the map operator after observeOn, that’s going to run on Android’s main thread. We don’t want to be reading from an HTTP response on the main thread, we want that to be happening before we change to the main thread. The request comes in, and it emits the response down the Observable chain. We map that into the result string, and then we change threads to the main thread, where we can ultimately subscribe and show it in the UI.

Android

RxJava2 for Android: part 3

An important static method of Observable is fromCallable.

OkHttpClient client = // …
Request request = // …
Observable.fromCallable(new Callable<String>() {
    @Override public String call() throws Exception {
        return client.newCall(request).execute();
    }
});

fromCallable is essentially modeling some synchronous behavior that returns a single value. The nice thing about fromCallable is that you are allowed to throw an exception from a callable.  If you have an HTTP request that you want to make which could throw an I/O exception you can now put that inside a fromCallable. The returned Observable, when subscribed to, will execute that request, and if that request throws an exception you will get an on error. If that request completes, you will get the response, an onNext.

 

 

Android

RxJava2 for Android: part 2

As explained in the previous installment, Observables and Flowables can be viewed as streams. These data streams don’t necessarily have to take the form of traditional data types, as RxJava pretty much treats everything as a stream of data- everything from variables to properties, caches, and even user input events like clicks and swipes. The data emitted by each stream can either be a value, an error, or a “completed” signal. Once you’ve created your data-emitting streams, you combine them with reactive objects that consume and then act on this data, performing different actions depending on what the stream has emitted. RxJava includes a whole bunch of useful operators to work with streams, making it easy to do things like filtering, mapping, delaying, counting, and much more.

observable

To create this workflow of data streams and objects that react to them, RxJava extends the Observer software design pattern. Essentially, in RxJava you have Observable objects that emit a stream of data and then terminate, and Observer objects that subscribe to Observables. An Observer receives a notification each time their assigned Observable emits a value, an error, or a completed signal.

So at a very high level, RxJava is all about:

  • Creating an Observable.
  • Giving that Observable some data to emit.
  • Creating an Observer.
  • Assigning the Observer to an Observable.
  • Giving the Observer tasks to perform whenever it receives an emission from its assigned Observable

An Observable is similar to an Iterable in that, given a sequence, it’ll iterate through that sequence and emit each item, although Observables typically don’t start emitting data until an Observer subscribes to them.

Each time an Observable emits an item, it notifies its assigned Observer using the onNext() method. Once an Observable has transmitted all of its values, it terminates by calling either:

  • onComplete: Called if the operation was a success.
  • onError: Called if an Exception was thrown.

onNext is the method where items are going to be delivered. As long as there is one or more items being produced by the Observable or Flowable, this method will be called for each one, allowing you to do whatever processing you want to do with the items. This could be infinite. If you are listening to a button click, this onNext method will be called every time the user clicks a button. For non-infinite sources, we have those two terminal events. They either can complete, where complete indicates success, or they can error, where error indicates that either processing the onNext callback resulted in an exception being thrown. Both onComplete, and onError are called terminal events, which means you will never get another callback after you get either one of those.

.An example below there is an Observable that emits the numbers 12and 4, and then terminates.

Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
  @Override
  public void subscribe(ObservableEmitter<Integer> e) throws Exception {
      //Use onNext to emit each item in the stream//
      e.onNext(1);
      e.onNext(2);
      e.onNext(3);
      e.onNext(4);
      //Once the Observable has emitted all items in the sequence, call onComplete//
      e.onComplete();
  }
 }
);

Observers are objects that you assign to an Observable, using the subscribe()operator. Once an Observer is subscribed to an Observable, it’ll react whenever its Observer emits one of the following:

  • onNext: The Observable has emitted a value.
  • onError: An error has occurred.
  • onComplete: The Observable has finished emitting all its values.
Observer<Integer> observer = new Observer<Integer>() {
  @Override
  public void onSubscribe(Disposable d) {
      Log.e(TAG, "onSubscribe: ");
  }
  @Override
  public void onNext(Integer value) {
      Log.e(TAG, "onNext: " + value);
  }
  @Override
  public void onError(Throwable e) {
      Log.e(TAG, "onError: ");
  }
  @Override
  public void onComplete() {
      Log.e(TAG, "onComplete: All Done!");
  }
};
//Create our subscription//
observable.subscribe(observer);
Android

RxJava2 for Android: part 1

Unless you can model your entire system synchronously, a single asynchronous source breaks imperative programming. Not “break” in the sense that it stops working, but in the sense that it pushes the complexity onto you, and you start losing the things that imperative programming is really good for.

You need to think reactively in your app. Most of the things in it are essentially asynchronous. Network interactions need to be done in separate threads asynchronously, database interactions have to be done in separate threads asynchronously, and even the user interactions are asynchronous in nature. By clinging to more traditional imperative programming and state management techniques, you’re ultimately harming yourself.

15

The model above is pretty problematic. You need to take this model, where the code sits in the middle, as the arbiter of state, and trying to coordinate all these asynchronous things, and instead of having that, you can remove your responsibility by hooking these things up directly. You can change the UI to subscribe directly to the database, and just react when the data changes. You can change the database and network call to just react when the button is clicked, instead of you having to receive that click, and then dispatch it. Similarly, the network response comes back; it would be nice if that just updated the data, and you know now that when the data updates, the UI automatically updates, and so you removed your responsibility for doing that. If Android does something asynchronously, like rotating, it would be nice if that was automatically reflected in the UI, or automatically started some background job. Ultimately that removes a lot a code you had to write in order to maintain those states yourselves.

Okay, so what’s RxJava? RxJava is the Java implementation of Reactive Extensions. And Reactive Extensions is the .Net implementation of Reactive Programming. Reactive programming is a programming paradigm oriented around data flows and the propagation of change.

RxJava has:
1. A set of classes for representing sources of data.
2. A set of classes for subscribing to that data, and listening to when it changes.
3. A set of methods for modifying and composing the data so you can end up creating those links between the different asynchronous sources of data and the things that subscribe and display it.

The two main types in RxJava2 that can represent the sources of data are Observable and Flowable. These both end up modeling the same types of data, which can be zero to n items. It can be empty, it can have a single item, or potentially many, and then they terminate either successfully or with an error.

Why do you need two types to represent the same structure of data?
This comes down to something called “backpressure”. Systems which have finite resources, and backpressure is a way to tell all of the people sending you data to slow down since you can’t process it as fast as they are sending. For example, if you have a source of data which is touch events, this is something you can’t really slow down: you can’t tell the user, “draw half of your curve, and then stop and wait while I catch up drawing, and then you can continue the rest.” You can potentially do this in other ways, such as disabling buttons or displaying other UI to try to slow them down, but the source of data itself is not one that can be slowed down. You can compare that to something like a database, where you have a large result set, and maybe you only want to pull out certain rows at a time. A database can model this really well: it has the concept of cursors. But a stream of touch events can’t model this at all, because there’s no way to push back and slow down the user’s finger. In RxJava1, you would see both of these types implemented as Observables, so at runtime you might try and apply backpressure and you ultimately get an exception, and your app crashes. In RxJava2 you model them as different types, because one fundamentally can support backpressure and one fundamentally cannot.

 

Android

Services

Services are how an application indicates to the OS that it needs to perform a longer running operation outside the UI flow. But the Service does the work in the Main Thread. It is advised to not use a Service at all for 90% of the use cases. But if you still want to use Services, make sure you stop them after use. There are two distinct ways to terminate them. Started Services (via onStartCommand()) stay alive until they are explicitly stopped with a stopSelf() or a stopService() call. Until then the Service just sits around waiting to process things and eating up resources. A bound Service stays around until only all of its clients unbind from it calling unbindService(). Mixing these two is useful but it’s a common source of errors.

14

As you can see from the above figure, even after unbinding the Service, it will stay around hogging memory until it’s stopped. NEVER LET SERVICES EXIST FOR LONGER THAN THEY SHOULD BE.