Tuesday, July 27, 2010

Custom Logger for Android

Now and then you must feel the need to have some more control over the way Android Application logs are getting displayed. Possible requirement scenarios; redirecting your Android logs into a File or you might want to control the logs those are getting displayed e.g. for production mode, you may want to block all logs to get better performance.
I have written a custom Logger, which is a wrapper over android.util.Log. This will keep existing behavior of Log class as it is and add few handy features to get more control over your application logs-
Storing Logs directly into File- at present all logs comes on the LogCat. You need to manually copy/past logs from LogCat to any file for further analysis. Another option is to get the Dump state when an application gets “Forced Closed”. But this wrapper will allow you an automatic solution. Imagine a scenario, your Phone is not connected with the LogCat and you need the tracing. This wrapper will be helpful in this scenario.
Controlled Logging- it will give you the control to select the range of logs to be display/stored e.g. if you select the allowed Log Level to VERBOSE, all Log Level (integer values) higher than VERBOSE will be displayed. You can even completely block all logging (perfect for production).
To get above additional benefits, you need to refer to a new Class instead of android.util.Log-
MLog.i(“TAG”, “ Log Message”)
All methods are static and make sure, you call MLog.init(context, “ Log_File_Name”) at the very beginning (probably in the onCreate() method of your Activity). This utility class will create a log file under data/data/ Your_Application_Package/files/ Log_File_Name
Sample usage scenarios-
Step1- Configure the Logger (Optional Step)
To stop logging-
MLog.enableLog = false; (this will be suitable for Production Release)
To enable logging only of INFO, WARN and ERROR-
MLog.logLevel = MLog.INFO;
Step2- Initialize the Logger
Once you set above properties, initiate the logger-
MLog.init(this.getApplicationContext(), "app_log.txt");
Note: be careful to pass Application Context rather than Activity Context, which might cause Leak Window issue.
Step3- Use the Logger. Same as you use Log.i(TAG, msg), Log.v(TAG, msg)
MLog.i(TAG, "Location Activity...");
So now you can get these additional benefits by using the attached Logger (MLog.java) in your next project. Have a happy and controlled logging :-)
  

Tuesday, July 20, 2010

Weekend at Yeouido (Han River Cruise)


Yeouido is one of the Han River Cruise boarding points. It has a wonderful river side park (Yeouido Park or Han River Public Park) an ideal place to spend your weekend.
How to reach (from Suwon through Subway)-
  • Line 1 (Suwon to Singil)
  • Change to Line 9 from Singil
  • Line 9 (Singil to Yeouinaru)
What I can do in Yeouido-
  • Han River Cruise
  • Yeouido Park- you can rent bicycles to roam around.
  • 63 Building (Wax Museum, Aquarium and Food court)

From Yeouinero subway station take Exit 3, and you get the wonderful Yeouido Park in front of you. Apart from the Cruise and the River side Park, you will also find a golden color building (Building 63) within walking distance. It houses a Wax Museum, Aquarium and a good food court.
To get the best out of your cruise, it is always good to have the cruise in the evening (probably you should take 7:30PM one). You get to see the best possible nature around the bank of the river and also get the feel of musical fountain which starts only after it gets dark. So I would suggest you should book the Cruise for 7:30-8 PM slot.
Best part of the Cruise is definitely the Banpo Bridge and its Moonlight Rainbow Fountain  
I shouldn’t forget to mention one KFC just next to the Cruise ticket counter. It’s Chicken burgers are yummy....:-)
Tickets-
1 Adult (Round Trip)- 15000 Won  (for Cruise at 7:30 PM)
How to return back- Subway Line 9 (Yeouinaru-Singil) and then Subway Line 1 (Singil-Suwon)

Monday, July 12, 2010

A day at Suwon World Cup Stadium




A nice, relaxing Sunday evening at Suwon World Cup Stadium (after a painful and irritating throat pain and a mild cold on Friday n Saturday). Watched a friendly match- Suwon Samsung Bluewings F.C. Vs. Japan based Urawa Red Diamonds.
I guess I need not to mention, Suwon World Cup stadium, was one of the prime venues for World Cup 2002. It’s really amazing to watch the way Korean people cheer up their home team. Though there was a small bunch of supporter for the Japanese team as well. Unfortunately I was accompanied by a group of friends who were more interested in singing, having photo session and playing Antakshari (an Indian Musical Game) rather than what is going on in 90 mins. But I enjoyed their company very much :-) and it was a bit refreshing as both the sides failed to score any goal.  
There were multiple attempts from both the sides, but finally they didn’t disturb the score line and kept it a perfect friendly match (no win-loss pain). I enjoyed the moves of Urawa, they have couple of very sharp mid-fielders.


