Android Componets

Services
       Services are for long running processes that may need to keep running even decoupled from any activity.
       Perform long running operations in background and does not provide a user interface.
       Performing operations that need to continue even if the user leaves the activity.
       application’s activities, such as a long download (e.g., downloading an app from the Android Market) or playing music (e.g., an Android music app)
Example:
       Performing operations that need to exist regardless of activities coming and going, such as maintaining a chat connection in support of a chat application.
       Providing a local API to remote APIs, such as might be provided by a web service.
Types:
       Started : A service is "started" when an application component (such as an activity) starts it by calling startService(). Once started, a service can run in the background indefinitely, even if the component that started it is destroyed. Usually, a started service performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is done, the service should stop itself.
       Bound : A service is "bound" when an application component binds to it by calling bindService(). A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC). A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.
       Local Service : Corresponding service is running in the same application.
       Remote Service : Corresponding service is running in different application.
       For creating a service we need to extend the service class or a subclass of service like IntentService.
Life Cycle:
       onCreate(): The system calls this method when the service is first created, to perform one-time setup procedures (before it calls either onStartCommand() or onBind()). If the service is already running, this method is not called.
       onStartCommand(): The system calls this method when another component, such as an activity, requests that the service be started, by calling startService(). Once this method executes, the service is started and can run in the background indefinitely. If you implement this, it is your responsibility to stop the service when its work is done, by calling stopSelf() or stopService(). (If you only want to provide binding, you don't need to implement this method.)
       onBind :The system calls this method when another component wants to bind with the service (such as to perform RPC), by calling bindService(). In your implementation of this method, you must provide an interface that clients use to communicate with the service, by returning an IBinder. You must always implement this method, but if you don't want to allow binding, then you should return null.
       onDestroy() : The system calls this method when the service is no longer used and is being destroyed. Your service should implement this to clean up any resources such as threads, registered listeners, receivers, etc. This is the last call the service receives.
Life time of Service:
       Activities being terminated abruptly in the face of low memory issues apply in a similar fashion with services.
       Android 4.0 Ice Cream Sandwich introduces a new method, onTrimMemory(), that allows the system to better handle low memory situations specifically with services, giving them a chance to release unused or unneeded resources before having to resort to onDestroy().
Mainfest Entry:
       <service android:name=“NameofService"/>.
       If we want to require some permission of those who wish to start or bind to the service, add an android:permission attribute naming the permission we are mandating.
       Like an activity, a service can define intent filters that allow other components to invoke the service using implicit intents. By declaring intent filters, components from any application installed on the user's device can potentially start your service if your service declares an intent filter that matches the intent another application passes to startService()
Caution
       A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with our activities.
Creating a started service:
       A started service is one that another component starts by calling startService(), resulting in a call to the service's onStartCommand() method.
       An application component such as an activity can start the service by calling startService() and passing an Intent that specifies the service and includes any data for the service to use. The service receives this Intent in the onStartCommand() method.
Service class:
       Service :This is the base class for all services. When we extend this class, it's important that we create a new thread in which to do all the service's work, because the service uses our application's main thread, by default, which could slow the performance of any activity our application is running.
       IntentService :This is a subclass of Service that uses a worker thread to handle all start requests, one at a time. This is the best option if we don't require that our service handle multiple requests simultaneously. All we need to do is implement onHandleIntent(), which receives the intent for each start request so we can do the background work.
Extending the IntentService Class
       Most started services don't need to handle multiple requests simultaneously (which can actually be a dangerous multi-threading scenario), it's probably best if we implement our service using the IntentService class.
       Creates a default worker thread that executes all intents delivered to onStartCommand() separate from our application's main thread.
       Creates a work queue that passes one intent at a time to our onHandleIntent() implementation, so we never have to worry about multi-threading.
       Stops the service after all start requests have been handled, so we never have to call stopSelf().
       Provides default implementation of onBind() that returns null.
       Provides a default implementation of onStartCommand() that sends the intent to the work queue and then to our onHandleIntent() implementation.
Example of Intent service
public class HelloIntentService extends IntentService {
 /** * A constructor is required, and must call the super IntentService(String) * constructor with a name for the worker thread. */
publicHelloIntentService() {
super("HelloIntentService");
  }
/** * The IntentService calls this method from the default worker thread with * the intent that started the service. When this method returns, IntentService * stops the service, as appropriate. */
protected void onHandleIntent(Intent intent) {
/*We should do our work here like downloading a file*/
}
That's all we need: a constructor and an implementation of onHandleIntent().
If we decide to also override other callback methods, such as onCreate(), onStartCommand(), or onDestroy(), be sure to call the super implementation, so that the IntentService can properly handle the life of the worker thread.


Intent Service:
       onStartCommand() must return the default implementation (which is how the intent gets delivered to onHandleIntent()).
@Override
publicintonStartCommand(Intent intent, int flags, intstartId) {  
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
returnsuper.onStartCommand(intent,flags,startId);
 }
Extending the service class:
       An IntentService completes the task and stop itself, but while using service class the user need to stop the service.
       Local Service: override onCreate(),onStart().onStartCommand(),onDestroy(),onBind() returns null.
       startSevice(Intent service)
       Stopservice(Intent service)
Binding to local service:
       In order to create a bound service we must implement onBind() callback method to return a Ibinder that defines the interface for communication with the service.
       To request the service to run in the foreground,request the service to run in the foreground using startforeground().
       In case of calling bindservice(),onstartCommand() method is not called instead onBind() is called.
       Extending the Binder Class:If our service is private to our own application and runs in the same process as the client (which is common), we should create our interface by extending the Binder class and returning an instance of it from onBind(). The client receives the Binder and can use it to directly access public methods available in either the Binder implementation or even the Service.
       This works only if the client and service are in the same application and process, which is most common. For example, this would work well for a music application that needs to bind an activity to its own service that's playing music in the background.
       In our service, we have to create an instance of Binder that either:
       contains public methods that the client can call
       returns the current Service instance, which has public methods the client can call
       or, returns an instance of another class hosted by the service with public methods the client can call
Example for Binding to a service:
public class LocalService extends Service {
  // Binder given to clients
private final IBindermBinder = new LocalBinder();
 // Random number generator
private final Random mGenerator = new Random();
 /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */
public class LocalBinder extends Binder {
LocalServicegetService() {
 // Return this instance of LocalService so clients can call public methods
returnLocalService.this;    } }
 @Override public IBinderonBind(Intent intent) { return mBinder; }
 /** method for clients */
publicintgetRandomNumber() {
returnmGenerator.nextInt(100);   } }
protected void onStart() { super.onStart();
 // Bind to LocalService
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE); }
privateServiceConnectionmConnection = new ServiceConnection() {
@Override public void onServiceConnected(ComponentNameclassName, IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService(); mBound = true; }
@Override public void onServiceDisconnected(ComponentName arg0) {
mBound = false;} }
Using mService we call the methods of the local service class.
Binding using Messenger
       For our interface to work across different processes, we can create an interface for the service using a messenger. In this way service defines a Handler that responds to different type of Message objects. This Handler is the basis for a Messenger that can then share an IBinder with the client, allowing the client to send commands to the service using Message objects. Additionally, the client can define a Messenger of its own so the service can send messages back.
       The service implements a Handler that receives a callback for each call from a client.
       The Handler is used to create a Messenger object (which is a reference to the Handler)
       The Messenger creates an IBinder that the service returns to clients from onBind().
       Clients use the IBinder to instantiate the Messenger (that references the service's Handler), which the client uses to send Message objects to the service.
       The service receives each Message in its Handler—specifically, in the handleMessage() method.
Example:
public class MessengerService extends Service {
/** Command to the service to display a message */
static final int MSG_SAY_HELLO = 1;
 /** * Handler of incoming messages from clients. */
classIncomingHandler extends Handler {
 @Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show(); break;
default:
super.handleMessage(msg); } } }
 /** * Target we publish for clients to send messages to IncomingHandler. */
final Messenger mMessenger = new Messenger(new IncomingHandler());
/** * When binding to the service, we return an interface to our messenger * for sending messages to the service. */
@Override
publicIBinderonBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
returnmMessenger.getBinder();
  }
 }
