Posts

Showing posts from October, 2014

Android - Fragment initialization constructor vs setArguments

   One of the few eye openers for new application developers dealing with Fragments is as to how they are initialized. The recommended approach to use Fragment.setArguments might seem a bit too much of a work specially when the constructor is available. Besides, it seems to be error prone too as it could result in a fragment in an uninitialized state. This is even more so obvious for library developers exposing Fragments and application developers missing the prerequisites to use the Fragment (as its not a compile time enforcement). So why would anyone want setArguments? Its easy to adopt an approach once the reasoning is understood.      Although, both approach satisfy the initialization requirement, the deal breaker is a use case of orientation change when the activity for most applications is recreated (as long as the developers aren't handling it via onConfigurationChange). In this case, the activity is destroyed and a new instance of the activity is crea...

Android - Exploit to stay Foreground without foreground service

   Android application developers seek ways for their process to stay alive (without user intervention) and prevent it from being killed by the framework. A bug in early versions of Android enabled applications to start foreground service without a valid notification and the framework wouldn't display a notification and the user wasn't aware of this foreground process even though the application might have been pushed to background. Framework developers fixed this issue and displayed a default Notification for invalid specifications, there by letting user know about this running service. By the way, this doesn't guarantee that the process wouldn't be killed as explained in the post ( Myth of Foreground Service ) but does reduce the probability significantly on a device with normal usage.    The reason as to why this works is because the Android framework lowers the oom_score for this process to less value in /proc/pid/oom_adj. Based on this, developers might be te...

Android - Service displayed Dialog

Image
   This post  talks about displaying a dialog via Service context by hijacking the token used for soft keyboards. Although it works, it is limited in its usage such as its location and might seem too much of a work for little gain.    However, window manager service displays another type of Windows, WindowManager.LayoutParams.TYPE_TOAST to display toast messages. Toast messages can be shown by Activities and Services. This post is about reusing this window type to display the desired dialog.     @Override     public int onStartCommand(Intent intent, int flags, int startId) {         LayoutInflater inflate = (LayoutInflater)                 getSystemService(Context.LAYOUT_INFLATER_SERVICE);         final View viewContainer = inflate.inflate( R.layout.custom_dialog, null);         TextView view = ( TextView ) viewContainer.findVie...

Android - Myth of Foreground service

Image
    Android developers have a misconception that having a service as foreground with user's knowledge ensures that their process can't be killed by Android's low memory killer. And to make things worse, the developer documentation too is misleading, A foreground service is a service that's considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory . Is that really the case? Assuming that premise to be valid, what would happen when multiple applications launch foreground services? Time to bust the myth !!!  For simplicity, lets have an application launch a number of services each in its own process space have largeHeap enabled. In this case, a single apk has 20 services each running in its own process space. The services are started as not sticky to ensure that they aren't restarted by Android Framework, besides as per the documentation they are not candidates to be killed, so it shouldn't mat...

Android - Periodic sleep based UI updates

   Quite a few applications spawn a background thread or ASyncTask to perform a periodic operation in the background and update the UI accordingly. This makes sense when the when the operation is a database or network based operation but in some cases this is as trivial as a sleep for few seconds like this,    new Thread( new Runnable() {          @Override          public void run() {               try {                  Thread.sleep( 1000 );                  Message msg = mMainThreadHandler.obtainMessage();                  mMainThreadHandler.postMessage( msg );               } catch ( Exception e ) {               }          }   ...

Android - Expedia like Circular list view

Image
I recently came across the launch screen of the expedia's Android app and the interface was quite nice. It looks like its a Grid view with each tiles having their own positions with the columns scrolling.     Turns out that its not a GridView, instead two different ListViews placed next to each other. They have their own adapter providing the data and they have a reference to each other. This reference is what is being used to scroll the other list view when the user scrolls one of the lists. So how is the list view scrolled automatically? Well, its done via setSelectionFromTop . The logic is just to invoke it periodically via a Handler associated with the main thread. So far it makes sense, but how does the list view never reaches the end and instead just circles back to the first child?     Well, its true that the list view didn't reach the end but its actually not displaying the first child, its actually displaying a new child view but the adapter is s...

Android NDK - pthread_cancel alternatives

    Android's NDK doesn't support pthread_cancel due to the complexity it brings to the table. So is there any way to request a native thread to quit? This is mostly a requirement for a relatively long living thread, usually sleeping for a while in a loop. Threads in gaming applications often wake up to check network stats etc. So how can they be terminated (say when the application is pushed to background or when it is paused)?       The simple solution is to keep checking for a boolean variable and exit accordingly. void* networkStatThread(void* arg) {        while ( true ) {              usleep( duration );              bool exitThread = false;                 pthread_mutex_lock(&myMutex);              exitThread = mQuitThread;             ...