When the activity is destroyed, make sure any background thread is cancelled.

There was a race condition when the activity was destroyed when the background
thread was still running.
Before we release the handler, cancel any running thread, wait for it to
actually exit before purging the handler.
This code should be rewritten to use AsyncTask instead of raw threads
in my opinion.

Tested: I tried to import +100 vcard and make the app exit and it did not crash
however the current bug will show under high load. Need to wait for a monkey run
to confirm it is fixed.

Bug:2517391

Change-Id: I37e7619f6b93a8faa7da4506caffb9ed40e4f844
diff --git a/src/com/android/contacts/ImportVCardActivity.java b/src/com/android/contacts/ImportVCardActivity.java
index adc2f67..502af7d 100644
--- a/src/com/android/contacts/ImportVCardActivity.java
+++ b/src/com/android/contacts/ImportVCardActivity.java
@@ -910,6 +910,29 @@
         // make sure that the handler does not run any callback when
         // this activity isFinishing().
 
+        // Need to make sure any worker thread is done before we flush and
+        // nullify the message handler.
+        if (mVCardReadThread != null) {
+            Log.w(LOG_TAG, "VCardReadThread exists while this Activity is now being killed!");
+            mVCardReadThread.cancel();
+            int attempts = 0;
+            while (mVCardReadThread.isAlive() && attempts < 10) {
+                try {
+                    Thread.currentThread().sleep(20);
+                } catch (InterruptedException ie) {
+                    // Keep on going until max attempts is reached.
+                }
+                attempts++;
+            }
+            if (mVCardReadThread.isAlive()) {
+                // Find out why the thread did not exit in a timely
+                // fashion. Last resort: increase the sleep duration
+                // and/or the number of attempts.
+                Log.e(LOG_TAG, "VCardReadThread is still alive after max attempts.");
+            }
+            mVCardReadThread = null;
+        }
+
         // Callbacks messages have what == 0.
         if (mHandler.hasMessages(0)) {
             mHandler.removeMessages(0);
@@ -919,16 +942,6 @@
         super.onDestroy();
     }
 
-    @Override
-    public void finalize() {
-        // TODO: This should not be needed. Throw exception instead.
-        if (mVCardReadThread != null) {
-            // Not sure this procedure is really needed, but just in case...
-            Log.e(LOG_TAG, "VCardReadThread exists while this Activity is now being killed!");
-            mVCardReadThread.cancel();
-            mVCardReadThread = null;
-        }
-    }
 
     /**
      * Scans vCard in external storage (typically SDCard) and tries to import it.