public class ActivityMessenger extends Activity {
 /** Messenger for communicating with the service. */
   Messenger mService = null;
 /** Flag indicating whether we have called bind on the service. */
booleanmBound;
 /** * Class for interacting with the main interface of the service. */
privateServiceConnectionmConnection = new ServiceConnection() {
public void onServiceConnected(ComponentNameclassName, IBinder service) {
// This is called when the connection with the service has been // established, giving us the object we can use to // interact with the service. We are communicating with the // service using a Messenger, so here we get a client-side // representation of that from the raw IBinder object.
mService = new Messenger(service);
mBound = true;
}
public void onServiceDisconnected(ComponentNameclassName) {
  // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound = false;
} };
public void sayHello(View v) {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try { mService.send(msg); }
catch (RemoteException e) { e.printStackTrace(); } }
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); }
@Override
protected void onStart() { super.onStart();
// Bind to the service
bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE); }
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false; } } }
       Note: Only activities, services, and content providers can bind to a service—you cannot bind to a service from BroadCastReceiver.
       Implement ServiceConnection. Your implementation must override two callback methods:
       onServiceConnected() The system calls this to deliver the IBinder returned by the service's onBind() method. onServiceDisconnected() The Android system calls this when the connection to the service is unexpectedly lost, such as when the service has crashed or has been killed. This is not called when the client unbinds.  a service from a broadcast receiver.
       Call bindService(), passing the ServiceConnection implementation.
       When the system calls your onServiceConnected()callback method, you can begin making calls to the service, using the methods defined by the interface.
       To disconnect from the service, call unbindService().
       Note: You should usually not bind and unbind during your activity's onResume() and onPause(), because these callbacks occur at every lifecycle transition and you should keep the processing that occurs at these transitions to a minimum. Also, if multiple activities in your application bind to the same service and there is a transition between two of those activities, the service may be destroyed and recreated as the current activity unbinds (during pause) before the next one binds (during resume).
       START_NOT_STICKY: If the system kills the service after onStartCommand() returns, do not recreate the service, unless there are pending intents to deliver.
       START_STICKY: If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with a null intent, unless there were pending intents to start the service, in which case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.
       START_REDELIVER_INTENT: If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand() with the last intent that was delivered to the service. Any pending intents are delivered in turn. This is suitable for services that are actively performing a job that should be immediately resumed, such as downloading a file.
                                BroadCastReceivers
       A broadcast receiver is a component that responds to system-wide broadcast announcements. Many broadcasts originate from the system—for example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Applications can also initiate broadcasts—for example, to let other applications know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More commonly, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work. For instance, it might initiate a service to perform some work based on the event. A broadcast receiver is implemented as a subclass of BroadcastReceiver and each broadcast is delivered as an Intent object.
