Wednesday, June 22, 2016

Paradigm shift in the World of Mobile Computing...

Since the day of July 1991 when the GSM network was first made operational in Finland lot of things have changed.

In earlier days of Mobile Communication, the communication part was important and it was the most challenging part of mobile computing. Lots of research has taken place to develop a Mobile Switching Center, Base Station Controller, etc. Not only that, lots of inputs have been made to define how the different MSCs will communicate with each other and how the interfaces between different parts of the network elements like Um, Abis, B interface, and C interface will function.

In those days, stresses were given to define Traffic Channel and Signalling Channel. Common Control Channel (CCCH) or Dedicated Control Channel (DCCH) were more important than the mobile device itself. Modulation and technologies like Frequency Hopping Spread Spectrum were more important than the voice and data itself.

But days have changed. Once the telecommunication part of mobile computing is more or less established and the OFCN is laid down, the focus is now on the usefulness of the data and the voice itself or what we do with the data that are being transmitted over the network. The focus shifted from the network part to the mobile device part.

And with the advent of smartphones, it is the Apps that have become more important than any other parts of the mobile ecosystem. The apps have created a complete paradigm shift in the mobility world and it is taking the world of mobility to a different concept altogether.

From late 2007 to approximately 2010 were the years when mobile apps became multi-billion dollar businesses. And it forced every organization to take a policy that is called the Mobility First policy. It means that for each and every service that a company offers, it first takes care of the mobile platform.

And the latest paradigm shift in the mobility world is mobile social computing. We have seen the proliferation of social apps like Facebook, Google Plus, Instagram, LinkedIn, Twitter, and many others and I can say that these apps are shaping the behaviors of mobile users.

With this ever-changing mobile world, the engineers also had to align themselves accordingly. For example, I started my career as a Telecommunication engineer in SIEMENS India and now working on the Android platform after working on other mobile OS like Symbian S60. To do that I had to unlearn many things related to the mobile network world and relearn software like C++, Java, Design Pattern, UML, and such things. So here I am now. I was able to successfully transform myself from a telecommunication engineer to a mobile software engineer and presently working on Android.

Probably many people of my age who started their career in 1994-95, have undergone such transformation. There were always some teething problems in this change management, but I feel happy that I have seen the world of mobile telecommunication changing in front of my eyes…

Today this Android app which you can install from https://tinyurl.com/y752chtb
that describes the call setup of GSM GSM-originated call to a PSTN number is my tribute to the change of priority of technologies in the world of telecom - from a Telecomm-centric domain to an App-centric world...

Friday, June 3, 2016

Android Graphics & Animation

Here are my Youtube tutorial videos explaining Android Graphics and Animation. Hope you will  enjoy it.














Monday, December 28, 2015

Developing a POI REST Client using Asynctask and integrating it with Google Map

Wednesday, November 25, 2015

Concurrent Programming in Android - Part II

Note : Here are my two tutorials on Android Concurrency Model. Please have a look at these:
  1. https://youtu.be/zWdVVI7kH4E
  2. https://youtu.be/1J6iqKJgvDU
In the part - I of the discussion on concurrent programming in Android, we have seen about the Handler-Message-Runnable & Asynchronous task framework. There we took a case study of downloading an image from an Internet server and found out how these methodologies can be applied for a long running task which has to be done in a background thread.

With the continuation of the same discussion we will today talk about the internals of the Android Concurrency Model - particularly about the topics like Looper, Message Queue, Handler and and how they work together to give us a better concurrent system. We will also develop an example in which we will pass a message from the main UI thread to a background worker thread immediately after the worker thread is created. We will also see the usefulness of the Java Synchronization technique, specifically the CountdownLatch synchronization object.

Here is a simplified diagram of Asynchronous Model of Android which shows how we can post Runnables or send Messages through Handler to the MQ of the Looper.



At the heart of any UI driven model, lies a loop called Message Loop whose task is to listen to any hardware events that the user may generate and dispatch them to the appropriate handler. In android this message looping is done by a class called Looper. The simpler version of the Looper class is as follws:

public class Looper {
    private static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    // Looper message queue
  final MessageQueue mQueue;
    // The current thread
    Thread mThread;
    // . . . Other attributes
    // The message queue for each Looper object, and it belongs to the thread
    private Looper() {
        mQueue = new MessageQueue();
        mRun = true;
        mThread = Thread.currentThread();
    }
    // Initialize the current thread as a looper.
    public static final void prepare() {
        if (sThreadLocal.get() != null) {
            // Try to have Looper thread again to create the Looper will throw an exception
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
    }
    // Other methods 
}

Important function of Looper is prepare.

As we can see from the above code that the prepare function actually constructs the Message Queue responsible for queuing up messages. Also in the prepare function we can see that there will be only one looper per thread. The looper gets stored as a Thread Local Storage object. And as we can see, the thread in which the Looper.prepare is called, becomes the looper's mThread object.

The other important function of the Looper class is the loop method. It has been defined as follows:

//Run the message queue in this thread.
public static void loop() {
//Other code
final Looper me = myLooper();//returns the current looper
//other code......
 for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
//other code...........
 msg.target.dispatchMessage(msg);
//other code....

Have a look infinite for loop and the following dispatchMessage method. This is what is responsible for listening events and dispatching those messages to the right handler.

Next important Class is the Handler class. The bare minimal version of this Handler class is as follows:
public class Handler {
    final MessageQueue mQueue;  // The associated MQ
    final Looper mLooper;  // The associated looper
    final Callback mCallback; 
    // Other attributes
    public Handler() {
//Other code ......
        // The default will be associated with the current thread looper
//returning the Thread Local storage's Looper
        mLooper = Looper.myLooper();
        // Looper cannot be empty, the construction method of the default can only be used on the looper thread
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
       //Associating the MQ with the Looper
        mQueue = mLooper.mQueue;
        mCallback = null;
    } 
    // Other methods
}

The handler class is a utility class and is responsible to help users to send messages to the Message queue. If we take the current thread's Handler to send message, the messages will be posted to the current thread's looper's Message Queue.

The main thread or the UI thread of Android will automatically have a looper. But if we want to create an worker thread, we need to specifically add the Looper for that thread. The below code is an example of such an worker thread. Lets call it as LooperThread.

class LooperThread extends Thread {
    public Handler mHandler;
    public void run() {
      Looper.prepare();
//Other works such as handler      
mHandler = new Handler() {
          public void handleMessage(Message msg) {
              // process incoming messages here
         }
      };
      Looper.loop();
   }
}

As we can see from the above code snippet, the moment we declare the above piece of code in any Android worker thread, it becomes capable of handling incoming messages.

Its all theories. Now lets write an example of sending messages from the UI thread of Android (or Activity) to a background thread. You can download the source code from here

The WorkerThread class is defined as follows:

/**
 * Created by som on 24/11/15.
 */
public class WorkerThread extends Thread{

    public Handler workerThreadHandler;
    CountDownLatch mLatch;

    public WorkerThread(CountDownLatch latch){

        mLatch = latch;
    }


    public void run() {
        Looper.prepare();
        workerThreadHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {

                Log.i("MsgToWorkerThread", "Message received from UI thread...");
                        MainActivity.getMainApp().runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.getMainApp().getApplicationContext(), "Message received in worker thread from UI thread", Toast.LENGTH_LONG).show();
                                //Log.i("MsgToWorkerThread", "Message received from UI thread...");
                            }
                        });

            }

        };
        Log.i("MsgToWorkerThread", "Worker thread ready...");
        mLatch.countDown();
        Looper.loop();
    }
}

 And the MainActivity from where the message is sent to the WorkerThread is defined as follows:

public class MainActivity extends AppCompatActivity {

