Skip to content

Android Fundamentals

Julian Falcionelli edited this page Apr 22, 2017 · 1 revision

What’s an Intent?

An intent is an abstract description of an operation to be performed. It can be used to start an Activity, start a Broadcast or start a Service. Also it can contain data, so for instance you can send data from one Activity to another that is being initialized.

Also you can use an intent to communicate with other applications or system services (like twitter, facebook, simple text messages).

Activity vs Fragment

An Activity is an application component that provides a screen with which users can interact in order to do something, and each activity is given a window in which to draw its user interface. But, a Fragment represents a behavior or a portion of user interface in an Activity. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running. A fragment must always be embedded in an activity and the fragment's lifecycle is directly affected by the host activity's lifecycle.

So, the main differences are that:

  • An activity can contain fragments and not the other way around. I can not put an activity inside another, but a fragment in another.
  • The life cycle of both is different.
  • I can not put an activity inside another.
  • The fragments are useful when you have to change the amount of information in a display according to their size, defining multiple layouts in the resource kit, according to the densities, if it is a tablet or phone.

How is the Activity Lifecycle?

Activity launched -> onCreate() -> onStart() -> onResume() -> Activity Running -> onPause() -> onStop() -> onDestroy() -> Activity shut down

This is the backbone of the lifecycle. Then if app remains on Pause or on Stop state for a long time, Android OS may need that memory and kill this process. In this case the app returns to onCreate(). If it's on Pause, when you get back and it's still on memory, it returns to onResume().

Intents and Intent Filters

An Intent is a messaging object you can use to request an action from another app component.

When you create an implicit intent, the Android system finds the appropriate component to start by comparing the contents of the intent to the intent filters declared in the manifest file of other apps on the device. If the intent matches an intent filter, the system starts that component and delivers it the Intent object. If multiple intent filters are compatible, the system displays a dialog so the user can pick which app to use.

Context

Not all Context instances are created equal. Depending on the Android application component, the Context you have access to varies slightly:

Application – is a singleton instance running in your application process. It can be accessed via methods like getApplication() from an Activity or Service, and getApplicationContext() from any other object that inherits from Context.

Activity/Service – inherit from ContextWrapper which implements the same API, but proxies all of its method calls to a hidden internal Context instance, also known as its base context. Whenever the framework creates a new Activity or Service instance, it also creates a new ContextImpl instance to do all of the heavy lifting that either component will wrap. Each Activity or Service, and their corresponding base context, are unique per-instance.

BroadcastReceiver – is not a Context in and of itself, but the framework passes a Context to it in onReceive() each time a new broadcast event comes in. This instance is a ReceiverRestrictedContext with two main functions disabled; calling registerReceiver() and bindService(). These two functions are not allowed from within an existing BroadcastReceiver.onReceive(). Each time a receiver processes a broadcast, the Context handed to it is a new instance.

ContentProvider – is also not a Context but is given one when created that can be accessed via getContext(). If the ContentProvider is running local to the caller (i.e. same application process), then this will actually return the same Application singleton. However, if the two are in separate processes, this will be a newly created instance representing the package the provider is running in.

Handler vs AsyncTask vs Service

A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own. Personally I use Handlers only to post changes to the UI thread. E.g. you do some computations in a background thread and post the result via handler.

AsyncTask is great when some stuff has to be done in background while in the current activity. E.g. downloading, searching for text inside a file, etc. To use it, you must subclass AsyncTask and implement the doInBackground() callback method, which runs in a pool of background threads. To update your UI, you should implement onPostExecute(), which delivers the result from doInBackground() and runs in the UI thread, so you can safely update your UI. You can then run the task by calling execute() from the UI thread.

Use Service when you've got something that has to be running in the background for extended periods of time. It's not bound to any activity. The canonical example is a music player.

How should i handle tasks that need lot of work?

By default, all components of the same application run in the same process and thread (called the "main" thread). When your app performs intensive work in response to user interaction (network access or database queries), this single thread model can yield poor performance unless you implement your application properly. When the thread is blocked, no events can be dispatched, including drawing events. From the user's perspective, the application appears to hang. Thus, there are simply two rules to Android's single thread model:

  1. Do not block the UI thread
  2. Do not access the Android UI toolkit from outside the UI thread

So if you have operations to perform that are not instantaneous, you should make sure to do them in separate threads ("background" or "worker" threads). To do this you can use Handlers or Async Tasks.

What’s a Cursor?

A Cursor is an interface that provides random read-write access to the result set returned by a database query.

What’s a Cursor Adapter?

This adapter let us expose data from a Cursor to a ListView widget.

Design Patterns

  • Singleton: The Application Class represents an singleton.
  • Observer: use with the Broadcast receiver. When one object changes state, all of its dependents are notified and updated automatically.
  • Adapter: to set the data on the listviews and recyclerviews. This pattern lets two incompatible classes work together by converting the interface of a class into another interface the client expects. It’s the adapter’s job to handle the data and send the configuration command to the correctViewHolder.
  • ViewHolder: on adapters to reuse the cells.
  • Builders.
Clone this wiki locally