Showing posts with label Asynchronous Operations. Show all posts
Showing posts with label Asynchronous Operations. Show all posts

Monday, 1 May 2017

HB Blog 134: Improve Android Applications Performance.

Hey guys, I hope you liked my previous post on app performance HB Blog 132: Does Your Phone Get Hang? Know Why...  . I got few mails and suggestions for posting similar kind of posts. So, here is my one more post for optimize your app's performance in various ways to improve its responsiveness and battery efficiency.
Basically, user expects app to launch app faster as well as load UI without any glitches. App launch can take place in one of three states, each affecting how long it takes for your app to become visible to the user: cold start, warm start, and lukewarm start. In a cold start, your app starts from scratch. In the other states, the system needs to bring the app from the background to the foreground.
At the beginning of a state, the system has three tasks. These tasks are:
  1.     Loading and launching the app.
  2.     Displaying a blank starting window for the app immediately after launch.
  3.     Creating the app process.
As soon as the system creates the app process, the app process is responsible for the next stages. These stages are:
  1.     Creating the app object.
  2.     Launching the main thread.
  3.     Creating the main activity.
  4.     Inflating views.
  5.     Laying out the screen.
  6.     Performing the initial draw.
There are few safety measures we can take for improving application performance such as,
  1. Remove unused resource IDs:- We often declare and find a view using android:id="@+id/view". But, while actual calling it in java classes is not needed. Sometimes, we don't need any changes in that particular view so e can avoid creating this ids. Because, these ids are creating public static final constant variable which are taking up unneeded memory.
  2. Remove unused resource:- Many times we keep on changing UI/UX so in that case we might add up resource but won't remove it once they are unused, so try to remove unused resource it may be images, icons as well as layout and other XML.
  3. Minimize load on onCreate():-  When your application launches, the blank starting window remains on the screen until the system finishes drawing the app for the first time. At that point, the system process swaps out the starting window for your app, allowing the user to start interacting with the app. If you’ve overloaded Application.oncreate() in your own app, the system invokes the onCreate() method on your app object. Afterwards, the app spawns the main thread, also known as the UI thread, and tasks it with creating your main activity. From Android 4.4 (API level 19), logcat includes an output line containing a value called Displayed. This value represents the amount of time elapsed between launching the process and finishing drawing the corresponding activity on the screen. We understand that which activity is taking more time for loading and using tools like Method Tracer, Inline Tracer, etc. It also gives which methods are the culprits, most of the time it is onCreate() method. We need to optimize the load of these method by initializing resource that are needed at startup itself. We can also use methods such as reportFullyDrawn() to let the system know that your activity is finished with its lazy loading.
  4. Use injection framework like Dagger:- Whether the problem lies with unnecessary initialization or disk I/O, the solution calls for lazy-initializing objects: initializing only those objects that are immediately needed. We can have a dependency injection framework like Dagger that creates objects and dependencies are when they are injected for the first time.
  5. Use Asynchronous operation:- Using a background thread ("worker thread") removes strain from the main thread so it can focus on drawing the UI. In many cases, using AsyncTask provides a simple way to perform your work outside the main thread. AsyncTask automatically queues up all the execute() requests and performs them serially. This behavior is global to a particular process and means you don’t need to worry about creating your own thread pool. For background database operations we can use compile statements can be used. Have a look on similar post for more information, HB Blog 95: How To Compile SQL Statement Into Reusable Pre-compiled Statement Object???
  6. Avoid Virtualization:- If you don't need to access an object's fields, make your method static. Invocations will be about 15%-20% faster. It's also good practice, because you can tell from the method signature that calling the method can't alter the object's state. In native languages like C++ it's common practice to use getters (i = getCount()) instead of accessing the field directly (i = mCount). This is an excellent habit for C++ and is often practiced in other object oriented languages like C# and Java, because the compiler can usually inline the access, and if you need to restrict or debug field access you can add the code at any time. However, this is a bad idea on Android. Virtual method calls are expensive, much more so than instance field lookups. It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly.
  7. Use Enhanced For Loop Syntax:- The enhanced for loop (also sometimes known as "for-each" loop) can be used for collections that implement the Iterable interface and for arrays. There are several alternatives for iterating through an array:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    static class Foo {
        int mSplat;
    }
    
    Foo[] mArray = ...
    
    public void zero() {
        int sum = 0;
        for (int i = 0; i < mArray.length; ++i) {
            sum += mArray[i].mSplat;
        }
    }
    
    public void one() {
        int sum = 0;
        Foo[] localArray = mArray;
        int len = localArray.length;
    
        for (int i = 0; i < len; ++i) {
            sum += localArray[i].mSplat;
        }
    }
    
    public void two() {
        int sum = 0;
        for (Foo a : mArray) {
            sum += a.mSplat;
        }
    }
    

    • zero() is slowest, because the JIT can't yet optimize away the cost of getting the array length once for every iteration through the loop. 
    • one() is faster. It pulls everything out into local variables, avoiding the lookups. Only the array length offers a performance benefit. 
    • two() is fastest for devices without a JIT, and indistinguishable from one() for devices with a JIT. It uses the enhanced for loop syntax introduced in version 1.5 of the Java programming language.
  8. Avoid complex Layout Hierarchies:- Layouts are a key part of Android applications that directly affect the user experience. If implemented poorly, your layout can lead to a memory hungry application with slow UIs. The Android SDK includes tools to help you identify problems in your layout performance, which will help to implement smooth scrolling interfaces with a minimum memory footprint. In the same way a complex web page can slow down load time, your layout hierarchy if too complex can also cause performance problems. If your application UI repeats certain layout constructs in multiple places, you can use the <include/> and <merge/> tags to embed another layout inside the current layout. Beyond simply including one layout component within another layout, you might want to make the included layout visible only when it's needed, sometime after the activity is running. Deferring loading resources is an important technique to use when you have complex views that your app might need in the future. You can implement this technique by defining a ViewStub for those complex and rarely used views.
  9. Use View Holder for listview:- Listview is one of the most important and very excessively used view. The key to a smoothly scrolling ListView is to keep the application’s main thread (the UI thread) free from heavy processing. Ensure you do any disk access, network access, or SQL access in a separate thread. The key to a smoothly scrolling ListView is to keep the application’s main thread (the UI thread) free from heavy processing. Ensure you do any disk access, network access, or SQL access in a separate thread. A way around repeated use of findViewById() is to use the "view holder" design pattern. A ViewHolder object stores each of the component views inside the tag field of the Layout, so you can immediately access them without the need to look them up repeatedly.
  10. Use 3rd party libraries carefully:- Actually, we use available libraries and resources for fasten our development time. It might not work as expected all the time and not all the design patterns and precautions are followed in these kinda libraries. So do explore complete libraries and then go for it. Android Arsenal is one of the interesting and helpful site which has categorized directory of libraries and tools for Android.