    private static MainActivity mainApp;
    private CountDownLatch mCountDownLatch;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
///.....................Other Code......////
        mCountDownLatch = new CountDownLatch(1);
        mainApp = this;
        WorkerThread workerThread = new WorkerThread(mCountDownLatch);
        workerThread.start();
        try {
            mCountDownLatch.await();
            Log.i("MsgToWorkerThread", "Worker Thread is up and running. We can send message to it now...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Toast.makeText(this, "Trial run...", Toast.LENGTH_LONG).show();
        Message msg = workerThread.workerThreadHandler.obtainMessage();
        workerThread.workerThreadHandler.sendMessage(msg);
        //Toast.makeText(this, "Trial run...", Toast.LENGTH_LONG).show();
    }

This is simple. Only one issue that i would like to discuss about that to avoid the Race Condition, i have used the Java Synchronization object CountdownLatch. For this countdownlatch, we send the message only when the worker thread becomes ready.
Hope i am able to throw some lights on the internals of Android Concurrency Model.

Thursday, September 24, 2015

One way to solve the Screen Rotation problem while dealing with Android Asynctask

In many cases of Android applications employing Asynctask, the Activity that creates the Asynctask, may finish before the background job is actually done. In fact while the Asynctask is doing its job in the background, if we rotate the screen of the device, the previous Activity which created this Asynctask will be destroyed and a new instance of the same activity will be created. Hence even if the background task continues, it won't be able to update the UI, because it has already lost the connection with the previous Activity which created it. So if we were showing a ProgressDialog in the main Activity screen, it will throw runtime exception, because the Activity that created it has been already destroyed and the background task is still trying to update the previous ProgressDialog.

See the following Activity which creates an Asynctask to download an Image from a server.

package com.somitsolutions.training.android.asynctaskdownloadimage;

public class MainActivity extends Activity implements OnClickListener{
 
 Button mStartDownloadButton, mDisplayImageButton;
 EditText mURL;
 ImageView mImageView;
 private CallBack c;
 ProgressDialog mProgressDialog;
 DownloadImageAsyncTask mTask;
 Context context;
 Bitmap mBitmap;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  mStartDownloadButton = (Button)findViewById(R.id.buttonDownloadImage);
  mDisplayImageButton = (Button)findViewById(R.id.buttonDisplayImage);
  mURL = (EditText)findViewById(R.id.editTextURL);
  mImageView = (ImageView)findViewById(R.id.imageView1);
  mImageView.setVisibility(View.INVISIBLE);
  mStartDownloadButton.setOnClickListener(this);
  mDisplayImageButton.setOnClickListener(this);
  
  context = this;
  
  mProgressDialog = new ProgressDialog(this);
  mProgressDialog.setMessage("On Progress...");
  mProgressDialog.setCancelable(true);
  
   c = new CallBack() {
          
    public void onProgress(){
     if(mProgressDialog == null){
      mProgressDialog = new ProgressDialog(MainActivity.this);
     mProgressDialog.setMessage("On Progress...");
     mProgressDialog.setCancelable(true);
     }
     mProgressDialog.show();  
          }
          
          public void onResult(Bitmap result){
            mBitmap = result;
            mProgressDialog.dismiss();
            Toast.makeText(context, "Done...", Toast.LENGTH_LONG).show();
            mStartDownloadButton.setEnabled(true);
            mProgressDialog = null;
           
          }
          
          public void onCancel(){
           mProgressDialog.dismiss();
           Toast toast = Toast.makeText(getApplicationContext(), "Cancelled", Toast.LENGTH_LONG);
              toast.show();
              mProgressDialog = null;
          }
         };
 }
 @Override
 public void onClick(View v) {
  // TODO Auto-generated method stub
  if (v.equals(mStartDownloadButton)){
   String URL = mURL.getText().toString();
   URL = URL.replace(" ", "");
   
   if(URL != null &amp;&amp; !URL.isEmpty()){
    DownloadImageAsyncTask asyncTask = new DownloadImageAsyncTask(context, c);
    asyncTask.execute(URL);
    mStartDownloadButton.setEnabled(false);
   }
   
  }
  
  if(v.equals(mDisplayImageButton)){
   mImageView.setImageBitmap(mBitmap);
   mImageView.setVisibility(View.VISIBLE);
  }
 }
}

For the above Activity, if we rotate the screen when the background task is going on, the following LogCat messages will be shown:

...................
09-24 14:23:26.431: E/WindowManager(8814): android.view.WindowLeaked: Activity com.somitsolutions.training.android.asynctaskdownloadimage.MainActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{3eded954 V.E..... R....... 0,0-639,128} that was originally added here
09-24 14:23:26.431: E/WindowManager(8814): at android.view.ViewRootImpl.(ViewRootImpl.java:363)
09-24 14:23:26.431: E/WindowManager(8814): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:271)
09-24 14:23:26.431: E/WindowManager(8814): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
09-24 14:23:26.431: E/WindowManager(8814): at android.app.Dialog.show(Dialog.java:298)
09-24 14:23:26.431: E/WindowManager(8814): at com.somitsolutions.training.android.asynctaskdownloadimage.MainActivity$1.onProgress(MainActivity.java:52)
09-24 14:23:26.431: E/WindowManager(8814): at com.somitsolutions.training.android.asynctaskdownloadimage.DownloadImageAsyncTask.onProgressUpdate(DownloadImageAsyncTask.java:37)
09-24 14:23:26.431: E/WindowManager(8814): at com.somitsolutions.training.android.asynctaskdownloadimage.DownloadImageAsyncTask.onProgressUpdate(DownloadImageAsyncTask.java:1)
09-24 14:23:26.431: E/WindowManager(8814): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:656)
09-24 14:23:26.431: E/WindowManager(8814): at android.os.Handler.dispatchMessage(Handler.java:102)
09-24 14:23:26.431: E/WindowManager(8814): at android.os.Looper.loop(Looper.java:135)
09-24 14:23:26.431: E/WindowManager(8814): at android.app.ActivityThread.main(ActivityThread.java:5254)
09-24 14:23:26.431: E/WindowManager(8814): at java.lang.reflect.Method.invoke(Native Method)
09-24 14:23:26.431: E/WindowManager(8814): at java.lang.reflect.Method.invoke(Method.java:372)
09-24 14:23:26.431: E/WindowManager(8814): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
09-24 14:23:26.431: E/WindowManager(8814): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
09-24 14:23:27.764: D/AndroidRuntime(8814): Shutting down VM
09-24 14:23:27.765: E/AndroidRuntime(8814): FATAL EXCEPTION: main
09-24 14:23:27.765: E/AndroidRuntime(8814): Process: com.somitsolutions.training.android.asynctaskdownloadimage, PID: 8814
09-24 14:23:27.765: E/AndroidRuntime(8814): java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{3eded954 V.E..... R......D 0,0-639,128} not attached to window manager
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:396)
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:322)
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:116)
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.app.Dialog.dismissDialog(Dialog.java:341)
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.app.Dialog.dismiss(Dialog.java:324)
09-24 14:23:27.765: E/AndroidRuntime(8814): at com.somitsolutions.training.android.asynctaskdownloadimage.MainActivity$1.onResult(MainActivity.java:57)
09-24 14:23:27.765: E/AndroidRuntime(8814): at com.somitsolutions.training.android.asynctaskdownloadimage.DownloadImageAsyncTask.onPostExecute(DownloadImageAsyncTask.java:42)
09-24 14:23:27.765: E/AndroidRuntime(8814): at com.somitsolutions.training.android.asynctaskdownloadimage.DownloadImageAsyncTask.onPostExecute(DownloadImageAsyncTask.java:1)
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.os.AsyncTask.finish(AsyncTask.java:636)
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.os.AsyncTask.access$500(AsyncTask.java:177)
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.os.Handler.dispatchMessage(Handler.java:102)
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.os.Looper.loop(Looper.java:135)
09-24 14:23:27.765: E/AndroidRuntime(8814): at android.app.ActivityThread.main(ActivityThread.java:5254)
09-24 14:23:27.765: E/AndroidRuntime(8814): at java.lang.reflect.Method.invoke(Native Method)
09-24 14:23:27.765: E/AndroidRuntime(8814): at java.lang.reflect.Method.invoke(Method.java:372)
09-24 14:23:27.765: E/AndroidRuntime(8814): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)

