Posts

Showing posts from August, 2014

Android : Google Play Store like transparent clickable action bar

Image
    The recent updates to the Play store application introduced the new look to the action bar when browsing applications. The action bar is transparent with just the store icon on the left and the search icon in the right and yet more than one half of the action bar responds to click events and navigates back to the previous screen. If the title isn't set, the entire middle section of the action bar is not clickable as the width of the up navigation container wraps content and in this case it is just an icon. So how does the Play store implement the wide clickable area?    Well, play store actually sets the title. Its just that the color of the text is transparent which causes the container to wrap both the play store icon and the text view hosting the transparent application name and that is why it responds to click events and navigates user back to the previous user interface. Its implemented just my modifying the action bar styles, <style name="MyTh...

Android - ListView and Dynamic data

       One of the challenges working with ListView dealing with dynamic data is to determine the number of records good enough to fill the entire ListView. In some cases, apps try to determine this value by using list view's height and the height of the view from the adapter and then requesting to download so much of data when the activity starts. The idea is basically to ensure optimum data usage and good user experience. Fetching too little records isn't good user experience and too much is a lot of data usage. Besides, these apps anyway have a logic in the ListView's onScrollListener to fetch more data when needed.        This scroll listener callback can be used to handle all use cases. The obvious one is to fetch more data when the user scrolls the list view. The other one is when the adapter is set on the list view. Lets consider the worst case where in the adapter provides a data set not enough to fill the entire list view. In this case,...

Android - Activity to use multiple themes via ContextThemeWrapper

    Android's Manifest specifications supports theme either at the application level or at the activity level but what if we want different UI elements within the same activity to be based on different themes? Android provides an utility ContextThemeWrapper for this purpose.         ContextThemeWrapper newThemeContext = new ContextThemeWrapper(this /*activityContext*/, android.R.style.Theme_Holo );         LayoutInflater inflater = (LayoutInflater) newThemeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);         View newView = inflater.inflate(R.layout.activity_sub_main, null);    ContextThemeWrapper is an specific extension of a ContextWrapper providing theme override functionality. An instance of this overrides the wrapped context's theme and uses the new theme. Its important to invoke getSystemService() on the new context rather than the wrapped context as the overridden version a...

Android - WeakReference.get() and NullPointerException

      Just came across a less reproducible NPE around WeakReferences and no wonder this wasn't caught in a code review. In this case, the back end logic held a WeakReference on a ListView's adapter and the idea is to update the ListView only when its necessary. The code was very simple and is often overlooked.             if (mAdapter.get() != null) {                 mAdapter.get().notifyDataSetChanged();             }   And this worked fine except for a crash once in a while. Basically, the WeakReference was holding on to the object in the check but not when it was being used to update the adapter. So the object was basically garbage collected. Thats a tiny window for a race and yet the GC found its way. So just to demonstrate, how about repeated attempts?         new Thread(new Runnable() {             ...

Android - listener for View's Visibility updates

     Android View implementations don't provide a callback mechanism for changes to a view's visibility. The closest callback is a hook API onVisibilityChanged  that custom implementation can override. However, this doesn't really help for application components using direct SDK View components and i had to live this workaround, which is sadly too much of a work. public class MyImageView extends ImageView {     WeakReference<VisibilityChangeListener> mListener;     public interface VisibilityChangeListener {         public void onVisibilityChanged(int visibility);     }     public MyImageView(Context context) {         super(context);     }     public MyImageView(Context context, AttributeSet attrs) {         super(context, attrs);     }     public MyImageView(Context context, AttributeSet attrs, int defS...

Android - show soft keyboard automatically upon activity or fragment creation

     One of the frequent problems in Activities is to show the keyboard automatically upon activity creation. This makes sense especially when the first interaction is to enter some text into text fields like creating an event in calendar, search application, or a banking application with focus on username. It is kind of a pain for the user to click on the text field in spite of focus being on the text field. This is even more obvious in a big screen device with the Edit Text being on the top half and user having to reach out just to show the keyboard. So the quick solution, is to listen for focus change and request for the keyboard to be shown (an activity having just an EditText).         editText.setOnFocusChangeListener(new android.view.View.OnFocusChangeListener() {             @Override             public void onFocusChange(final View v, boolean hasFocus) {       ...

Android's Binder - Under the Hood

Image
    Android's Binder is a just an abstraction on top linux concepts. Its a well defined protocol to facilitate IPC but the underlying mechanism is plain old linux concept. Under the hood, it just uses memory mapped pages to transfer data from one process to other.     As and when an application process is created, it opens binder driver (/dev/binder) and one of the early operations is to memory map 128 KB by the driver. binder_proc is the data structure which book keeps all process specific data like mapped memory, size, total buffers, allocated buffers, free buffers etc. proc->buffer is the list of all buffers, proc->allocated_buffer is for used buffers and proc->free_buffers is for unused buffers. There are additional data structures which maps a handle to binder_proc and this is the essence of IPC.      Any process wanting to invoke an API served by another process triggers a sequence of steps in the binder driver. The perquisite...

Android's world of Contexts

     Android's most frequently used APIs is based on Context and Activity, Service, Application basically expose these APIs but upon a closer look, Activity class basically extends ContextThemeWrapper (theme added functionality on top of ContextWrapper). ContextWrapper is just an implementation to delegate all context specific calls to an enclosed context. So what is the need for an Activity to relay these calls? This is to give flexibility to change context to serve different needs.     In case of an application, android creates a context (ContextImpl) and attaches this to the Application instance and the Application instance is set as an outer context for the newly created context.             ContextImpl appContext = new ContextImpl();             appContext.init(this, null, mActivityThread);             app = mActivityThread.mInstrumentation.newApplication( ...

Android - System.out.println

   In Android, all logs are written to /dev/log and logcat is just a process to read and print these logs. The synchronization logic (especially when multiple threads log) is taken care in the driver handling the log device. Applications don't have to deal with the device directly, instead use the convenient APIs (android.util.Log). But what about the Java's API System.out? Android supports this by registering for a custom implementation to trap these calls.     System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));     System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));    AndroidPrintStream is an extension of LoggingPrintStream which basically has a custom implementation for println() and thats how the logs meant for console are redirected to /dev/log. class AndroidPrintStream extends LoggingPrintStream {     ...     ...     ...     protected void log(String line) { ...

Android - Surface Flinger triggered Framework reboot

    In early versions of Android, surface flinger was hosted along with the rest of the framework services in a single process space. Consequently, any fatal failures in Surface Flinger terminates the core framework process (system_server) and from here on all services, including Surface Flinger, are restarted. However, in later versions of Android, Surface Flinger was separated into its own process space and yet termination of the same causes a framework reboot. So how is this done?    Its because of the way services and their dependencies are setup at boot time. Init process's configuration is setup like this in init.rc,                   service surfaceflinger /system/bin/surfaceflinger                        class main                        user system           ...