Registering in Manifest file:
<receiver android:name=".Activity_Name">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"/>
</intent-filter>
</receiver>
       We have to override the onReceive(Context context,Intent intent) method.
privateBroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "Received", Toast.LENGTH_LONG).show();
  }
};
Broadcasting a Intent:
Intent broadcast = new Intent();
broadcast.setAction(BROADCAST_ACTION);
sendBroadcast(broadcast);
The BROADCAST_INTENT should be same as mentioned for the intent filter while registering in the mainfest.
Registering the receiver Dynamically:
We can register the receiver in onResume() of our activity.
IntentFilter filter = new IntentFilter();
filter.addAction(DemoBroadcast.BROADCAST_ACTION);
registerReceiver(receiver, filter);
For unregistering the receiver we can unregister it in onPause().
unregisterReceiver(receiver);
AsyncTask
       AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
       AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If we need to keep threads running for long periods of time, it is highly recommended that we use the various APIs provided by the java.util.concurrentpacakge such as Executor, ThreadPoolExecutor and FutureTask.
       An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
AsyncTask’s Generic Types
       The three types used by an asynchronous task are the following:
       Params, the type of the parameters sent to the task upon execution.
       Progress, the type of the progress units published during the background computation.
       Result, the type of the result of the background computation.
       When an asynchronous task is executed, the task goes through 4 steps:
       onPreExecute(), invoked on the UI thread immediately after the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
       doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
       onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
       onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
Threading rules
       There are a few threading rules that must be followed for this class to work properly:
       The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
       The task instance must be created on the UI thread.
       execute(Params...) must be invoked on the UI thread.
       The task can be executed only once (an exception will be thrown if a second execution is attempted.)
Example for AsyncTask:
classProgressTask extends AsyncTask<Integer,Integer,Void>{
              @Override
       protected Void doInBackground(Integer... params) {
             // TODO Auto-generated method stub
       int start = params[0];
       for(int i=start;i<=100;i+=5){
       try {
       boolean cancelled=isCancelled();
         //if async task is not cancelled, update the progress
       if(!cancelled){
       publishProgress(i);
       SystemClock.sleep(1000);
         }
         } catch (Exception e) {
       Log.e("Error", e.toString());
         }
         }
       Log.d("Anki", "doInBackground Called");
       return null;
             }
             @Override
       protected void onCancelled() {
             // TODO Auto-generated method stub
       progress.setMax(0);
       Log.d("Anki", "onCancelled Called");
       super.onCancelled();
             }
             @Override
       protected void onPostExecute(Void result) {
             // TODO Auto-generated method stub
       Log.d("Anki", "onPostExecute Called");
       super.onPostExecute(result);
      }
       @Override
       protected void onPreExecute() {
             // TODO Auto-generated method stub
       progress.setMax(100);
       Log.d("Anki", "onPreExecute Called");
       super.onPreExecute();
             }
             @Override
       protected void onProgressUpdate(Integer... values) {
             // TODO Auto-generated method stub
       progress.setProgress(values[0]);
       Log.d("Anki", "onProgressUpdate Called");
       super.onProgressUpdate(values);
             }   
             }

Comments

Popular posts from this blog

Android Objective type Question and Answers

Android Questions and Answers for written exams

SCJP1.6 Question and Answers