Pages

Gin Rummy Indian Rummy Nine Men's Morris and more Air Attack

Saturday, 5 March 2016

auto and decltype in C++11 and C++14

C++11 and C++14 compiler helps you to find out the type of a variable, function with the introduciton of auto. auto works similar to var in C#.

auto with declarations

So instead of declaring
    int x = 10;
you can declare
    auto x = 10; 

Can we use auto without initialization? No. In this case compiler will not be able to deduce the type of the variable.

Can we use auto with class member  variable? Only where you can initialize the member variable; static constants. So the below shown declaration is valid.
    class Test
    {
    public:
        static const auto x = 4;
    };

auto with functions

In C++11

Another place where we can use auto is with function return type. But there is a catch in using auto with return type. If you just use as shown below things will not work,
    auto add(int x, int y) {
        return x+y;
    }

You can definitely use auto in place of function return type, if you change the function to as shown below,
    auto add(int x, int y) -> int {
        return x+y;
    }

This doesn't look like too interesting, isn't it; it is just that we are specifying the return type in a different place. We will see some use of having auto with function declaration in c++11 in below sections

In C++14

In C++14 the first version of add function defined above will work fine.

What if we have multiple return statement with different types? you will get a compilation error. So the following function will give you compilation error.
auto factorial(int n) 
{
    if (n == 1) {
        return int(1);
    }
    if (n == 2) {
        return long(2);
    }

    int res = 1;
    for (; n>0; --n) {
        res *= n;
    }

    return res;
}

What about the following recursive function? 
auto factorial(int n) 
{
    if (n > 1) {
        return factorial(n-1) * n;
    }

    return 1;
}

Another compilation error. It is not allowed to call recursive function call before a return statement.
So change the function slightly as shown below and everything should start working.
auto factorial(int n) 
{
    if (n == 1) {
        return 1;
    }
    return factorial(n-1) * n;
}

In c++14 you can also make function parameter auto, the below given version of factorial works just fine in c++14.
auto factorial(auto n)
{
    if (n == 1) {
        return 1;
    }
    return factorial(n-1) * n;
}

decltype

Let me introduce another feature, decltype,  and see if the auto in function return type has any benefit or not.
decltype helps to get the type of a variable or expression, one use of it is shown below,
    float a = 1.0f;
    decltype(a) b = a;

Ok so we have got another way to declare variable. We can use auto as well in this case, what benefit does decltype brings?
Now lets go back the function that we declared and see if we can use decltype there, maybe we can. Modified function is shown below,
    auto add(int x, int y) -> decltype(x) {
        return x+y;
    }
Another interesting thing about decltype is that we can also give expression with it. The following code  snippet works really well and the return type will be float.
    auto add(float x, int y) -> decltype(x+y) {
        return x+y;
    }

Like sizeof operator the expression in decltype will not  be getting evaluated. So the following program will output 1,1.
    #include <iostream>

int main(int argc, char **argv) {
    int x = 1;
    decltype(++x) y = x;
    std::cout << x << "," << y<< std::endl;
}   

auto with reference

Now lets see how auto works with references, can you guess what is the output of the following code block?
#include <iostream>
    
int & incr(int &x)
{
    return ++x;
}

int main(int argc, char **argv) {
    int x = 1;
    auto y = incr(x);
    ++y;
    std::cout << x << std::endl;
}

It is 2 not 3. auto type by default takes the value not reference. Change the declaration as shown below and everything should work as expected.
    auto & y = incr(x);

Then what about pointers?auto works as expected, it is not necessary to specify as auto *

decltype(auto) - c++14

The above code can be made to work as expected using  decltype(auto), It takes the type from the initialization

#include <iostream>

int & incr(int &x)
{   
    return ++x;
}   

int main(int argc, char **argv) {
    int x = 1;
    decltype(auto) y = incr(x);
    ++y;
    std::cout << x << std::endl;
}  

Output of the above program is 3.

Now lets change the function incr function by using auto as shown below and lets see what happens.
#include <iostream>

auto incr(int &x)
{   
    return ++x;
}   

int main(int argc, char **argv) {
    int x = 1;
    decltype(auto) y = incr(x);
    ++y;
    std::cout << x << std::endl;
} 
Now the output is 2.

How do we fix this to make the behaviour same as that of the first program? One way is to use decltype(auto) with function as shown below,
#include <iostream>

decltype(auto) incr(int &x)
{   
    return ++x;
}   

int main(int argc, char **argv) {
    int x = 1;
    decltype(auto) y = incr(x);
    ++y;
    std::cout << x << std::endl;
}  

Please visit http://blog.trsquarelab.com/2015/05/compiling-c11-and-c14-programs-with-gcc.html for information on how to compile with C++11 and C++14 support in Ubuntu using GCC