09-24 14:23:27.765: E/AndroidRuntime(8814): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

...................

One way to solve this problem is to override the onPause lifecycle method of the Activity, and inside that cancel the Background task and dismiss the ProgressDialog...

But the best way to handle this situation is to create a Fragment instead of the Activity, and inside that Fragment create the Asynctask.

Here is the code of such a fragment:

package com.somitsolutions.training.android.asynctaskdownloadimage;

import android.app.Fragment;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivityFragment extends Fragment implements OnClickListener{
 
 Button mStartDownloadButton, mDisplayImageButton;
 EditText mURL;
 ImageView mImageView; 
 private CallBack c;
 ProgressDialog mProgressDialog;
 DownloadImageAsyncTask mTask;
 Context context;
 Bitmap mBitmap;
 private static MainActivityFragment app;
 Boolean isScreenRotated = false;
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setRetainInstance(true);

   c = new CallBack() {
          
    public void onProgress(){
     if(c != null && !isScreenRotated){
      if(mProgressDialog == null) {
       mProgressDialog = new ProgressDialog(getActivity());
      }
      mProgressDialog.setMessage("On Progress...");
      mProgressDialog.setCancelable(true);

      mProgressDialog.show();
      }

          }
          
          public void onResult(Bitmap result){

     if (c != null && !isScreenRotated){
      mBitmap = result;

      Toast.makeText(getActivity().getApplicationContext(), "Done...", Toast.LENGTH_LONG).show();
      mStartDownloadButton.setEnabled(true);

      if(mProgressDialog != null){
       mProgressDialog.dismiss();
       mProgressDialog = null;
      }
     }
     if (isScreenRotated){
      Toast.makeText(getActivity().getApplicationContext(),"Download not completed. Please retry...", Toast.LENGTH_LONG).show();
      isScreenRotated = false;
     }
           
          }
          
          public void onCancel(){

           Toast toast = Toast.makeText(getActivity().getApplicationContext(), "Cancelled", Toast.LENGTH_LONG);
              toast.show();
     if(mProgressDialog != null){
      mProgressDialog.dismiss();
      mProgressDialog = null;
     }

          }
         };
 }

 @Override
 public void onActivityCreated(Bundle savedInstanceState){
  super.onActivityCreated(savedInstanceState);
  //isScreenRotated = false;
 }


 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

  View view = inflater.inflate(R.layout.activity_main,container,false);

  mStartDownloadButton = (Button)view.findViewById(R.id.buttonDownloadImage);
  mDisplayImageButton = (Button) view.findViewById(R.id.buttonDisplayImage);
  mURL = (EditText) view.findViewById(R.id.editTextURL);
  mImageView = (ImageView) view.findViewById(R.id.imageView1);
  mImageView.setVisibility(View.INVISIBLE);
  mStartDownloadButton.setOnClickListener(this);
  mDisplayImageButton.setOnClickListener(this);

  return view;
 }


 @Override
 public void onClick(View v) {
  // TODO Auto-generated method stub
  if (v.equals(mStartDownloadButton)){
   String URL = mURL.getText().toString();
   URL = URL.replace(" ", "");

   if(URL != null && !URL.isEmpty()){
    DownloadImageAsyncTask asyncTask = new DownloadImageAsyncTask(c);
    asyncTask.execute(URL);
    mStartDownloadButton.setEnabled(false);
   }
   
  }
  
  if(v.equals(mDisplayImageButton)){
   mImageView.setImageBitmap(mBitmap);
   mImageView.setVisibility(View.VISIBLE);
  }
 }

 @Override
 public void onDetach() {
  // All dialogs should be closed before leaving the activity in order to avoid
  // the: Activity has leaked window com.android.internal.policy... exception
  if (mProgressDialog != null && mProgressDialog.isShowing()) {
   mProgressDialog.dismiss();
   mProgressDialog = null;
  }
  if(mBitmap != null){
   mBitmap = null;

  }
  isScreenRotated = true;
  super.onDetach();
 }

 /*@Override
 public void onAttach(Activity activity){
  super.onAttach(activity);
  isScreenRotated = false;

 }*/
}


Look at the above code and see how we handle the rotation  in the Detach function (like dismissing the ProgressDialog) of the Fragment. Also important is calling setRetainInstance(true) in the onCreate method of the Fragment. Since we are calling setRetainInstance(true), the fragment won't be newly created when the screen rotates, however the Detach method will be called as usual.

And now the Activity will look like the following:

package com.somitsolutions.training.android.asynctaskdownloadimage;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

You can clone the source code of the complete App from https://github.com/sommukhopadhyay/AsynctaskDownloadImage