Posts

Showing posts from December, 2014

Android - ListFragment onItemClick() invoked after onDestroyView()

   Android's callback APIs are well sequenced and works as expected for most of the time. However, i ran into this problem where in a ListView's onItemClick() was invoked after the fragment's view was destroyed. Some search suggested that this could be because of the delay in processing Fragment Transactions, especially as they are posted to the main thread and executed in the next available slot and not immediately.      But after spending some time in Fragment transaction, it turns out that this was an issue with frameworks's AbsListView. Besides, this was seen only with a ListView in a Fragment and not with other AdapterViews or custom views. As and when the Fragment is being destroyed, all the views attached to the activity window has to be detached. AbsListView has a custom logic when it is detached from the parent window,     @Override     protected void onDetachedFromWindow() {         super.onDetachedFromWin...

Android - LoaderManager returning null Loaders after orientation change

Image
   Android's LoaderManager APIs can be used to hook up the new instance of the Activity ( after an orientation change) with the existing Loader (started by the old activity instance before the orientation change). The internal implementation is described here and it works fine except for one use case. It works fine because Android framework is able to detect the orientation change and invokes a specific API to save info in the old activity instance. However, there is one use where things aren't saved,   * User launches the activity and triggers the background operation to launch the Loaders   * User pushes the application to background via Home key   * User changes the orientation in Launcher activity   * User resumes the app from the recent app list     Now, as the application is resumed, Android has to destroy the old instance and recreate a new instance to handle the new orientation. However, as and when this happens, getSupportLoad...

Android - Service's onDestroy invoked before onStartCommand

     Android's service life cycle seems straight forward and for cases when a Service is started explicitly, developers expect callbacks onCreate() followed by onStartCommand() and eventually a onDestroy() callback as the service is stopped. However, android's service life cycle documentation has the following, Services can use their stopSelf(int) method to ensure the service is not stopped until started intents have been processed     This seems to suggest that its possible for the service to be destroyed even before the intents are processed, i.e, for onStartCommand() to be invoked. So how often can this happen and what influences this behavior? The worst case scenario is obviously for a client to start and stop service immediately in the same thread.     private void startStopService()  {         Intent intent = new Intent(this, MyService.class);         startService( intent );     ...

Android - Address Sanitizer for Native applications

   Address Sanitizer's support for Android works quite well that the application isn't slowed down to a drastic extent that it isn't usable anymore. The latest NDK ( Revision 10d ) offers easy use to enable address sanitizer for applications. It doesn't work in Android L and isn't supported for 64bit ABIs.    It needs the following compile time options to be enabled in Android.mk,          LOCAL_CFLAGS    := -fsanitize=address -fno-omit-frame-pointer          LOCAL_LDFLAGS   := -fsanitize=address          LOCAL_ARM_MODE := arm and following in Application.mk to use clang 3.5          NDK_TOOLCHAIN_VERSION=clang3.5    Address Sanitizer basically instruments the code for run time analysis and doesn't offer static analysis. This works for malloc, realloc and free. new and delete is supported only when c++ stdlib is linked dynamically...

Android - Library components used across different Applications or Product Flavors

    Android framework supports applications or different product flavors of the same application (like free and pro) to use the same library dependencies. The library could expose components like Activities, Services, UI widgets etc. These java based libraries are linked into these multiple applications and are not shared unlike native libraries which are loaded once into memory and shared across processes.     A typical application with product flavors might be setup to change the package name during the compilation process,  android {     ...     productFlavors {         pro {             applicationId = "com.sample.testapp.pro"         }         free {             applicationId = "com.sample.testapp.free"         }     }  }  dependencies {     ...  ...

Android - Dialog specific Theme

   Android's Dialog APIs typical usage picks up the theme of the context (Activity) that is used to build the Dialog.             AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);     The dialog is now going to be based on the Activity's Theme. However, there are cases when the Dialog needs to based on a different theme and AlertDialog has an overloaded Builder API to specify this custom theme.              public AlertDialog.Builder (Context context, int theme)    Note that the theme attribute isn't an explicit style (DialogTheme) instead is a reference attribute in the current theme that points to Dialog theme.     <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">         <item name="android:alertDialogTheme">@style/DialogTheme</item>     </style>   ...

Android's in built Firewall

Image
    Android comes with a basic firewall support and it is exposed via Setting's Data Usage. The setting is meant to fine tune network access settings, enable/disable background data in Mobile networks, enable/disable data roaming. Network access by background process (background data) can be controlled either for the entire device or per application basis. So how is this achieved and how can this be used for other purposes?      Android's NetworkPolicyManager is the entry point for Settings app. Settings app being an system application has the permissions to request changes. Besides, NetworkPolicyManager is hidden from the SDK too. Settings app uses APIs like setRestrictBackground, setUidPolicy. In Android world each and every application has its own uid and this is picked up by settings and passed on to the framework via setUidPolicy. From here on, NetworkPolicyManager routes the request to Framework's network policy manager service, which routes the re...

Android - ListAdapter's isEnabled vs areAllItemsEnabled

   Android's ListView supports disabling few or all list items. These items can't be clicked by the user and applications can enable or disable items at runtime via an Adapter and notify a data set change. The confusion for developers is couple of APIs provided by ListAdapter for this functionality. The documentation of these APIs is straight forward.    A ListView with few disabled items might want to return false from areAllItemsEnabled and return an appropriate value for the specific time from isEnabled .     @Override     public boolean areAllItemsEnabled() {         return false;     }     @Override     public boolean isEnabled(int position) {         if ( position % 2 == 0 ) {             return true;         } else {             return false;         } ...

Android - Simulate low memory kill

     One of the use cases that application developers tend to ignore or deal at last is the case where in Android kills the application process when it is in background and there is a need for memory to launch or resume other applications. In an ideal scenario, the state saved in Activity's and Fragment's onSaveInstanceState should be good enough to restore the application to its last known state as and when the user resumes the application (after a kill). Nevertheless, it has to be verified in a development environment.    So how are application developers supposed to test this case? Android's low memory killer works on a pre defined threshold values to decide when to kick in and start killing least important process. This pre defined threshold usually does't come into play when user is dealing with one application, which is most often the case with developers working on their app. So the obvious solution is to fine tune these values to cause the low memory ...

Android - Lollipop's new View constructor (Default style)

     Lollipop added a new overloaded constructor for View which takes an additional parameter, defStyleRes. As per the documentation, this is a style resource providing default values for View's attributes and can't be changed by a theme unlike the reference attribute defStyleAttr. The documentation also claims that this is more useful for sub classes and is meant for developers who would like to fall back to a definitive default values for custom attributes etc.     But what does this mean for Application developers who most likely would continue to inflate these views via XML? Lets take a look at a custom TextView, public class MyTextView extends TextView {     public MyTextView(Context context) {         this(context, null);     }     public MyTextView(Context context, AttributeSet attrs) {         this(context, attrs, 0);     }    ...

Android - ImageView with large Bitmaps and OutOfMemory failures

    Android's recommendation to deal with OutOfMemory failures is to optimize the usage of Bitmaps in ImageView. The approach is to determine the original dimensions of the source image and then scale it down to the actual size of the hosting ImageView. Note that this scaling happens in the Bitmap decoding phase and there by reduces the memory usage. Developers might misunderstand this with  ImageView's scale feature like FIT_CENTER, FIT_END. The difference is that ScaleType doesn't really reduce the memory footprint as it is achieved during the rendering phase and not during Bitmap decoding phase.          The ImageView always holds an active reference to the last set Drawable resource and in case of Bitmaps, it would be a BitmapDrawable. The BitmapDrawable in turn holds a reference to the decoded Bitmap (of original dimensions) and this chain holds true until another Drawable is set or until the ImageView is removed from the View hierarchy ...