Throughout the match, I was wondering…. why Indian footballers don’t try for Clubes in Korea and Japan. It would be much easier and competitive rather than European and North American clubs, who has edge over their Strength and Physic. These guys don’t have that huge physics and mainly concentrate on speed and sharpness. Sunil Chhetri is now in Kansas City Wizards and struggling, Subrata Paul and Gurmang Singh had failed attempts in Canada and Australia respectively. After watching Nehru Cup final, I have strong believe that with proper approach and facilities, present Indian Football team can match up with these Asian football standard. Things are improving and I guess its all about time...
Being a passionate Indian Football supporter :-) , I really have a strong wish, that in my life time, Indian Football team play the World Cup! Before signing off, I shouldn't forget to mention a nice portal to get updates on Indian Football- SportsKeeda  
    



Wednesday, July 7, 2010

Few Multi-Threading Implementations


Sequential Producer & Consumer
In my first example, I will demonstrate an implementation to solve the famous producer and consumer problem. Producer should complete its production, before Consumer can consume it, as simple as that. In addition, both the operations should run on 2 separate threads.
public class SequentialExecutor {

      /**
       * Shared
       */
      volatile int shared;
     
      /**
       * Lock object, whose monitor will be shared by both the threads
       */
      Object lock = new Object();
     
      /**
       * Producer
       */
      P p;
     
      /**
       * Consumer
       */
      C c;
     
      public SequentialExecutor(){
            p = new P();
            c = new C();
      }
     
      public class P implements Runnable {
            public void run(){
                  while(true){
                        synchronized (lock) {
                              try{
                                    // add some processing delay
                                    Thread.sleep(1000);
                              }catch(Exception ex){
                                    ex.printStackTrace();
                              }
                              shared++;
                              System.out.println("Produce->"+ shared);
                        }
                  }
            }
      }
     
      public class C implements Runnable {
            public void run(){
                  while(true){
                        synchronized (lock) {
                              try{
                                    // add some processing delay
                                    Thread.sleep(1500);
                              }catch(Exception ex){
                                    ex.printStackTrace();
                              }
                              System.out.println("Consume->"+ shared);
                        }
                  }
            }
      }
     
      public static void main(String[] args){
            SequentialExecutor se = new SequentialExecutor();
            new Thread(se.p, "P Thread").start();
            new Thread(se.c, "C Thread").start();
      }
}
You’ll get output as-
Produce->1
Consume->1
Produce->2
Consume->2
Produce->3
Consume->3
Produce->4
Consume->4
Here the trick is being done by the common object lock.

Binary Semaphore Implementation
public class Semaphore {

      int counter = 0;
      /**
       * Binary Semaphore- restricts the probable counter values
       * to (0/1)
       */
      int BOUND = 1;
     
      /**
       * Acquire the lock.
       * This SHOULD be an Atomic operation
       */
      public synchronized void acquire(){
            Thread currentThread = Thread.currentThread();
            System.out.println("[acquire] Thread: "+ currentThread.getName()+" - Start");
            System.out.println("Counter: "+ counter);
           
            while(counter == BOUND){
                  // make the calling  thread wait
                  System.out.println(currentThread.getName()+ " Waiting to Acquire...");
                  try{
                        wait();
                  }catch(Exception ex){
                        ex.printStackTrace();
                  }
            }
            counter++;
            System.out.println("[acquire] Thread: "+ currentThread.getName()+" -Done");
      }
     
      /**
       * Release the lock.
       * This SHOULD be an Atomic operation
       */
      public synchronized void release(){
            Thread currentThread = Thread.currentThread();
            System.out.println("[release] Thread: "+ currentThread.getName());
            System.out.println("Counter: "+ counter);
           
            if(counter > 0){
                  counter--;
                  try{
                        // Notify the other thread waiting to acquire lock
                        notify();
                  }catch(Exception ex){
                        ex.printStackTrace();
                  }
            }
      }
}
How to use it-
  1. Acquire the Semaphore lock- acquire()
  2. Do some operation.
  3. Release the Semaphore lock. (Make sure you release it. Otherwise, other threads will never get chance to execute)- release()