Saturday, 21 February 2015

HB Blog 59: Asynchronous Operations In Android And iOS.

Asynchronous Operations In Android:-
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers. An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute. AsyncTask must be subclassed to be used. The subclass will override at least one method (doInBackground(Params...)), and most often will override a second one (onPostExecute(Result).)

The three types used by an asynchronous task are the following:
1)Params, the type of the parameters sent to the task upon execution.
2)Progress, the type of the progress units published during the background computation.
3)Result, the type of the result of the background computation.

When an asynchronous task is executed, the task goes through 4 steps:
    onPreExecute() - It invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface. We can stop further background process in case of webservice parsing while no internet connection is found.
    doInBackground(Params...) - It is invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
    onProgressUpdate(Progress...) - It is invoked on the UI thread after a call to publishProgress(Progress...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing.
    onPostExecute(Result) - It is invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.

Here is skeleton for AsyncTask,
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Async_DemoTask extends AsyncTask<String, String, String> {
  
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    // Doing something on the main thread before the task is executed
       //start progress bar
       //check internet connection
    }

    @Override
    public String doInBackground(String... params) {
       // Perform long running process
        return response;
    }

    @Override
    protected void onPostExecute(String success) {
        super.onPostExecute(success);
       //stop progress bar
       //Update the UI
    }
}

Asynchronous Operations In iOS:-
Grand Central Dispatch (GCD) comprises language features, runtime libraries, and system enhancements that provide systemic, comprehensive improvements to the support for concurrent code execution on multicore hardware in iOS and OS X. With GCD, you can line up blocks of code in a queue for the system to execute as necessary. These blocks or operations, will be dispatched in the queue to another thread, leaving your main UI thread to continue its tasks.

dispatch_queue_create - It creates a new dispatch queue to which blocks can be submitted.
dispatch_get_main_queue - It returns the serial dispatch queue associated with the application’s main thread.This queue is created automatically on behalf of the main thread before main is called. This method is useful for updating UI.

Here is skeleton for dispatch_async,
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// Doing something on the main thread
dispatch_queue_t demoQueue = dispatch_queue_create("demo queue",NULL);
dispatch_async(demoQueue, ^{
    // Perform long running process
    dispatch_async(dispatch_get_main_queue(), ^{
        // Update the UI       
    });
});
// Continue doing other stuff on the
// main thread while process is running.