lambda expression in C++11 and C++14

Lambda expressions are available from C++11 onwards.

The simplest of the lambda expression is
[] {};
which does nothing.

The syntax of a lambda expression is,
[ /*capture-list*/ ] ( /*params*/ ) mutable /* optional*/ /*exception*/ /*attribute*/ -> /*return type*/ { /*body*/ }
capture-list list of comma separated captures
params list of comma separated parameters
mutable allows body to modify parameters captured by value
exception exception specifications
attribute attribute specifications

You can think of lambda expression as a functor. For easy understanding you can imagine that the lambda expression is implemented as some thing like,
class ClosureType
{
    /* members variables are identified using capture list */
public:
    ClosureType(/*capture list*/)
    {}

    /* non-mutable lambda */
    return-type operator(/* parameter list*/) const {/*body*/}

    /* mutable lambda */
    return-type operator(/* parameter list*/) {/*body*}
};

Simple examples

The following code snippet will print Hello from Lambda
[]{
    std::cout << "Hello from Lambda" << std::endl;
}();

Capture list

To access variables declared outside the lambda expression you can use capture list.
int n = 10;

[n]{
    std::cout << "n = " << n << std::endl;
}();
Capturing all automatic variables,
int n = 10;
int m = 20;

[=]{
    std::cout << "n = " << n << " m = " << m << std::endl;
}();
No need to capture global variables, they are accessible in lambda expressions. The above method access variables by value.

To access by reference use & as shown below,
    int n = 10;
    int m = 20;

    [n, &m]{
        std::cout << "n = " << n;
        m = 10;
    }();


    std::cout << " m = " << m << std::endl;
Output of the above program is n = 10 m = 10

Just as we done earlier use just & to access all automatic variables by reference.

this variable can be accessed in the lambda expressions if we add this in the capture list as [this].

capture expressions - C++14

C++14 allows captured members to be initialized with arbitrary expressions. A simple example would be,
auto l = [v = 1] {std::cout << v; };
l();
We can also use reference in the expression as,
int y;
[&x = y]{}

 

Parameters

Paremeters can be specified as you would do for a function. For example the following code will output 1, 2
auto l = [] (int a, int b) {std::cout << a << " " << b; };
l(1, 2);
Can I use template like I do with function? No. But in C++14 you can use auto for parameters as shown below,
auto l = [] (auto a) {std::cout << a ; };
l(1);

 

Return value

If you do not specify any return type will be deduced from the return statement,
auto increment = [] (int i) {return ++i;};
std::cout << increment(1) << std::endl;
The above code can also be declared as,
auto increment = [] (int i) ->int {return ++i;};
std::cout << increment(1) << std::endl;
We can also use decltype in return type.
auto increment = [] (int i) ->decltype(i) {return ++i;};
std::cout << increment(1) << std::endl;
In C++14 the return type can also be auto

Recursive lambda expression

We can also have recursion with lambda expression. In this case we cannot use auto to store lambda variable, but fill have to use std::function. An example is shown below,
#include <iostream>
#include <functional>

std::function<int(int)> factorial = [] (int n) -> int {
    if (n <= 1) {
        return 1;
    }

    return factorial(n-1) * n;
};

int main(int argc, char ** argv)
{
    std::cout << factorial(4) << std::endl;
    return 0;
}

Nested lambda expression

Lambda expression can also be nested.
#include <iostream>

int main(int argc, char ** argv)
{
    int i = 1;

    auto outer = [=] {
        int j = 2;
        auto inner = [=] {
            std::cout << "inner : " << i << " " << j;
        };
        inner();
        std::cout << "outer : " << i << " " << j;
    };

    outer();

    return 0;
}
Output of the above program is inner : 1 2outer : 1 2

Lambda expression as function parameter

There are many ways of declaring function which takes lambda expression as parameter, some of them are shown below.
#include <iostream>
#include <functional>

void func1(std::function<void(std::string const &)> const & l)
{
    l("from func1");
}

template <typename T>
void func2(T l)
{
    l("from func2");
}

// if C++14 is supported
#if __cplusplus > 201103L
void func3(auto l)
{
    l("from func3");
}
#endif

int main(int argc, char **argv)
{
    auto l = [] (std::string const & msg) {
                    std::cout << msg << std::endl;
                };

    func1(l);
    func2(l);

#if __cplusplus > 201103L
    func3(l);
#endif

    return 0;
}

Function returning lambda expression

Examples for function returning lambda expressions are given below,
#include <iostream>
#include <functional>

std::function<void()> func1()
{
    return [] {
                std::cout << "from func1" << std::endl;
              };
}

// In C++14 you don't have to specify return type
auto func2() -> std::function<void()>
{
    return [] {
                std::cout << "from func2" << std::endl;
              };
}

int main(int argc, char **argv)
{
    func1()();
    func2()();

    return 0;
}

Dangling reference

We have to make sure that the variables captured using reference is alive (life time is not ended).
As an example the below given programme has an illegal memory access. It is trying to access variable i after its life time is over.
#include <iostream>
#include <functional>

std::function<void()> func()
{
    int i = 10;
    return [&] {
                std::cout << i << std::endl;
              };
}

int main(int argc, char **argv)
{
    func()();

    return 0;
}

Sizeof lambda expressions

Size of lambda expressions might vary according to the compiler. If the lambda expression does not capture any variables then its size will mostly be 1. If it captures variables the size of lambda expression will the total size of the variables it captured. The output of the below program when compiled with gcc is 1 8.
#include <iostream>

int main(int argc, char ** argv)
{
    int i = 1;
    int j = 2;

    auto l1 = [] {
        std::cout << "l1";
    };

    auto l2 = [=] {
        std::cout << "l2 : " << i << j;
    };

    std::cout << sizeof(l1) << " " << sizeof(l2) << std::endl;

    return 0;
}

Please visit http://blog.trsquarelab.com/2015/05/compiling-c11-and-c14-programs-with-gcc.html for information on how to compile with C++11 and C++14 support in Ubuntu using GCC

multi-threaded programming in C++11

This page is more on examples of multi-thread programming in c++11 than a reference.

Creating thread

A new thread can be created using std::thread class. An example is shown below on how to create a thread.
#include <thread>
#include <iostream>

void run() 
{
    std::cout << __FUNCTION__ << std::endl;
}

int main(int argc, char **argv) {
    std::thread t(run);

    t.join();
}

The above example create a thread t which executes the run function it the new thread.
If we do not create any thread there will always be one thread in the application, we usually call it the main thread.Now suppose we are creating a new thread then the main thread and the newly created thread will execute in parallel. In our example above thread object t is created in main thread and it will be out of scope once main thread finish executes main function and terminate will be called, even if the newly created thread is active. To avoid this we need to make our main thread wait for the newly created thread to complete its execution. The way to do that is to call t.join();

Important functions in std::thread

get_id Retrieves thread thread id
joinable Checks if the thread is joinable
join Joins the thread, ie. wait for the thread to complete its execution
detach Detach thread
swap Swap thread objects

Using Mutex

Mutex can be used to protect data from multiple threads. mutex::lock can be used to prevent multiple thread access to shared data and mutex::unlock to release the lock.
An example of using std::mutex is shown below,
#include <thread>
#include <mutex>
#include <chrono>
#include <vector>
#include <memory>
#include <iostream>

void run()
{
    static std::mutex m;

    // only one thread at a time so that both
    // of the print outs happens one after another
    m.lock();

    std::cout << __FUNCTION__ << " started" << std::endl;

    // wait for 100 milli seconds
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    std::cout << __FUNCTION__ << " ended" << std::endl;

    m.unlock();
}

int main(int argc, char **argv) {
    std::vector<std::shared_ptr<std::thread> > threads;

    for (int i=0; i<5; ++i) {
        std::shared_ptr<std::thread> t(new std::thread(run));
        threads.push_back(t);
    }

    for (std::shared_ptr<std::thread> t : threads ) {
        t->join();
    }
}

Important functions in std::mutex

lock locks the mutex
unlock unlock the mutex
try_lock try locking the mutex, returns if the mutex is already locked

Condition Variable

Condition variable is a synchronization primitive that allows a thread to wait until a condition occurs.
As a simple example, lets take the first example and make it work without using join function.
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>

std::condition_variable cv;
std::mutex m;

void run() {
    std::cout << __FUNCTION__ << " entered" << std::endl;

    // lets put a small delay
    for (int i=0; i<5; ++i) {
        std::cout << "." << std::flush;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    std::cout << std::endl;

    std::cout << __FUNCTION__ << " exiting" << std::endl;

    // notify once we are done with the thread execution
    std::unique_lock<std::mutex> l(m);
    cv.notify_one();
}

int main() {
    std::thread t(run);
    t.detach();

    // wait for the thread to finish, once the thread execution is complete it will be notified 
    std::unique_lock<std::mutex> l(m);
    cv.wait(l);
    
    return 0;
}

Important functions in std::condition_variable

wait wait for notification
notify_one notify one waiting thread
notify_all notify all waiting thread

Now lets see some example of multi thread programming.

Printing 1 to 10 from two thread.

Lets print 1 to 10 with odd numbers printed in one thread and even from the other thread.
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>

// mutex used with condition variables
std::mutex evenMutex;
std::mutex oddMutex;

// condition variables
std::condition_variable evenCV;
std::condition_variable oddCV;

void evenThread()
{
    for (int i=2; i<11; i+=2) {
        // wait for the odd thread to print the value and notify this thread
        {
            std::unique_lock<std::mutex> l(oddMutex);
            oddCV.wait(l);
        }

        std::cout << i << std::endl;

        // notify the odd thread to print value
        std::unique_lock<std::mutex> el(evenMutex);
        evenCV.notify_one();
    }
}

void oddThread()
{
    for (int i=1; i<10; i+=2) {
        std::cout << i << std::endl;

        // notify the even thread to print the value
        {
            std::unique_lock<std::mutex> ol(oddMutex);
            oddCV.notify_one();
        }

        // wait for the even thread to print the value
        std::unique_lock<std::mutex> el(evenMutex);
        evenCV.wait(el);
    }
}

int main(int argc, char **argv)
{
    std::thread ot(oddThread);
    std::thread et(evenThread);

    ot.join();
    et.join();

    return 0;
}

Thread pool 

Lets create a thread pool which creates a given number of threads and distributes the work in one of the available thread. If no thread is available it will wait for a thread to finish.
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <atomic>
#include <vector>
#include <queue>
#include <memory>

class ThreadPool;

// worker class. It will create a thread and wait for a task from the ThreadPool
class Worker {
    std::thread mThread;
    std::atomic_bool mFinished;
    ThreadPool *mPool;

public:
    Worker(ThreadPool *pool)
     : mFinished(false),
       mPool(pool) {
        create();
    }

    ~Worker() {
        join();
    }

    void join() {
        if (mThread.joinable()) {
            mThread.join();
        }
    }

    void terminate() {
        mFinished = true;
    }

    void create();

private:
    void doCreate();
};

class ThreadPool {
private:
    int mWorkerCount;
    // worker vector
    std::vector<std::shared_ptr<Worker>> mThreads;

    // work quueue is a queue of lambda functions
    std::queue<std::function<void(void)>> mWorkQueue;

    // lock used to synchronize queue access and update
    std::mutex mWorkQueueLock;

    // condition variable used to notify task availability
    std::mutex mNotifierLock;
    std::condition_variable mNotifier;

    // condition variable used to notify termination of thread pool
    std::mutex mTerminateLock;
    std::condition_variable mTerminateCV;

public:
    ThreadPool(int workerCount)
     : mWorkerCount(workerCount) {
        create();
    }

    ~ThreadPool() {
        // wait for the termination of the pool
        std::unique_lock<std::mutex> tl(mTerminateLock);
        mTerminateCV.wait(tl);
    }

    void terminate() {
        for (std::shared_ptr<Worker> t: mThreads) {
            t->terminate();
        }
        std::unique_lock<std::mutex> tl(mTerminateLock);
        mTerminateCV.notify_one();
    }

    void submitWork(std::function<void()> const & work) {
        // add task to queue
        {
            std::unique_lock<std::mutex> ql(mWorkQueueLock);
            mWorkQueue.push(work);
        }

        // notify availability of task
        std::unique_lock<std::mutex> nl(mNotifierLock);
        mNotifier.notify_one();
    }

    std::function<void()> getWork() {
        // wait for a task
        waitForWork();

        {
            // retrieve a work
            std::unique_lock<std::mutex> ql(mWorkQueueLock);
            std::function<void()> work = mWorkQueue.front();
            mWorkQueue.pop();
            return work;
        }
    }

private:
    void waitForWork() {
        // wait until queue is not empty
        std::unique_lock<std::mutex> nl(mNotifierLock);
        mNotifier.wait(nl, [this] {
            std::unique_lock<std::mutex> ql(mWorkQueueLock);  return !mWorkQueue.empty();
        });
    }

    void create() {
        for (int i=0; i<mWorkerCount; ++i) {
            mThreads.push_back(std::shared_ptr<Worker>(new Worker(this)));
        }
    }

};

void Worker::create() {
    mThread = std::thread([this] {
        doCreate();
    });
}

void Worker::doCreate() {
    while (!mFinished) {
        mPool->getWork()();
    }
}

int main(int argc, char **argv) {
    ThreadPool pool(2);

    pool.submitWork([]{std::cout << "**work1**" << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); });
    pool.submitWork([]{std::cout << "**work2**" << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); });
    pool.submitWork([]{std::cout << "**work3**" << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); });
    pool.submitWork([]{std::cout << "**work4**" << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); });
    pool.submitWork([]{std::cout << "**work5**" << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); });
    pool.submitWork([]{std::cout << "**work6**" << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); });

    return 0;
}

Advanced Android Interview Questions and Answers 3

(PREVIOUS (Advanced Android Interview Questions and Answers 2

1. How to verify that there is an activity available that can respond to the intent?

SHOW/HIDE ANSWER
Using package manager.
PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(intent,
        PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;

2. How to get result from an Activity?

SHOW/HIDE ANSWER
Call startActivityForResult() with a request code
Implement onActivityResult(int requestCode, int resultCode, Intent data) on your activity
A result code specified by the second activity. This is either RESULT_OK if the operation was successful or RESULT_CANCELED if the user backed out or the operation failed for some reason

3. What is the use of android:sharedUserId?

SHOW/HIDE ANSWER
If android:sharedUserId is set same for two applications which are signed with the same certificate then both the application will share the same user ID.
Application with the same user ID can access each other's data and, if desired, run in the same process.

4. How to convert an Android application project to an Android library project with gradle build system?

SHOW/HIDE ANSWER
In your app build.gradle file change,
apply plugin: 'com.android.application'
to
apply plugin: 'com.android.library'
For a libary project you wont need applicationId, versionCode and versionName

5. What is the purpose of running zipalign?

SHOW/HIDE ANSWER
Running zipalign ensure that all uncompressed data(images or raw files) starts with a particular alignment(4-byte boundaries) relative to the start of the file.
The benefit is a reduction in the amount of RAM consumed when running the application.
Reference
http://developer.android.com/tools/help/zipalign.html

6. What is the purpose of running ProGuard?

SHOW/HIDE ANSWER
The ProGuard tool shrinks, optimizes, and obfuscates your code by removing unused code and renaming classes, fields, and methods with semantically obscure names. Benefits are,
  • smaller sized .apk file
  • more difficult to reverse engineer.

Reference
http://developer.android.com/tools/help/proguard.html

7. What is lint tool?

SHOW/HIDE ANSWER
Is a static code analysis tool that checks your Android project source files for potential bugs and optimization improvements for correctness, security, performance, usability, accessibility, and internationalization.
Reference
http://developer.android.com/tools/help/lint.html

8. What is multiple APK support in Google play

SHOW/HIDE ANSWER
A Feature on Google Play that allows you to publish different APKs for your application that are each targeted to different device configurations.
Reference
http://developer.android.com/google/play/publishing/multiple-apks.html

9. What is the current size limit for an application in Google play?

SHOW/HIDE ANSWER
100 MB at the time of writting this answer.

10. How to upload apks with a size of more than that is mentioned above?


11. What is Support Library?

SHOW/HIDE ANSWER
A set of code libraries that provide backward-compatible versions of Android framework APIs as well as features that are only available through the library APIs.
Reference
http://developer.android.com/intl/ja/tools/support-library/index.html

12. What is DDMS?

SHOW/HIDE ANSWER
Is a debugging tool its full name is Dalvik Debug Monitor Server (DDMS).
It some of the features are,
  • provides heap usage for a process
  • tracks memory allocation of objects
  • provides thread information
  • android file system exploring
  • method profiling
  • network trafic analysis
  • emulates phone operation and location

Reference
http://developer.android.com/intl/ja/tools/debugging/ddms.html

13. What is the differece between Serializable and Parcelable?

SHOW/HIDE ANSWER
Serializable is a standard Java interface where as Parcelable is an Android specific interface.
Parcelable is faster than Serializable. Serializable is easier than a Parcelable to implement.

14. What are the different ways to store data?

SHOW/HIDE ANSWER
  • Sqlite Database
  • Internal Store
  • External Store
  • Network Connection
  • Shared Preferences

15. What are different ways to process a task in a background thread(other than main(UI) thread) in Android?

SHOW/HIDE ANSWER
  • Using Java Thread/Runnable classes
  • Using AsyncTask
  • Using Loaders(AsyncTaskLoader, etc.)
  • Using HandlerThread/Looper/Handler
  • Using ThreadPool : http://developer.android.com/training/multiple-threads/run-code.html
  • Using IntentService

16. What is data binding?

SHOW/HIDE ANSWER
It helps in binding values of an object directly to views in the layout. If the data changes it can update the views.
Reference
http://developer.android.com/tools/data-binding/guide.html

17. What causes an ANR?

SHOW/HIDE ANSWER
  • No response to an input event (such as key press or screen touch events) within 5 seconds.
  • A BroadcastReceiver hasn't finished executing within 10 seconds.

Reference
http://developer.android.com/training/articles/perf-anr.html

18. In which thread does an IntentService performs it's task?

SHOW/HIDE ANSWER
Not in the main thread but in a worker thread

19. What is doze mode?

SHOW/HIDE ANSWER
Device enters doze mode if, an user leaves it unplugged and stationary for a period of time, with the screen off. In doze mode network access and and CPU-intensive services are restricted.
Periodically, the system exits Doze for a brief time to let apps complete their deferred activities.
Systems exits doze mode if user wakes the device by moving it, turning on the screen, or connecting a charger.

Reference
http://developer.android.com/training/monitoring-device-state/doze-standby.html

20. What is App Standby?

SHOW/HIDE ANSWER
An application goes to App Standby mode if the user does not touch the app for certain period of time and none of the following conditions happened:
  • you explicitly launch the app
  • The app has a process currently in the foreground
  • The app produces a notification

When in standby mode, network access and background sync jobs are restricted.
When user plugs the device into a power supply, system releases apps from standby mode.

Reference
http://developer.android.com/training/monitoring-device-state/doze-standby.html

Advanced Android Interview Questions and Answers 1

  1. Advanced Android Interview Questions and Answers 1 
  2. Advanced Android Interview Questions and Answers 2
  3. Advanced Android Interview Questions and Answers 3
  4. Advanced Android Interview Questions and Answers 4


1. What is the architecture of Android?


2. How many ways are there to create a bound service?

SHOW/HIDE ANSWER
Three,
  • Extending the Binder class
  • Using a Messenger
  • Using AIDL

3. What are the steps to create a Bound service using AIDL?

SHOW/HIDE ANSWER
Three,
  • Create the .aidl file : defines the programming interface with method signatures
  • Implement the interface : extend the Stub class and implement the methods
  • Expose the interface to clients : Implement a Service and override onBind() to return your implementation of the Stub class

4. Will calling finish() on an Activity calls all the usual activity life cycle method?

SHOW/HIDE ANSWER
Yes, except if you are calling it from onCreate, in which case onDestroy() will be immediately called without any of the rest of the activity lifecycle (onStart(), onResume(), onPause(), etc) executing.

5. Should base Activity class's onCreate should be called from your Activity implementation?

SHOW/HIDE ANSWER
Yes, if not an exception will be thrown.

6. What is the activity life cycle?

SHOW/HIDE ANSWER
  • onCreate : System calls this method while creating the activity
  • onStart : Called just before the activity becomes visible
  • onResume : Called just before the activity starts interacting with the user, such as receiving the events
  • onPause : Called when the system is about to start resuming another activity
  • onStop : Called when the activity is no longer visible to the user
  • onRestart : Called after the activity has been stopped, just prior to it being started again
  • onDestroy : Called before the activity is destroyed
Reference
http://developer.android.com/guide/components/activities.html

7. What is the Fragment life cycle?

SHOW/HIDE ANSWER
  • onAttach: called once the fragment is associated with its activity.
  • onCreate: called to do initial creation of the fragment.
  • onCreateView: creates and returns the view hierarchy associated with the fragment.
  • onActivityCreated: tells the fragment that its activity has completed its own Activity.onCreate().
  • onViewStateRestored: tells the fragment that all of the saved state of its view hierarchy has been restored.
  • onStart: makes the fragment visible to the user (based on its containing activity being started).
  • onResume: makes the fragment begin interacting with the user (based on its containing activity being resumed).
  • onPause: fragment is no longer interacting with the user either because its activity is being paused or a fragment operation is modifying it in the activity.
  • onStop: fragment is no longer visible to the user either because its activity is being stopped or a fragment operation is modifying it in the activity.
  • onDestroyView: allows the fragment to clean up resources associated with its View.
  • onDestroy: called to do final cleanup of the fragment's state.
  • onDetach: called immediately prior to the fragment no longer being associated with its activity.

Reference
http://developer.android.com/guide/components/fragments.html
http://developer.android.com/reference/android/app/Fragment.html

8. How to programmatically add fragment to an existing ViewGroup?

SHOW/HIDE ANSWER
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

Reference
http://developer.android.com/guide/components/fragments.html#Adding

9. What are the steps to implement Loader?

SHOW/HIDE ANSWER
  • Initialize the LoadManager or restart it with initLoader or restartLoader respectively
  • Implement the Loader implementation class
  • Override the LoaderManager.LoaderCallbacks
  • Return your Loader implementation from onCreateLoader
  • Use the data from onLoadFinished
Reference
http://developer.android.com/guide/components/loaders.html

10. What are the two types on Intents?

SHOW/HIDE ANSWER
  • Explicit intents specify the component to start by name (the fully-qualified class name)
  • Implicit intents do not name a specific component, but instead declare a general action to perform, which allows a component from another app to handle it.
Reference
http://developer.android.com/guide/components/intents-filters.html#Types

11. What is a content provider?

SHOW/HIDE ANSWER
Content provider can be used to share data between or within applications.

12. What are the advantages of AsyncTaskLoader over AsyncTask?

SHOW/HIDE ANSWER
  • AsyncTaskLoader can an handle Activity configuration changes more easily
  • Closer relationship with Activity/Fragment life-cycle

13. How many threads are there to service AsyncTask jobs?


14. What are the levels in the importance hierarchy for an Android process?

SHOW/HIDE ANSWER
There are 5 of them and they are,
  • Foreground process
  • Visible process
  • Service process
  • Background process
  • Empty process
Reference
http://developer.android.com/guide/components/processes-and-threads.html#Lifecycle

15. What is reactive programming?

SHOW/HIDE ANSWER
It is an emerging discipline that combines asynchronous and event-based systems. RxAndroid provides support for reactive programming for Android.
References
https://github.com/ReactiveX/RxAndroid
http://reactivex.io/tutorials.html
https://www.youtube.com/watch?v=JCLZ55M2gVo

16. How to cancel an AsyncTask?

SHOW/HIDE ANSWER
First call the method cancel on the AsyncTask. Now it will not cause the AsyncTask to cancel by interrupting the background thread. But it will cause isCancelled() to return true. You should always check the return value of isCancelled() periodically from doInBackground(Object[]), if possible (inside a loop for instance.) Reference
http://developer.android.com/reference/android/os/AsyncTask.html

17. What are the two types of services?

SHOW/HIDE ANSWER
  • Started : If is started by calling startService().
  • Bounded : If is started by calling bindService().
Reference
http://developer.android.com/guide/components/services.html

18. In which thread does a Started or Bounded service run?

SHOW/HIDE ANSWER
Main thread

19. Can a service run in the foreground?


20. What is Retrolambda?


Wednesday, 2 March 2016

Android Bottom Sheet tutorial

Bottom sheet are introduced in design support library revision 23.2.0. The design spec for bottom sheets can be found at https://www.google.com/design/spec/components/bottom-sheets.html

Dependency

dependencies {
 compile 'com.android.support:design:23.2.0'
}

Gradle might not be able to download this revision for you, you would need to update your SDK using android SDK manager.

Implementation

You can implement bottom sheets support with just layout xml file.
To make a view as bottom sheets add it as a child of CoordinatorLayout and then set BottomSheetBehavior to it (app:layout_behavior="android.support.design.widget.BottomSheetBehavior")
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:background="@android:color/holo_red_dark">

    <Button
        android:id="@+id/show_dialog"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show Dialog"/>

    <LinearLayout
        android:id="@+id/bottom_sheet_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
        android:orientation="vertical"
        android:background="@android:color/holo_blue_dark"
        app:behavior_hideable="true">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="Item 1"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="Item 2"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="Item 3"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="Item 4"/>

    </LinearLayout>

</android.support.design.widget.CoordinatorLayout>

Set app:behavior_hideable(BottomSheetBehavior.setHideable) to true to hide and show the bottom sheets by scrolling.
app: behavior_peekHeight(BottomSheetBehavior.setPeekHeight) can be used to set a display height for the bottom sheets.

You can programatically set these attributes on BottomSheetBehavior as well. BottomSheetBehavior is obtained from the botton sheet view as BottomSheetBehavior.from(bottom_sheet_view)

If you’d like to receive callbacks for state changes, you can set a BottomSheetCallback.
        behavior = BottomSheetBehavior.from(bottom_sheet_view);
        behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(View bottomSheet, int newState) {
                switch (newState) {
                case BottomSheetBehavior.STATE_DRAGGING:
                    break;
                case BottomSheetBehavior.STATE_SETTLING:
                    break;
                case BottomSheetBehavior.STATE_EXPANDED:
                    break;
                case BottomSheetBehavior.STATE_COLLAPSED:
                    break;
                case BottomSheetBehavior.STATE_HIDDEN:
                    break;
                }
            }

            @Override
            public void onSlide(View bottomSheet, float slideOffset) {
            }
        });


State can be set programatically using BottomSheetBehavior.setState

Source code for the example can be found at https://github.com/trsquarelab/androidexamples/tree/master/BottomSheets

Saturday, 27 February 2016

Tutorial on design support library

To understand design support library we will create a simple weather application. In the navigation view we will have a list of city names and if the user clicks on any of them then a detailed weather information for the city will be displayed.

Weather data will be retrieved from openweathermap.org. To use the application you would need to get an appID and set it to the member variable AppId in the class WeatherClient.java.

The complete application can be found at https://github.com/trsquarelab/androidexamples/tree/master/DesignSupportLibrary

Dependency

To add design support library support add the following dependency in your app's build.gradle file.

dependencies {
 compile 'com.android.support:design:23.1.0'
}

Navigation View

Represents a standard navigation menu for application. The menu contents usually are populated from a menu resource.

NavigationView is used as DrawerLayout’s drawer content view. Our main layout file will have the NavigationView added as,
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <include layout="@layout/weather_info"/>

    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/city_list"/>
</android.support.v4.widget.DrawerLayout >


Here the layout file weather_info will have the detailed weather information. To see the full list, please visit https://github.com/trsquarelab/androidexamples/blob/master/DesignSupportLibrary/src/main/res/layout/weather_info.xml

app:headerLayout can be used to set a header for the drawer, this is optional. Our header layout will just a TextView with text as "City".

app:menu is the menu resource inflated for the navigation items.

android:fitsSystemWindows=“true” will ensure that the content don't overlay the system windows, such as navigation bar or status bar.

Our menu resource would look like,
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/cityLondon"
            android:title="London" />
        <item
            android:id="@+id/cityTokyo"
            android:title="Tokyo" />
        <!-- Other items goes here -->
    </group>
</menu>
Please see the full list at https://github.com/trsquarelab/androidexamples/blob/master/DesignSupportLibrary/src/main/res/menu/city_list.xml

Now we should have the drawer that we be opened by swiping from left side of your device.

The drawer can be opened and closed programatically by using DrawerLayout methods openDrawer and closeDrawers respectively.

Handling events on the menu items can be done by setting an implementation of NavigationView.OnNavigationItemSelectedListener using the method NavigationView.setNavigationItemSelectedListener,
     navigationView.setNavigationItemSelectedListener(
        new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
  // Handle the click event here
            }
        });

Collapsing Toolbars

We will declare CollapsingToolbarLayout inside an AppBarLayout. AppBarLayout allows your Toolbar and other views (such as tabs provided by TabLayout) to react to scroll events in a sibling view.

<android.support.design.widget.AppBarLayout
 android:id="@+id/appbar"
 android:layout_width="match_parent"
 android:layout_height="@dimen/appbar_height"
 android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
 android:fitsSystemWindows="true">

 <android.support.design.widget.CollapsingToolbarLayout
  android:id="@+id/collapsing_toolbar"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  app:layout_scrollFlags="scroll|exitUntilCollapsed"
  android:fitsSystemWindows="true"
  app:contentScrim="?attr/colorPrimary"
  app:expandedTitleMarginStart="48dp"
  app:expandedTitleMarginEnd="64dp">

  <ImageView
   android:id="@+id/weather_image"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:fitsSystemWindows="true"
   android:scaleX="5.0"
   android:scaleY="5.0"
   android:scaleType="center"
   app:layout_collapseMode="parallax"/>

  <android.support.v7.widget.Toolbar
   android:id="@+id/toolbar"
   android:layout_width="match_parent"
   android:layout_height="?attr/actionBarSize"
   app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
   app:layout_collapseMode="pin" />

 </android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
Make sure that app:layout_collapseMode is set to "pin" for the Toolbar. And for ImageView app:layout_collapseMode set to "parallax" to scroll it in a parallax fashion.
app:layout_scrollFlags is used to set the scrolling behavior. "scroll" means the view will scroll in direct relation to scroll events. "exitUntilCollapsed" means while scrolling off screen the view will be scrolled until it is 'collapsed'. Please visit http://developer.android.com/reference/android/support/design/widget/AppBarLayout.LayoutParams.html#attr_android.support.design:layout_scrollFlags for more information.
app:contentScrim is the scrim which is shown  or hidden when the scroll position reached a certain limit. Please visit http://developer.android.com/reference/android/support/design/widget/CollapsingToolbarLayout.html#attr_android.support.design:contentScrim for more information. ?attr/colorPrimar is the primary color of the application, which will be used for action bar background.

Floating Action Button

It is a round button denoting the primary action for the interface. We use it to refresh the weather information.
<android.support.design.widget.FloatingActionButton
        android:id="@+id/refresh_button"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        app:layout_anchor="@id/nested_scrollview"
        app:layout_anchorGravity="bottom|right|end"
        android:src="@drawable/refresh_icon"
        android:layout_margin="5dp"
        android:clickable="true"/>
When used with a CoordinatorLayout use layout_anchor along with layout_anchorGravity to place it relative to other views.

Snackbar

Snackbar is another lightweight and quick feedback to a user. Snackbars are shown on the bottom of the screen and contain text with an optional single action.

Keep your Snackbar inside a CoordinatorLayout for swipe to dismiss operation.

They are time out after the given time length by animating off the screen. In addition, users can swipe them away before the timeout.

With no action,
Snackbar.make(refresh_button, "Weather data loaded", Snackbar.LENGTH_LONG)
        .setAction("Ok", null)
        .show();
With an action,
Snackbar.make(refresh_button, "Failed to load weather data: ", Snackbar.LENGTH_LONG)
        .setAction("Reload", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loadWeatherData();
            }
        }).show();

View of the Snackbar can be accessed using,
View view = snackbar.getView();
The TextView can be accessed using,
TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);