0% found this document useful (0 votes)
5 views86 pages

Core Java Concepts: Inheritance, Polymorphism

The document provides an overview of core Java concepts including inheritance, polymorphism, abstraction, encapsulation, and the differences between method overloading and overriding. It also discusses access modifiers, the implementation of the String class, garbage collection, serialization, reflection, and the singleton design pattern. Key distinctions between abstract classes and interfaces, as well as the use of final, finally, and finalize keywords are also covered.

Uploaded by

swfizz
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views86 pages

Core Java Concepts: Inheritance, Polymorphism

The document provides an overview of core Java concepts including inheritance, polymorphism, abstraction, encapsulation, and the differences between method overloading and overriding. It also discusses access modifiers, the implementation of the String class, garbage collection, serialization, reflection, and the singleton design pattern. Key distinctions between abstract classes and interfaces, as well as the use of final, finally, and finalize keywords are also covered.

Uploaded by

swfizz
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Core Java

What is Inheritance?
one class acquires the properties (methods and fields) of another. With the use of
inheritance the information is made manageable in a hierarchical [Link] uses
the keyword e​ xtends​ to inherit the properties of a class.

What is Polymorphism?
Polymorphism in Java has two types: Compile time polymorphism (static binding) and
Runtime polymorphism (dynamic binding). Method overloading is an example of static
polymorphism, while method overriding is an example of dynamic polymorphism.

Abstraction?

Abstraction is the concept of hiding the internal details and describing things in simple
terms. For example, a method that adds two integers. The method internal processing is
hidden from outer world. There are many ways to achieve abstraction in object oriented
programming, such as encapsulation and inheritance.A java program is also a great
example of abstraction. Here java takes care of converting simple statements to
machine language and hides the inner implementation details from outer world.

Encapsulation?

Encapsulation is the technique used to implement abstraction in object oriented


programming. Encapsulation is used for access restriction to a class members and
[Link] modifier keywords are used for encapsulation in object oriented
programming. For example, encapsulation in java is achieved using ​private​,
protected​ ​and ​public​ ​keywords

Difference between method overloading and overriding.

overloading ​:Same method name and parameters are different in same class.
Overloading happens at [Link] type of method does not matter in case of
method overloading, it can be same or different.

Overriding​ : Same method name and same parameters in parent and child
[Link] happens at runtime. The overriding method can have more specific
return type (meaning if, for example, base method returns an instance of Number class,
all overriding methods can return any class that is extended from Number, but not a
class that is higher in the hierarchy, like, for example, Object is in this particular case).

Performance​: Overloading gives better performance compared to overriding. The


reason is that the binding of overridden methods is being done at runtime.
Note​:Static methods can be overloaded which means a class can have more than one
static method of same name. Static methods cannot be overridden, even if you declare
a same static method in child class it has nothing to do with the same method of parent
class as overridden static methods are chosen by the reference class and not by the
class of the object.

So, for example:

public​ ​class​ ​Animal​ {


​public​ ​static​ ​void​ ​testClassMethod​() {
System​.​out​.​println(​"The static method in Animal"​);
}
​public​ ​void​ ​testInstanceMethod​() {
System​.​out​.​println(​"The instance method in Animal"​);
}
}
public​ ​class​ ​Cat​ ​extends​ ​Animal​ {
​public​ ​static​ ​void​ ​testClassMethod​() {
System​.​out​.​println(​"The static method in Cat"​);
}

​public​ ​void​ ​testInstanceMethod​() {


System​.​out​.​println(​"The instance method in Cat"​);
}

public​ ​static​ ​void​ ​main​(​String​[] ​args​) {


Cat myCat ​=​ ​new​ Cat();
myCat​.​testClassMethod();
Animal myAnimal ​=​ myCat;
myAnimal​.​testClassMethod();
myAnimal​.​testInstanceMethod();
}
}
Will output:

The s
​ tatic​ method in Cat ​// testClassMethod() is called from "Cat" reference
The s​ tatic​ method in Animal ​// testClassMethod() is called from "Animal" reference,
​// ignoring actual object inside it (Cat)
The instance method in Cat ​// testInstanceMethod() is called from "Animal" reference,
​// but from "Cat" object underneath

Static vs. dynamic binding

1. Static binding in Java occurs during compile time while dynamic binding occurs
during runtime.
​ inal​ and s
2. private​, f ​ tatic​ methods and variables use static binding and are
bonded by compiler while virtual methods are bonded during runtime based
upon runtime object.
3. Static binding uses T​ ype​ (​class​ in Java) information for binding while dynamic
binding uses object to resolve binding.
4. Overloaded methods are bonded using static binding while overridden methods
are bonded using dynamic binding at runtime.

Differences between abstract classes and interfaces?

An abstract class​, is a class that contains both concrete and abstract methods
(methods without implementations). An abstract method must be implemented by the
abstract class sub-classes. Abstract classes cannot be instantiated and need to be
extended to be used.

An interface​ is like a blueprint/contract of a class (or it may be thought of as a class


with methods, but without their implementation). It contains empty methods that
represent, what all of its subclasses should have in common. The subclasses provide
the implementation for each of these methods. Interfaces are implemented.

Can an Interface implement another Interface?

Yes, an interface can implement another interface (and more than one), but it needs to
use e​ xtends​, rather than ​implements​ keyword. And while you can not remove methods
from parent interface, you can add new ones freely to your subinterface.
What are the access modifiers you know? What does each one do?

There are four access modifiers in Java language (from strictest to the most lenient):

a. private​ ​variables,​ ​methods​, ​constructors​ or ​inner classes​ are only visible to its'
containing class and its' methods. This modifier is most commonly used, for
example, to allow variable access only through getters and setters or to hide
underlying implementation of classes that should not be used by user and
therefore maintain encapsulation. Singleton constructor is also marked ​private​ to
avoid unwanted instantiation from outside.
b. protected​ can be used on ​variables,​ ​methods​ and ​constructors​ therefore allowing
access only to subclasses and classes that are inside the same package as
protected members' class.
c. Default (no keyword is used) this modifier can be applied to ​classes​, ​variables​,
constructors​ and ​methods​ and allows access from classes and methods inside
the same package.
d. public​ modifier is widely-used on ​classes​, ​variables​, ​constructors​ and ​methods​ to
grant access from any class and method anywhere. It should not be used
everywhere as it implies that data marked with p ​ ublic​ is not sensitive and can not
be used to harm the program.

How is ​String​ class implemented? Why was it made immutable?


The String class is immutable, so that once it is created a String object cannot be
changed. The String class has a number of methods, some of which will be discussed
below, that appear to modify strings. Since strings are immutable, what these methods
really do is create and return a new string that contains the result of the operation.
String helloWorld ​=​ ​"Hello, World!"​;

"Hello, World!"​ is called a ​literal​ and compiler creates a ​String​ object with its' value. So
String capital ​=​ ​"Hello, World!"​.​toUpperCase();

is a valid statement, that, firstly, will create an object with literal value "Hello, World!"
and then will create and return another object with value "HELLO, WORLD!"
Objects of String are immutable, and objects of StringBuffer and StringBuilder are
[Link] and StringBuilder are similar, but StringBuilder is faster and
preferred over StringBuffer for single threaded program. If thread safety is needed, then
StringBuffer is used.

StringBuffer
● Mutable​ - can be modified after creation
● Synchronized​ - multiple threads can access it and modify it without any ​side effects
● Relatively slow process. Many ​locking​ and ​unlocking​ actions will take place

String str = "Geeks";

// conversion from String object to StringBuffer


StringBuffer sbr = new StringBuffer(str);
[Link]();// reverse of string
[Link](sbr);

StringBuilder
● Mutable​ - can be modified after creation
● Not synchronized​ - accessing it and modifying it by more than one threads can produce
unexpected results!
● Much faster than the ​StringBuffer​ class

// conversion from String object to StringBuilder


StringBuilder sbl = new StringBuilder(str);
[Link]("ForGeeks");
[Link](sbl);
When to use which one :
● If a string is going to remain constant throughout the program, then use
String class object because a String object is immutable.
● If a string can change (example: lots of logic and operations in the
construction of the string) and will only be accessed from a single thread,
using a StringBuilder is good enough.
● If a string can change, and will be accessed from multiple threads, use a
StringBuffer because StringBuffer is synchronous so you have
thread-safety.

What is the difference between instantiation and initialization of an object?


Initialization ​is the process of the memory allocation, when a new variable is created.
Instantiation ​is the process of explicitly assigning definitive value to a declared variable
int​ j; ​// Initialized variable (int defaults to 0 right after)
j ​=​ ​10​; ​// Instantiated variable

What the difference between local, instance and class variables?


● Local variables​ exist only in methods that created them, they are stored
separately in their respected Thread Stack (for more information, see question
about Java Memory Model) and cannot have their reference passed outside of
the method scope. That also means that they cannot be assigned any access
modifier or made ​static​ - because they only exist during enclosing method's
execution and those modifiers just do not make sense, since no other outside
method can get them anyway.
● Instance variables​ are the ones, that are declared in classes and their value can
be different from one instance of the class to another, but they always require
that class' instance to exist.
● Class variables​ are those, that are marked with ​static​ keyword in their class'
body. They can only have one value across all instances of that class (changing
it in one place will change it in their class and, therefore, in all instances) and can
even be retrieved without that class' instance (if their access modifier allows it).
What is garbage collector? How does it work?
● All objects are allocated on the heap area managed by the JVM. As long as an
object is being referenced, the JVM considers it alive. Once an object is no
longer referenced and therefore is not reachable by the application code, the
garbage collector removes it and reclaims the unused memory.

What is serialization? How do you implement it?


Serialization ​is the process of converting an object into a stream of bytes in order to
store an object into memory, so that it can be recreated at a later time, while still
keeping the object's original state and data. While Serializable is the easiest to
implement it is highly recommended to use ​Parcelable ​in Android instead, as
Parcelable was created exclusively for Android and it performs about 10x faster than
Serializable, because Serializable uses reflection, which is a slow process and tends to
create a lot of temporary objects and it may cause garbage collection to occur more
often.
Serializable​ is a standard Java interface.
Parcelable​ is an Android specific interface

public​ ​class​ ​MyObjects​ ​implements​ ​Parcelable​ { ​private​ ​int​ age; ​private​ ​String
name; ​private​ ​ArrayList​<​String​> address; ​public​ ​MyObjects​(​String​ name, ​int​ age,
ArrayList​<​String​> address) { ​this​.name = name; ​this​.age = age; ​this​.address =
address; } ​public​ ​MyObjects​(​Parcel​ source) { age = [Link](); name =
[Link](); address = [Link](); }

@Override

public​ ​int​ describeContents() { ​return​ ​0​; }

@Override

public​ ​void​ writeToParcel(​Parcel​ dest, ​int​ flags) {


[Link](age);

[Link](name); [Link](address); }

public​ ​int​ getAge() { ​return​ age; } ​public​ ​String​ getName() { ​return​ name; }
public​ ​ArrayList​<​String​> getAddress() { ​if​ (!(address == ​null​)) ​return​ address;
else​ ​return​ ​new​ ​ArrayList​<​String​>(); } ​public​ ​static​ ​final​ ​Creator​<​MyObjects​>
CREATOR = ​new​ ​Creator​<​MyObjects​>() { ​@Override​ ​public​ ​MyObjects​[] newArray(​int
size) { ​return​ ​new​ ​MyObjects​[size]; } ​@Override​ ​public​ ​MyObjects
createFromParcel(​Parcel​ source) { ​return​ ​new​ ​MyObjects​(source); } }; }

Reflection i​ s an API which is used to examine or modify the behavior of methods,


classes, interfaces at runtime. Through reflection we can invoke methods at runtime
irrespective of the access specifier used with them.
Advantages of Using Reflection:

1. Extensibility Features: An application may make use of external, user-defined


classes by creating instances of extensibility objects using their fully-qualified
names.
2. Debugging and testing tools​: Debuggers use the property of reflection to
examine private members on classes.

Drawbacks:

3. Performance Overhead: ​Reflective operations have slower performance than


their non-reflective counterparts, and should be avoided in sections of code
which are called frequently in performance-sensitive applications.
4. Exposure of Internals: ​Reflective code breaks abstractions and therefore may
change behavior with upgrades of the platform.

What are these ​final​, ​finally​ and ​finalize​ keywords?


final​ ​is a keyword in the java language. It is used to apply restrictions on class, method
and variable. Final class can't be inherited, final method can't be overridden and final
variable value can't be changed.
final​ ​int​ x​=​100​;
x​=​200​;​//Compile Time Error because x is final
finally​ ​is a code block and is used to place important code, it will be executed whether
exception is handled or not.
finalize​ ​is a method used to perform clean up processing just before object is garbage
collected..

Dependency injection​ is a style of object creation in which an objects are created by


an external entity, or technique whereby one object supplies the dependencies of
another object.
Singleton Class Example
This is one of the top interview questions for experienced Java developers. We will list down series
of questions before delving into details,

● Do you know Singleton design pattern?


● Write code for Singleton design pattern?
● But this is poorly written code, can you write some improved or performance oriented code ?
● How will you handle singleton design pattern in a multi-threaded environment?
● Explain Double-Checked Locking pattern?

Singleton design pattern:


Singleton design pattern is the

● solution proposed to return same instance every time


● restrict instantiation of a class more than once
● exactly one copy is available at any given point of time
● ensures only one instance is available in a Java Virtual Machine

Q) How to check, whether 2 instances are same or different ?

● Answer is always check ​hash code​ of the returned instance


● If it is ​Same​, then both instances are same and it is singleton
● If it is ​Different​, then both are different instances and there is something wrong with program
logic

1. Singleton design pattern with Eager Instantiation :

Basic steps to create Singleton class

● Step 1:​ ​private static variable​ of the ​INSTANCE ​of the same class (this is only time
instance of this class get created)
● Step 2:​ Provide ​private constructor​ to restrict instatiation from outside class
● Step 3:​ Provide public static ​getInstance()​ method returning same ​INSTANCE​ every time
● Note:​ These are steps for eager initialization
1
package [Link];
2
3
4
5 public class SingletonDesignPatternWithEagerInitialization {
6
7
8 ​// Step 1: private static variable of INSTANCE variable
9
10 ​private static SingletonDesignPatternWithEagerInitialization

11
​INSTANCE = new SingletonDesignPatternWithEagerInitialization();
12
13
14
​// Step 2: private constructor
15
16 ​private SingletonDesignPatternWithEagerInitialization() {
17
18
19
​}
20

​// Step 3: Provide public static getInstance() method

​// returning same INSTANCE same time

​public static SingletonDesignPatternWithEagerInitialization

​getInstance() {

​return INSTANCE;

​}

}
Problem :

● The above written code is very poor in terms of performance


● because program returns singleton instance eagerly
● i.e.; it instantiates and keep instance ready to be available
● even before asking to return

2. Lazy Instantiation :

We can actually write more improved version of above code with Lazy initialization

Basic steps to create Singleton class using Lazy Initialization

● Step 1:​ Just declare ​private static variable​ of the same class (​beware don’t instantiate​)
● Step 2:​ Provide ​private constructor​ to restrict instatiation from outside class
● Step 3:​ Provide public static ​getInstance()​ method and check
1. Step 3.a:​ If INSTANCE variable is null, then only instantiate
2. Step 3.b:​ Otherwise, return already instantiated INSTANCE variable
● Note:​ These are steps for lazy initialization

Let us move on,


1
public class SingletonDesignPatternWithLazyInitialization {
2
3
4
5 ​// Step 1: private static variable of INSTANCE variable
6
​private static SingletonDesignPatternWithLazyInitialization
7
8 ​INSTANCE;
9
10
11
​// Step 2: private constructor
12
13 ​private SingletonDesignPatternWithLazyInitialization() {
14
​}
15
16 ​// Step 3: Provide public static getInstance() method
17
18 ​// returning INSTANCE after checking
19
​public static SingletonDesignPatternWithLazyInitialization
20
21 ​getInstance() {
22
23 ​if(null == INSTANCE){

24
​INSTANCE = new
25
​SingletonDesignPatternWithLazyInitialization();

​}

​return INSTANCE;

​}

}
3. Singleton design pattern in a multi-threaded environment

Problems of Lazy-Initialization :

● Although, we have done performance optimization for singleton design pattern with lazy
initialization but still there are certain problems
● So, before we start coding ​singleton class​ in a ​multi-threaded environment​ we should
understand problem with ​lazy initialization​ first
● In the above example for Lazy Initialization, suppose 2 or more threads execute in parallel or
concurrent, then there may be a issue with multiple instances being instantiated

Let us understand in steps:

● Thread-1 got the chance and it is put into execution


● It finds the INSTANCE to be null and therefore Thread-1 instantiates
● Concurrently if any other thread got chance and if it tries to executes, then there may be a
possibility of new instance is getting created, although it is 50 % chance
● Because, new Thread-1 haven’t completed with creation of singleton INSTANCE and
another thread at the same time finds singleton INSTANCE to be null and tries to create
another one

To overcome this situation, we need to execute lazy instance creation inside​ synchronized block

Basic steps to create Singleton class using Lazy Initialization in a Multi-threaded environment

● Step 1:​ Just declare ​private static variable​ of the same class (beware don’t instantiate)
● Step 2:​ Provide ​private constructor​ to restrict instantiation from outside class
● Step 3:​ Provide public static ​getInstance()​ method and check
1. Step 3.a:​ If INSTANCE variable is null, then only instantiate
2. Step 3.b:​ Otherwise, return already instantiated INSTANCE variable
3. Synchronized: ​Put both above checks inside synchronized block
● Step 4:​ In addition to above detailed steps, also make INSTANCE variable as ​volatile​. This
will help getting latest updated copy every time, as it will read from main memory than in its
own CPU-cache area
● Note:​ If your singleton INSTANCE is going to be executed in a single threaded environment,
then there is no need of making INSTANCE variable as volatile

[Link]

?
1
package [Link];
2
3
4
5 public class SingletonDesignPatternInMultiThreadedEnvironment {
6
7
8 ​// Step 1: private static variable of INSTANCE variable
9
10 ​private static volatile

11
​SingletonDesignPatternInMultiThreadedEnvironment INSTANCE;
12
13
14
​// Step 2: private constructor
15
16 ​private SingletonDesignPatternInMultiThreadedEnvironment() {
17
18
19
​}
20
21
22
23 ​// Step 3: Provide public static getInstance() method

24
​// returning INSTANCE after checking
25
26 ​public static SingletonDesignPatternInMultiThreadedEnvironment
27
​getInstance() {
28
29
30
​// synchronized block

​synchronized

​([Link]){

​if(null == INSTANCE){

​INSTANCE =

​new

​SingletonDesignPatternInMultiThreadedEnvironment();

​}

​return INSTANCE;

​}

​}

}
This way, we can assure that every time single & same instance is returned

4. Double-checked locking – DCL

Performance issue with above approach:

But again, there is a performance issue with above program. Let us understand,

● Assume that ONE instance is created and available for use (i.e.; singleton instance)
● And with this single & same instance, some thread (Thread-Arya) is executing in a
multi-threaded environment
● Now suppose a new thread (Thread-Surya) got execution cycle and trying to get singleton
instance, although it is already created & available for use
● But Thread-Surya has to wait till Thread-Arya releases lock or comes out of synchronized
block
● This is bad and poor situation, reason being singleton instance is already created and still it
has to wait to get that instance
● Ideally speaking, Thread-Surya doesn’t need to wait for Thread-Arya to release lock and
then check condition and then proceed with its execution

To conclude, we need to design singleton pattern in a such a way that

● once if singleton instance is created & available for use


● then no threads need to wait
● rather it should to get singleton instance and continue with its execution

To design such pattern, we need to look into ​double-checked locking​ design pattern

Let us move on and see exactly Double-Checked Locking Pattern in details

[Link]

?
1
public class SingletonDesignPatternWithDCL {
2
3 ​// Step 1: private static variable of INSTANCE variable
4
5 ​private static volatile SingletonDesignPatternWithDCL
6
​INSTANCE;
7
8 ​// Step 2: private constructor
9
10 ​private SingletonDesignPatternWithDCL() {

11
​}
12
13 ​// Step 3: Provide public static getInstance() method
14
​// returning INSTANCE after checking
15
16 ​public static SingletonDesignPatternWithDCL getInstance() {
17
18 ​// double-checking lock
19
​if(null == INSTANCE){
20
21 ​// synchronized block
22
23 ​synchronized ([Link]) {

24
​if(null == INSTANCE){
25
26 ​INSTANCE = new SingletonDesignPatternWithDCL();
27
​}
28
29 ​}
30
​}

​return INSTANCE;

​}

}
Conclusion:

We have covered almost for every possible situation that may arise problem while dealing with
Singleton design pattern; like

● Eager initialization
● Lazy initialization
● Lazy initializtion in a multi-threaded environment
● Double checking lock desing pattern

It is a design choice to choose from above listed approaches to begin with, as starting with
double-checking lock in a non-threaded environment yields poor results

So, it is always design choice to look that which approach fits our case perfectly for our business
requirement

There are mainly 3 concepts which can break singleton property of a class.
Reflection, Serialization,Cloning.
Reflection
import​ ​[Link];
Singleton instance1 = [Link];
Singleton instance2 = null;
try
{
Constructor[] constructors =
[Link]();
for (Constructor constructor : constructors)
{
// Below code will destroy the singleton pattern
[Link](true);
instance2 = (Singleton)
[Link]();
break;
}
}

catch (Exception e)
{
[Link]();
}
Overcome reflection issue:​ ​To overcome issue raised by reflection, ​enums​ are used

because java ensures internally that enum value is instantiated only once. Since java

Enums are globally accessible, they can be used for singletons. Its only drawback is that

it is not flexible i.e it does not allow lazy initialization.

//Java program for Enum type singleton


public enum GFG
{
INSTANCE;
}
As ​enums ​don’t have any constructor so it is not possible for Reflection to utilize it.
Enums have their by-default constructor, we can’t invoke them by ourself.​ JVM
handles the creation and invocation of enum constructors internally.​ As enums don’t
give their constructor definition to the program, it is not possible for us to access
them by Reflection also. Hence, reflection can’t break singleton property in case of
enums.

Serialization​:-​ ​Serialization​ can also cause breakage of singleton property of singleton


classes. Serialization is used to convert an object of byte stream and save in a file or
send over a network. Suppose you serialize an object of a singleton class. Then if you
de-serialize that object it will create a new instance and hence break the singleton
pattern.
try
{
Singleton instance1 = [Link];
ObjectOutput out = new ObjectOutputStream(new
FileOutputStream("[Link]"));
[Link](instance1);
[Link]();

// deserailize from file to object


ObjectInput in = new ObjectInputStream(new
FileInputStream("[Link]"));

Singleton instance2 = (Singleton) [Link]();


[Link]();

[Link]("instance1 hashCode:- "


+
[Link]());
[Link]("instance2 hashCode:- "
+
[Link]());
}

catch (Exception e)
{
[Link]();
}
Overcome serialization issue​:-​ To overcome this issue, we have to implement method
readResolve() method
// implement readResolve method
protected Object readResolve()
{
return INSTANCE;
}
Cloning​:​ C
​ loning​ is a concept to create duplicate objects. Using clone we can create
copy of object. Suppose, we create clone of a singleton object, then it will create a copy
that is there are two instances of a singleton class, hence the class is no more
singleton.
// JAVA code to explain cloning
// issue with singleton
class SuperClass implements Cloneable
{
int i = 10;
@Override
protected Object clone() throws CloneNotSupportedException
{
return [Link]();
}
}
// Singleton class
class Singleton extends SuperClass
{
- - ------
- }
Singleton instance1 = [Link];
Singleton instance2 = (Singleton) [Link]();
Overcome Cloning issue​:-​ To overcome this issue, override clone() method and throw
an exception from clone method that is CloneNotSupportedException. Now whenever
user will try to create clone of singleton object, it will throw exception and hence our
class remains singleton.
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
Hashtable and HashMap
Hashtable was part of the original [Link] and is a concrete implementation of a
Dictionary.

However, Java 2 re-engineered Hashtable so that it also implements the Map interface.
Thus, Hashtable is now integrated into the collections framework. It is similar to
HashMap, but is synchronized.

Like HashMap, Hashtable stores key/value pairs in a hash table. When using a
Hashtable, you specify an object that is used as a key, and the value that you want
linked to that key. The key is then hashed, and the resulting hash code is used as the
index at which the value is stored within the table.

Set​ ​is a collection that contains no duplicate elements. Set is an interface.. A ​TreeSet​ is a
set where the elements are sorted (and thus ordered), a ​HashSet​ is a set where the
elements are ​not​ sorted or ordered. A ​HashSet​ is typically a lot faster than a ​TreeSet​.

Sorting in Java

int[] arr = { 13, 7, 6, 45, 21, 9, 101, 102 };


// Sorts arr[] in ascending order
[Link](arr)​;//​Modified arr[]:[6, 7, 9, 13, 21, 45, 101, 102]
// Sorts arr[] in descending order
[Link](arr, [Link]());​//​Modified arr[] :
[102, 101, 45, 21, 13, 9, 7, 6, 2]
// Create a list of strings
ArrayList<String> al = new ArrayList<String>();
[Link]("Geeks For Geeks");
[Link]("Friends");
[Link]("Dear");
[Link]("Is");
[Link]("Superb");

/* [Link] method is sorting the


elements of ArrayList in ascending order. */
[Link](al);​//​ ​[Dear, Friends, Geeks For Geeks, Is,
Superb]
/*sorting the elements of ArrayList in descending order. */
​[Link](al, [Link]());
//[Superb, Is, Geeks For Geeks, Friends, Dear]
// Our arr contains 8 elements
int[] arr = { 13, 7, 6, 45, 21, 9, 2, 100 };

// ​Sort subarray​ from index 1 to 4, i.e.,


// only sort subarray {7, 6, 45, 21} and
// keep other elements as it is.
[Link](arr, 1, 5);​ //​Modified arr[] : [13, 6, 7, 21, 45, 9,
2, 100]
Comparable vs Comparator in Java

A comparable object is capable of comparing itself with another object. The class itself

must implements the ​[Link]​ interface to compare its instances.


Consider a Movie class that has members like, rating, name, year. Suppose we wish to

sort a list of Movies based on year of release. We can implement the Comparable

interface with the Movie class, and we override the method compareTo() of Comparable

interface.

// A Java program to demonstrate use of Comparable

import [Link].*;

import [Link].*;

// A class 'Movie' that implements Comparable

class Movie implements Comparable<Movie>

private double rating;

private String name;

private int year;

// Used to sort movies by year

public int compareTo(Movie m)

return [Link] - [Link];

// Constructor

public Movie(String nm, double rt, int yr)

[Link] = nm;
[Link] = rt;

[Link] = yr;

// Getter methods for accessing private data

public double getRating() { return rating; }

public String getName() { return name; }

public int getYear() { return year; }

ArrayList<Movie> list = new ArrayList<Movie>();

[Link](new Movie("Force Awakens", 8.3, 2015));

[Link](new Movie("Star Wars", 8.7, 1977));

[Link](new Movie("Empire Strikes Back", 8.8, 1980));

[Link](new Movie("Return of the Jedi", 8.4, 1983));

[Link](list);

Collections class has a second sort() method and it takes Comparator. The sort()
method invokes the compare() to sort objects.
// Class to compare Movies by ratings
class RatingCompare implements Comparator<Movie>
{
public int compare(Movie m1, Movie m2)
{
if ([Link]() < [Link]()) return -1;
if ([Link]() > [Link]()) return 1;
else return 0;
}
}

// Class to compare Movies by name


class NameCompare implements Comparator<Movie>
{
public int compare(Movie m1, Movie m2)
{
return [Link]().compareTo([Link]());
}
}
RatingCompare ratingCompare = new RatingCompare();
[Link](list, ratingCompare);
To summarize, if sorting of objects needs to be based on natural order then use

Comparable whereas if you sorting needs to be done on attributes of different objects,

then use Comparator in Java.

​ )​ gives the ordering of objects​, used typically in sorting objects in ascending


compareTo(

or descending order while ​equals(


​ )​ will only talk about the equality​ and say whether
they are equal or not.
equals()​ checks if two objects are the same or not and returns a boolean.

compareTo()​ (from interface Comparable) returns an integer. It checks which of the two
objects is "less than", "equal to" or "greater than" the other. Not all objects can be logically
ordered, so a compareTo() method doesn't always make sense.
ProGuard

ProGuard is the technique to shrink the code, which detects and remove the unused
classes, fields, methods, packages and attributes (including code libraries).

It follows a set of steps:

Shrinking, Optimizer, Obfuscator and Preverifier.

Shrinking:​ It shrink the code to by detecting and removing unused code.

Optimizer:​ It analyze and optimize the byte code.

Obfusator:​ It renames the optimize classes, methods with short names. (Used to
prevent Reverse Engineering).

Preverifier:​ It converts the optimize code into optimize jars and libs.

First generate the apk with the applied proguard build type, you
may get some errors and warning on apk generation (These are
normal we are facing also)
-If you getting errors like ClassNotFoundExceptions or may crash
the app then you have to keep those classes which are not found
or causes errors.

like this for classes, also can apply for members and fields

-keep public class <className with pakage>

-keep class retrofit2.** { *; }

-For Warning : You need to take a look on stacktrace to find which


classes gives those warnings,

-dontwarn <classes_name>

-dontwarn retrofit2.**

-dontwarn [Link].*

-dontwarn okio.**

then put these lines in your app’s (module) ‘[Link]’


file.
After that you have successfully applied proguard in your
application. Also check the size of apk this is now smaller than
before‘s size and secure on decompile apk.
Data Structures

Stack:​ ​Stack is a linear data structure which follows a particular order in which the
operations are performed. The order is LIFO(Last In First Out) or FILO(First In Last Out).
Mainly the following three basic operations are performed in the stack:

● Push: ​Adds an item in the stack. If the stack is full, then it is said to be an
Overflow condition.
● Pop:​ Removes an item from the stack. The items are popped in the reversed
order in which they are pushed. If the stack is empty, then it is said to be an
Underflow condition.
● Peek or Top:​ Returns top element of stack.
● isEmpty: ​Returns true if stack is empty, else false.

public class IntStack {


private int[] stack;
private int top;
private int size;

public IntStack(){
top = -1;
size = 100;
stack = new int[size];
}

public IntStack(int size){


top = -1;
[Link] = size;
stack = new int[[Link]];
}

public boolean isFull(){


return (top == [Link] - 1);
// return (top == size - 1);
}

public boolean isEmpty(){


return (top == -1);
// return ([Link] == 0);
}

public boolean push(int item){


if (!isFull()) {
top++;
stack[top] = item;
return true;
}else{
[Link]("Stack is full");
return false;
}
}
public int pop(){
return stack[top--];
}

public int length(){


return top + 1;
}
}

Queue:​ ​Like ​Stack​, Q


​ ueue i​ s a linear structure which follows a particular order in which
the operations are performed. The order is ​Fi​ rst ​In
​ F
​ ​irst O
​ ​ut (FIFO).
Mainly the following four basic operations are performed on queue:

Enqueue: ​Adds an item to the queue. If the queue is full, then it is said to be an Overflow

condition.

Dequeue:​ Removes an item from the queue. The items are popped in the same order in

which they are pushed. If the queue is empty, then it is said to be an Underflow

condition.

Front: ​Get the front item from queue.

Rear:​ Get the last item from queue.


public class IntQueue {

private int front;

private int rear;

private int total;

private int size;

private int q[];

public IntQueue() {

front = 0;

rear = 0;

total = 0;

size = 100;

q = new int[size];

public IntQueue(int size) {

front = 0;
rear = 0;

total = 0;

[Link] = size;

q = new int[[Link]];

public boolean isFull() {

if (total == [Link]) {

return true;

} else {

return false;

public boolean isEmpty(){

if(total == 0){

return true;

} else {

return false;

public boolean enqueue(int item){


if(isFull()){

[Link]("Queue is full");

return false;

}else{

q[rear] = item;

rear = (rear +1)%size;

total = total +1;

return true;

public int dequeue(){

if(isEmpty()){

[Link]("Queue is empty");

return Integer.MIN_VALUE;

}else{

int value = q[front];

front = (front + 1)%size;

total = total - 1;

return value;

}
public void showAll(){

int f = front;

for (int i = 0; i < total; i++) {

[Link]("Queue element is : "+q[f]);

f = (f+1)%size;

public int length(){

return total;

public int frontVlaue(){

if(isEmpty()){

[Link]("Queue is empty");

return Integer.MIN_VALUE;

}else{

return q[front];

public int rearVlaue(){


if(isEmpty()){

[Link]("Queue is empty");

return Integer.MIN_VALUE;

}else{

return q[rear];

Linked List: A
​ linked list is a linear data structure, in which the elements are not stored
at contiguous memory locations. In simple words, a linked list consists of nodes where
each node contains a data field and a reference(link) to the next node in the list. The
elements in a linked list are linked using pointers as shown in the below image:

Bubble Sort Algorithm


Bubble Sort compares all the element one by one and sort them based on their values.

If the given array has to be sorted in ascending order, then bubble sort will start by
comparing the first element of the array with the second element, if the first element is
greater than the second element, it will ​swap​ both the elements, and then move on to
compare the second and the third element, and so on.

If we have total ​n​ elements, then we need to repeat this process for ​n-1​ times.
It is known as ​bubble sort​, because with every complete iteration the largest element in the
given array, bubbles up towards the last place or the highest index.

int ​arr​[] = {​5​, ​1​, ​6​, ​2​, ​4​, ​3​};

int ​flag ​= ​0​;

Int n = ​arr​.​length;

bubbleSort(arr, n);

void ​bubbleSort(​int ​arr[], ​int ​n){

​int ​i, j, temp;

​for​(i = ​0​; i < n; i++){

​ ​"TAG"​, ​"Sorted Array:" ​+ i);


Log.​v(

​for​(j = ​0​; j < n-i-​1​; j++){

​// introducing a flag to monitor swapping

​ lag ​= ​0​;
f

​if​( arr[j] > arr[j+​1​]){

​// swap the elements

​ emp = arr[j];
t

arr[j] = arr[j+​1​];

arr[j+​1​] = temp;

​// if swapping happens update flag to 1

​ lag ​= ​1​;
f

​// if value of flag is zero after all the iterations of inner loop

// then break out

​if​(​flag ​== ​0​){

​break​;
}

Android

Android Activity LifeCycle


When app is first created
D/MainActivity: calling onCreate from MainActivity
D/MainActivity: calling onStart from MainActivity
D/MainActivity: calling onResume from MainActivity
are called
When screen sleeps
08:11:03.142 D/MainActivity: calling onPause from MainActivity
08:11:03.192 D/MainActivity: calling onStop from MainActivity
are called. And again when it wakes up
08:11:55.922 D/MainActivity: calling onRestart from MainActivity
08:11:55.962 D/MainActivity: calling onStart from MainActivity
08:11:55.962 D/MainActivity: calling onResume from MainActivity
are called
Case1: When Next Activity is called from Main Activity
D/MainActivity: calling Next Activity
D/MainActivity: calling onPause from MainActivity
D/NextActivity: calling onCreate from Next Activity
D/NextActivity: calling onStart from Next Activity
D/NextActivity: calling onResume from Next Activity
D/MainActivity: calling onStop from MainActivity
When Returning back to the Main Activity from Next Activity using back button
D/NextActivity: calling onPause from Next Activity
D/MainActivity: calling onRestart from MainActivity
D/MainActivity: calling onStart from MainActivity
D/MainActivity: calling onResume from MainActivity
[Link] – Android™ Notes for Professionals 241
D/NextActivity: calling onStop from Next Activity
D/NextActivity: calling onDestroy from Next Activity
Case2: When Activity is partially obscured (When overview button is pressed) or When
app goes to background and
another app completely obscures it
D/MainActivity: calling onPause from MainActivity
D/MainActivity: calling onStop from MainActivity
and when the app is back in the foreground ready to accept User inputs,
D/MainActivity: calling onRestart from MainActivity
D/MainActivity: calling onStart from MainActivity
D/MainActivity: calling onResume from MainActivity
are called
Case3: When an activity is called to fulfill implicit intent and user has make a selection.
For eg., when share button is
pressed and user has to select an app from the list of applications shown
D/MainActivity: calling onPause from MainActivity
The activity is visible but not active now. When the selection is done and app is active
D/MainActivity: calling onResume from MainActivity
is called
Case4:
When the app is killed in the background(to free resources for another foreground app),
onPause(for prehoneycomb device) or onStop(for since honeycomb device) will be the
last to be called before the app is terminated. onCreate and onDestroy will be called
utmost once each time the application is run. But the onPause, onStop,
onRestart, onStart, onResume maybe called many times during the lifecycle.
Android Activity Launch Mode can be opted from any four modes as described below.

Standard (Default Launch Mode If not specified)

<activity android:launchMode="standard" />

A new instance of actvity is created everytime in the task from which it was started.
Multiple instances of activity can be created and each instance may belong to different
task.

SingleTop

<activity android:launchMode="singleTop" />

If instance of activity is present on top of Task stack, a new instance will not be created
and system will route your intent information through onNewIntent(). If it is not presnt on
top, a new instance will be created. Multiple instance can be created and each instance
may belong to different task.

SingleTask

<activity android:launchMode="singleTask" />

A new task will be created and a new instance of the activity will be pushed at root of
new task. If instance exists on the seperate task then system routes the call to existing
instance through onNewIntent() method. Only one instance will exist at a time.

SingleInstance

<activity android:launchMode="singleInstance" />


Only one instance will exist at a time. System will not launch any other activity into task
holding this type. It is always a single member of its task and activities started from here
will open into seperate task.

Save data in a local database using Room

There are 3 major components in Room:

● Database:​ Contains the database holder and serves as the main access point for
the underlying connection to your app's persisted, relational data.
● The class that's annotated with @
​ Database​ should satisfy the following
conditions:
○ Be an abstract class that extends ​RoomDatabase​.
○ Include the list of entities associated with the database within the
annotation.
○ Contain an abstract method that has 0 arguments and returns the class
that is annotated with ​@Dao​.
● At runtime, you can acquire an instance of D
​ atabase​ by calling
[Link]()​ or​[Link]()​.

Room.​databaseBuilder​(context, AppDatabase.​class​,
dbName).fallbackToDestructiveMigration().build();

@Database​(entities = {User.​class​, Wishlist.​class​}, version = ​1​, exportSchema = ​false​)

public abstract class ​AppDatabase ​extends ​RoomDatabase {

​public abstract ​UserDao userDao();

​public abstract ​WishlistDao wishlistDao();}

● Entity:​ Represents a table within the database.

// Set custom table name, add indexes

@Entity(tableName = "videos",

indices = {@Index("title")})

public final class VideoItem {


@PrimaryKey // required

public long articleId;

public String title;

public String url;

● DAO:​ Contains the methods used for accessing the database.

@Dao
public interface VideoDao {
// Create insert with custom conflict strategy
@Insert(onConflict = [Link])
void saveVideos(List<VideoItem> videos);
}
Use in Application class or provide via Dagger
ContentDatabase provideContentDatabase() {
return [Link](context, [Link], "[Link]")
.addMigrations([Link]).build();
}

RxJava Basics: Observable, Observer

Reactive Extensions ​is a library that follows Reactive Programming principles to


compose asynchronous and event-based programs by using observable sequence.

RxJava​ is a Java based implementation of Reactive Programming.

RxAndroid​ is specific to Android platform which utilises some classes on top of the
RxJava library.

RxJava​ is Java implementation of Reactive Extension (from ​Netflix​). Basically it’s


a library that composes asynchronous events by following Observer Pattern. You
can create asynchronous data stream on any thread, transform the data and
consumed it by an Observer on any thread. The library offers wide range of
amazing ​operators​ like map, combine, merge, filter and lot more that can be
applied onto data stream.

RxJava is all about two key components: ​Observable​ and ​Observer​. In addition to
these, there are other things like ​Schedulers​, ​Operators​ and ​Subscription​.

Observable​: Observable is a data stream that do some work and emits data.

Observer​: Observer is the counter part of Observable. It receives the data emitted by
Observable.

Subscription​: The bonding between Observable and Observer is called as


Subscription. There can be multiple Observers subscribed to a single Observable.

Operator / Transformation​: Operators modifies the data emitted by Observable before


an observer receives them.

Schedulers​: Schedulers decides the thread on which Observable should emit the data
and on which Observer should receives the data i.e background thread, main thread
etc.,

Disposable​: ​Disposable is used to dispose the subscription when an Observer no


longer wants to listen to Observable. In android disposable are very useful in avoiding
memory leaks​.

The following are the different types of O


​ bservables​ in RxJava:

● Observable

● Flowable
● Single

● Maybe

● Completable

The following are the different types of O


​ bservers​ in R
​ xJava​:

● Observer

● SingleObserver

● MaybeObserver

● CompletableObserver

Understanding Annotation Processors

#​Annotations
Annotations are the class of metadata, that can be associated with class, methods, fields
and even other annotations. Annotations in Java are used to provide additional
information, so it is an alternative option for XML and Java marker interfaces. These
methods can also be accessed during the runtime via ​reflections​.

#​Annotation Processors
Annotation processors are the code generators that eliminate the boilerplate code, by
creating code for you during the compile time. Since it’s compile time, there is no
overhead in the performance.

#​Why should I know about Annotation Processors?


Dagger 2 works on Annotation processor. So all the code generation is traceable at the
compile time. Hence you have no performance overhead and its errors are highly
traceable.

HEADER MANIPULATION IN RETROFIT

You can set static headers for a method using the ​@Headers​ annotation.

@Headers​(​"Cache-Control: max-age=640000"​)
@GET​(​"widget/list"​)
Call​<​List​<​Widget​>>​ widgetList​();

@Headers​({
​"Accept: application/[Link]+json"​,
​"User-Agent: Retrofit-Sample-App"
})
@GET​(​"users/{username}"​)
Call​<​User​>​ getUser​(​@Path​(​"username"​)​ ​String​ username​);
Note that headers do not overwrite each other. All headers with the same name will be

included in the request.

A request Header can be updated dynamically using the @​ Header​ annotation. A

corresponding parameter must be provided to the ​@Header​. If the value is null, the header will

be omitted. Otherwise, t​ oString​ will be called on the value, and the result used.

@GET​(​"user"​)
Call​<​User​>​ getUser​(​@Header​(​"Authorization"​)​ ​String​ authorization​)

Similar to query parameters, for complex header combinations, a ​Map​ can be used.

@GET​(​"user"​)

Call​<​User​>​ getUser​(​@HeaderMap​ ​Map​<​String​,​ ​String​>​ headers​)

Headers that need to be added to every request can be specified using

an​OkHttpinterceptor​.

FCM(Firebase Cloud Messaging)

Simply we can say ​FCM (​Firebase Cloud Messaging​) is a new version of ​GCM
(​Google Cloud Messaging​). It is a cross-platform messaging solution that lets you
reliably deliver messages at no cost. Using ​FCM​, you can send notification messages to
drive user re-engagement and retention.

[Link]
ging-c37d165b8320

Differences between FCM and GCM


Firebase Cloud Platform​ inherits GCM’s core infrastructure​ but simplifies the
client development. Developers no longer needs to write their own registration or
subscription retry logic.

Mockito:​Mockito is a java based mocking framework. It internally uses ​Java Reflection


API and allows to create objects of a service. A mock object returns a dummy data and
avoids external dependencies. It simplifies the development of tests by mocking
external dependencies and apply the mocks into the code under test.

Fabric(Custom)

[Link]

Service vs IntentService

When to use?

● The ​Service​ can be used in tasks with no UI, but shouldn't be too long. If you
need to perform long tasks, you must use threads within Service.
● The ​IntentService​ can be used in long tasks usually with no communication to
Main Thread. If communication is required, can use Main Thread handler or
broadcast intents. Another case of use is when callbacks are needed (Intent
triggered tasks).

How to trigger?

● The ​Service​ is triggered by calling method ​startService()​.


● The I​ ntentService​ is triggered using an Intent, it spawns a new worker thread
and the method ​onHandleIntent()​ is called on this thread.

Triggered From

● The ​Service​ and ​IntentService​ may be triggered from any thread, activity or
other application component.
Runs On

● The ​Service​ runs in background but it runs on the Main Thread of the
application.
● The ​IntentService​ runs on a separate worker thread.

Limitations / Drawbacks

● The ​Service​ may block the Main Thread of the application.


● The I​ ntentService​ cannot run tasks in parallel. Hence all the consecutive intents
will go into the message queue for the worker thread and will execute
sequentially.

When to stop?

● If you implement a ​Service,​ it is your responsibility to stop the service when its
work is done, by calling ​stopSelf()​ or ​stopService()​. (If you only want to
provide binding, you don't need to implement this method).
● The ​IntentService​ stops the service after all start requests have been handled,
so you never have to call s ​ topSelf()​.

​Service ​onCreate() -> onStartCommand() -> onDestroy()

1. START_STICKY – When you set your service is started sticky it means it will restart
your service again by Android when memory is available to execute the task. But before
make sure that you do not pass any intent data because intent data will be lost when
service is killed. So we will receive null intent data on startCommand().

2. START_NOT_STICKY – When you set the flag to start not sticky then it will not start
your service if it killed by android resource and some more flag are available you can
check on the official developer site. You can set your flag as below.

1 @Override

2 public int onStartCommand(Intent intent, int flags, int startId) {

4 doSomeTask(startId); // Here you do some task

5 return START_STICKY; // you can set the flag as per your requirement.
6

7 }

IntentService​ onCreate() -> onHandleIntent() -> onDestroy().

Bound service

Bound service is one that allows binding service with the client. This service will
continue running the client unbind it. This service will start running when it binds to
bindService(). This kind of service provides the option to the client with either in the
same process or different process. For the different process, it binds remotely by IPC
(inter-process communication).

Inter-process communication​ provides to run service in a separate thread or multiple


threads. For single thread process it will execute by ​Messenger ​and for multiple
threads, it will handle by ​AIDL ​(Android Interface Definition Language) for example
audio, video playing etc.

Let’s first check How it works bind service in the application. Service can bind either by
activity or broadcast. What you need to do just call bindService(). For binding the
service You need to pass the IBinder instance in onBind() life cycle of service.
Whenever your task has completed then unBind() service from the client. Here is an
example to understand the concept.
1 public class MyService extends Service{

3 private final IBinder mBinder = new LocalService();

5 ​@Nullable

6 ​@Override

7 public IBinder onBind(Intent intent) {

8 return mBinder;

9 }

10

11 public class LocalService extends Binder{

12

13 MyService getService(){

14 return [Link];

15 }

16 }

17

18 public String getFirstMessage(){

19 return "Hi, I am sunil";

20 }

21

22 public String getSecondMessage(){

23 return "Good to see you.";

24 }

25 }

Let’s create an activity to bind this service and access this method inside the client.
1 public class BindServiceActivity extends AppCompatActivity {

3 MyService myService;

4 private boolean isBind;

6 ​@Override

7 protected void onCreate(​@Nullable​ Bundle savedInstanceState) {

8 [Link](savedInstanceState);

9 setContentView([Link].activity_bind_service);

1
0
((Button) findViewById([Link].btn_start)).setOnClickListener(new
1 [Link]() {
1
​@Override
1
2 public void onClick(View v) {

1 getServiceMessage();
3
}
1
});
4
}
1
5

1
6
private void getServiceMessage() {
1
7 // call the localService methods Here

1 String firstMessage = [Link]();


8
String secondMessage = [Link]();
1
[Link]([Link], firstMessage + " " +
9
secondMessage, Toast.LENGTH_LONG).show();
2
}
0

2
1 // Here need to create the service connection

2 ServiceConnection serviceConnection = new ServiceConnection() {


2
2 ​@Override
3
public void onServiceConnected(ComponentName name, IBinder service) {
2
4 // get the locala service instance

2 [Link] localService = ([Link])


5 service;

2 myService = [Link]();
6
isBind = true;
2
7

2
8 }

2
9
​@Override
3
0 public void onServiceDisconnected(ComponentName name) {

3 isBind = false;
1
}
3
};
2

3
3

3 ​@Override
4
protected void onSart() {
3
5 [Link]();

3 Intent intent = new Intent(this, [Link]);


6
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
3
7 }

3
8 ​@Override
3 protected void onStop() {
9
[Link]();
4
0 if (isBind) {

unbindService(serviceConnection);
4 }
1
}
4
2 }

4
3

4
4

4
5

4
6

4
7

4
8

4
9

5
0

5
1

5
2

5
3

5
4

5
5

5
6

5
7

5
8
5
9

6
0

Here is required ServiceConnection instance to create the connection between client


and server. You can bind the service in onStart() method and unbndService() in
onStop() method. But it’s per your requirement When we can unbind service.

Messenger

Messenger will process the message in a different process by using IPC (Inter Process
Communication) remote technique to communicate with client and server. Messenger
will be coupled with the handler, hence all the task will be in queue process in a Single
thread by Handler.

For bind the service what you need to do with pass the Messenger instance reference in
onBind() method and pass the reference of handler while creating the Messenger
instance. Hereabouts message will be carried in the format of the bundle with
Messenger that it awesome. Let’s see for example to create one service which runs in
the different process by using Messenger which is the coupled by Handler.
1 public class MyServiceIPC extends Service {

3 public static final int JOB_1 = 1;

4 public static final int JOB_RESPONSE_1 = 2;

6 Messenger messenger = new Messenger(new IncomingHandler());

8 ​@Nullable

9 ​@Override

10 public IBinder onBind(Intent intent) {

11 return [Link]();

12 }

13

14 class IncomingHandler extends Handler {

15 ​@Override

16 public void handleMessage(Message msg) {

17

18 Message message;

19 Bundle bundle = new Bundle();

20 String messageText;

21

22 switch ([Link]) {

23 case JOB_1:

24 messageText = [Link]().getString("message");

25 message = [Link](null, JOB_RESPONSE_1);

26 [Link](getApplicationContext(),messageText ,
Toast.LENGTH_SHORT).show();
27
[Link]("message_res", [Link]());
28
[Link](bundle);
29
Messenger activityMessenger = [Link];
30 try {

31 [Link](message);

32 } catch (RemoteException e) {

33 [Link]();

34 }

35 break;

36 default:

37 [Link](msg);

38 }

39

40 }

41 }

42 }

Now let’s create activity class to bind this service to send the message to this server
and again send back this response from server to client by using Messenger process by
the handler.
1 public class BindServiceIPCActivity extends AppCompatActivity {

3 private Button btnSend;

4 private EditText editText;

5 private Messenger messenger;

6 private boolean isBound;

7 private final Messenger mActivityMessenger = new Messenger(

8 new ResponseTakeHandler(this));

1
0
​@Override
1
1 protected void onCreate(​@Nullable​ Bundle savedInstanceState) {

1 [Link](savedInstanceState);
2
setContentView([Link].activity_bind_ipc);
1
3
editText = (EditText)findViewById([Link]);
1
4 btnSend = (Button)findViewById([Link]);

1 [Link](new [Link]() {
5
​@Override
1
6 public void onClick(View v) {

1
7
String messageText = [Link]().toString();
1
if ([Link]()){
8
[Link]([Link], "Please enter
1
message", Toast.LENGTH_LONG).show();
9
}else{
2
0 Message message = [Link](null,MyServiceIPC.JOB_1);

2 Bundle bundle = new Bundle();


1
[Link]("message", messageText);
2
2 [Link](bundle);
2 [Link] = mActivityMessenger;
3
try {
2
4 [Link](message);

2 } catch (RemoteException e) {
5
[Link]();
2
}
6
}
2
7

2 }
8
});
2
9

3 }
0

3
​@Override
1
protected void onStart() {
3
2 [Link]();

3 if (!isBound) {
3
// start service here
3
4 Intent intent = new Intent([Link],
[Link]);
3
5 bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

3 }
6
}
3
7

3 ​@Override
8 protected void onStop() {
3 [Link]();
9
isBound = false;
4
0 messenger = null;

}
4
1
ServiceConnection serviceConnection = new ServiceConnection() {
4
2 ​@Override

4 public void onServiceConnected(ComponentName name, IBinder service) {


3
messenger = new Messenger(service);
4
isBound = true;
4
}
4
5

4 ​@Override
6
public void onServiceDisconnected(ComponentName name) {
4
7 isBound = false;

4 messenger = null;
8

4
}
9
};
5
0

5
1
public class ResponseTakeHandler extends Handler{
5
2

5 public ResponseTakeHandler(Context context){


3

5
4 }

5 ​@Override
5 public void handleMessage(Message msg) {
5
6
switch ([Link]){
5
7 case MyServiceIPC.JOB_RESPONSE_1:

5 String result = [Link]().getString("message_res");


8
[Link]([Link], "Response:
"+result, Toast.LENGTH_LONG).show();
5 break;
9
default:
6
0 [Link](msg);

6 }
1

6
}
2
}
6
3

6 }
4

6
5

6
6

6
7

6
8

6
9

7
0

7
1

7
2

7
3

7
4

7
5

7
6
7
7

7
8

7
9

8
0

8
1

8
2

8
3

8
4

8
5

8
6

8
7

8
8

8
9

9
0

9
1

9
2

9
3

9
4
9
5

9
6

Here also required the Service Connection to build the connection between the client
and the server. The handler will process the response of Messenger and update the
user interface. But one more thing does not forget to add this service in
[Link].

AIDL

AIDL means android interface definition [Link] can process any task remotely by
using IPC technique. Android has a strong mechanism to communicate between service
and client through IPC technique. AIDL process the data between clients remotely and
safely only thing is required that client should be bind to this services. AIDL support to
process the generic data by using the Parcelable. Data processing through Parcelable
is fast in IPC mechanism. Different process means I am talking about the
communication between two different applications.
I think it’s big complex example, Let’s give another simple example to explain. I want to
multiply by given two numbers. I will pass two different numbers as input and will tell to
AIDL service to give the result as a response back to me. It is simple task here but it
can take any long background task to the process, for example, downloading any audio
or video files from the server.

For communication with two different apps or process, I need to create the AIDL file in
the same package of both apps. Why AIDL is required on client side also it will create
the copy of proxy for remote access.

Let’s create two different android studio project for App1 and App2.

1 // [Link]

2 package [Link];

4 // Declare any non-default types here with import statements

6 interface MultiplyNumberAidl {
7

8 int multiply(in int firstNumber, in int secondNumber);

9 }

1 public class AidlService extends Service{

3 @Nullable

4 @Override

5 public IBinder onBind(Intent intent) {

6 return new [Link]() {

7 @Override

8 public int multiply(int firstNumber, int secondNumber) throws


RemoteException {
9
return (firstNumber * secondNumber);
10
}
11
};
12
}
13
}

You need to set the build and sync to access the aidl file.
1 sourceSets {

2 main {

3 [Link] = ['src/main/aidl']

4 }

5 }

Add the service in [Link] file.


1 <service android:name=".[Link]"
android:process=":remote">
2
<intent-filter>
3
<action
4 android:name="[Link]" />
5 </intent-filter>

</service>

Now in App2, I will try to access the service to get the result. You need to bind via
explicit intent service with the client by ServiceConnection.
public class MultiplyNumberAidlActivity extends
AppCompatActivity {

@BindView([Link].editText_First)

EditText firstNumEditText;

@BindView([Link].editText_Second)

EditText secondNumEditText;

@BindView([Link])

Button btnAdd;

MultiplyNumberAidl aidlService;

@Override

protected void onCreate(@Nullable Bundle


savedInstanceState) {
[Link](savedInstanceState);

setContentView([Link].activity_aidl);

[Link](this);

initView();

private void initView() {

[Link](new [Link]() {

@Override

public void onClick(View v) {

String firstNumber =
[Link]().toString().trim();

String secondNumber =
[Link]().toString().trim();

int multiply= -1;


if ([Link]() &&
[Link]()){

[Link]([Link], "Please enter


first and second number.", Toast.LENGTH_SHORT).show();

}else{

try {

multiply =
[Link]([Link](firstNumber),
[Link](secondNumber));

} catch (RemoteException e) {

[Link]();

[Link]([Link], ""+multiply,
Toast.LENGTH_SHORT).show();

});
}

@Override

protected void onStart() {

[Link]();

Intent intent = new


Intent("[Link]
idl");

Intent updateIntent =
createExplicitFromImplicitIntent([Link]
, intent);

bindService(updateIntent, serviceConnection,
Context.BIND_AUTO_CREATE);

public static Intent


createExplicitFromImplicitIntent(Context context, Intent
implicitIntent) {

//Retrieve all services that can match the given intent


PackageManager pm = [Link]();

List resolveInfo = [Link](implicitIntent,


0);

//Make sure only one match was found

if (resolveInfo == null || [Link]() != 1) {

return null;

//Get component info and create ComponentName

ResolveInfo serviceInfo = [Link](0);

String packageName = [Link];

String className = [Link];

ComponentName component = new ComponentName(packageName,


className);

//Create a new intent. Use the old one for extras and such
reuse
Intent explicitIntent = new Intent(implicitIntent);

//Set the component to be explicit

[Link](component);

return explicitIntent;

ServiceConnection serviceConnection = new


ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder


service) {

aidlService =
[Link](service);

@Override
public void onServiceDisconnected(ComponentName name) {

aidlService = null;

};

An ​intent filter​ is an expression in an app's manifest file that specifies the type of
intents that the component would like to receive.

Data Binding:​ bind UI components in layouts to data sources

private​ ActivitySampleBinding mBinding;

@Override
protected​ ​void​ ​onCreate​(Bundle savedInstanceState) {
​super​.onCreate(savedInstanceState);
mBinding = [Link](
​this​, [Link].activity_sample);
[Link]([Link]);
}

Android Architecture Components

● Use ​LiveData​ to build data objects that notify views when the underlying
database changes.
● ViewModel​ Stores UI-related data that isn't destroyed on app rotations.
● Room​ is an a SQLite object mapping library. Use it to Avoid boilerplate code and
easily convert SQLite table data to Java objects. Room provides compile time
checks of SQLite statements and can return RxJava, Flowable and LiveData
observables.
LiveData:​ LiveData is an observable data holder. When ever the data is
changed(DB/Network) its automatically updated in the [Link] is
lifecycle-aware, meaning it respects the lifecycle of other app components, such
as activities, fragments, or services. This awareness ensures LiveData only
updates app component observers that are in an active lifecycle state.
LiveData has no publicly available methods to update the stored data. The
MutableLiveData​ ​class exposes the​ ​setValue(T)​ and​ ​postValue(T)​ methods
publicly and you must use these if you need to edit the value stored in a​ ​LiveData
object. Usually MutableLiveData is used in the​ ​ViewModel​ and then the
ViewModel only exposes immutable LiveData objects to the observers.

public class NameViewModel extends ViewModel {

// Create a LiveData with a String


private MutableLiveData<String> mCurrentName;

public MutableLiveData<String> getCurrentName() {


if (mCurrentName == null) {
mCurrentName = new MutableLiveData<String>();
}
return mCurrentName;
}

// Rest of the ViewModel...


}

public class NameActivity extends AppCompatActivity {

private NameViewModel mModel;


@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);

// Other code to setup the activity...

// Get the ViewModel.


mModel = [Link](this).get([Link]);

// Create the observer which updates the UI.


final Observer<String> nameObserver = new Observer<String>() {
@Override
public void onChanged(@Nullable final String newName) {
// Update the UI, in this case, a TextView.
[Link](newName);
}
};

// Observe the LiveData, passing in this activity as the LifecycleOwner and


the observer.
[Link]().observe(this, nameObserver);
}
}

ViewModel:​ is a class that is responsible for preparing and managing the data
for an​ ​Activity​ or a​ ​Fragment​.​ViewModel​ Stores UI-related data that isn't
destroyed on app [Link] will not be destroyed if its owner is
destroyed for a configuration change (e.g. rotation). The new instance of the
owner will just re-connected to the existing ViewModel.

MVVM:​ it allows separating the user interface logic from the business (or the
back-end) [Link] UI code simple and free of app logic in order to make it
easier to manage
Model ​- Model represents the data and business logic of the [Link] is to expose
its data through observables
ViewModel - ​ViewModel interacts with model and also prepares observable(s)
that can be observed by a View. ViewModel should not be aware about the view
who is interacting with.
View - ​Finally, the view role in this pattern is to observe (or subscribe to) a
ViewModel observable to get data in order to update UI elements accordingly.

MVP: Model View Presenter

The key points of MVP is:

● The user’s interactions ​call methods​ on the ​Presenter


● The Presenter stores state, manages state, and ​calls methods on the view t​ o
notify it to update itself
● The ​Model i​ s just data
● The ​View r​ eceives method calls from the presenter​ to be notified of changes to
update itself

MVC: Model View Controller

The key points of MVC is:

● The user’s interactions ​call methods​ on the ​Controller


● The Controller updates the Model (where the model is what actually stores state)
● The ​Model e ​ xposes change listeners to notify observers t​ hat it has changed
● The ​View s​ ubscribes for changes emitted by the model​ to update itself

apply() or commit()
The ​[Link]()​ method is ​asynchronous​, while ​[Link]()​ is
synchronous​.
Obviously, you should call either ​apply()​ or ​commit()​.
apply()​ was added in 2.3 (API 9), it commits without returning a boolean indicating
success or failure.
commit()​ returns true if the save works, false otherwise.

Unlike ​commit()​, which writes its preferences out to persistent storage synchronously,
apply()​ commits its changes to the in-memory S ​ haredPreferences ​immediately but
starts an asynchronous commit to disk and you won't be notified of any failures. If
another editor on this S ​ haredPreferences​ does a regular c ​ ommit()​ while a a
​ pply()​ is
​ ommit()​ will block until all async commits(apply) are completed as
still outstanding, the c
well as any other sync commits that may be pending.


Exception Handling

we want to deal with exceptions within our code using try/catch


blocks. That’s just good programming practice. However, we
aren’t perfect, and some exceptions cannot be foreseen. For that
reason, we always want to provide an application crash handler
that will catch the uncaught ones. Think of it as the ultimate
try/catch block.

The ​ApplicationCrashHandler c​ lass is relatively straight forward for


development purposes. We write a class that implements the
[Link]​ interface. We then use
[Link]()​ to install the handler.
I wrap this into a single class:

package [Link];

import [Link];

import [Link];

import [Link];

import [Link];

public class ApplicationCrashHandler implements


[Link] {

​/**

* Storage for the original default crash handler.

*/

​ rivate [Link] defaultHandler;


p

​/**
* Simple string for category log

*/

​ rivate static final String ​TAG =


p ​ "ApplicationCrashHandler";

​/**

* Installs a new exception handler.

*/

​ ublic static void installHandler() {


p

if (!(Thread.​getDefaultUncaughtExceptionHandler​()
instanceof ApplicationCrashHandler)) {

Thread.​setDefaultUncaughtExceptionHandler​(new
ApplicationCrashHandler());

}
private ApplicationCrashHandler() {

[Link] =
Thread.​getDefaultUncaughtExceptionHandler​();

​/**

* Called when there is an uncaught exception elsewhere in


the code.

* ​@param ​t the thread that caused the error

* ​@param ​e the exception that caused the error

*/

​ Override
@

public void uncaughtException(Thread t, Throwable e) {

// Place a breakpoint here to catch application crashes

​ ​TAG​, String.​format(
Log.​wtf( ​ "Exception: %s\n%s",
[Link](), getStackTrace(e)));
// Call the default handler

[Link](t, e);

​/**

* Convert an exception into a printable stack trace.

* ​@param ​e the exception to convert

* ​@return t
​ he stack trace

*/

​ rivate String getStackTrace(Throwable e) {


p

final Writer sw = new StringWriter();

final PrintWriter pw = new PrintWriter(sw);

[Link](pw);

String stacktrace = [Link]();


[Link]();

return stacktrace;

You can then adjust the ​SplashActivity​ to include a call to install


the handler in the ​onCreate()​ method:

@Override

protected void onCreate(Bundle savedInstanceState) {

[Link](savedInstanceState);

​ ;
setContentView([Link].​activity_splash)

// Install the application crash handler

ApplicationCrashHandler.​installHandler​();

// Record the start-up time


​ );
long currentTime = System.​currentTimeMillis(

long elapsedTime = currentTime -



ApplicationWrapper.​startTime;

if (elapsedTime > 3000) {

​ TAG, "LONG STARTUP TIME");


Log.​e(

​ TAG, String.​format​("Elapsed Time = %d ms",


Log.​d(
elapsedTime));

// Transition to the MainActivity

Intent intent = new Intent(this, [Link]);

startActivity(intent);

finish();

}
Android Ore Features
1. Picture in Picture
2. Password Auto Fill
3. Notification Channel
4. Snoozed Notifications
5. Notification Dots
6. New Emoji Styling
7. Smart Text selection
8. Auto Enable wifi

SQLite
public​ ​SQLiteHelper​(​Context context​)​ ​{
​super​(​context​,​ DATABASE_NAME​,​ ​null​,​ DATABASE_VERSION​);
​}

​//database values
​private​ ​static​ ​final​ String DATABASE_NAME ​=
"[Link]"​;
​private​ ​static​ ​final​ ​int​ DATABASE_VERSION ​=​ 3​ ;
​public​ ​static​ ​final​ String COLUMN_ID ​=​ "​ _id"​;

​//team table
​public​ ​static​ ​final​ String TABLE_TEAM ​=​ ​"team"​;
​public​ ​static​ ​final​ String COLUMN_MASCOT ​=​ ​"mascot"​;
​public​ ​static​ ​final​ String COLUMN_CITY ​=​ ​"city"​;
​public​ ​static​ ​final​ String COLUMN_COACH ​=​ ​"coach"​;
​public​ ​static​ ​final​ String COLUMN_STADIUM ​=​ ​"stadium"​;

​ rivate​ ​static​ ​final​ String DATABASE_CREATE_TEAM ​=​ ​"create


p
table "
​+​ TABLE_TEAM ​+​ ​"("​ ​+​ COLUMN_ID ​+​ ​" integer primary
key autoincrement, "
​+​ COLUMN_NAME ​+​ ​" string, "
​+​ COLUMN_MASCOT ​+​ ​" string, "
​+​ COLUMN_COACH ​+​ ​" string, "
​+​ COLUMN_STADIUM ​+​ ​" string, "
​+​ COLUMN_CITY ​+​ ​" string);"​;

​private​ ​static​ ​final​ String DATABASE_ALTER_TEAM_1 ​=​ ​"ALTER


TABLE "
​+​ TABLE_TEAM ​+​ ​" ADD COLUMN "​ ​+​ COLUMN_COACH ​+​ ​"
string;"​;

​ rivate​ ​static​ ​final​ String DATABASE_ALTER_TEAM_2 ​=​ ​"ALTER


p
TABLE "
​+​ TABLE_TEAM ​+​ ​" ADD COLUMN "​ ​+​ COLUMN_STADIUM ​+​ ​"
string;"​;

​@Override
​public​ ​void​ ​onCreate​(​SQLiteDatabase db​)​ ​{
db​.​execSQL​(​DATABASE_CREATE_TEAM​);
​}

​@Override
​public​ ​void​ ​onUpgrade​(​SQLiteDatabase db​,​ ​int​ oldVersion​,​ ​int
newVersion​)​ ​{
​if​ ​(​oldVersion ​<​ ​2)​ ​{
db​.​execSQL​(​DATABASE_ALTER_TEAM_1​);
​}
​if​ ​(​oldVersion ​<​ ​3)​ ​{
db​.​execSQL​(​DATABASE_ALTER_TEAM_2​);
​}
​}
}

Swaping without using Temporary variable


int x = 10;
int y = 5;
x = x + y;
y = x - y;
x = x - y;
[Link]("After swaping:"
+ " x = " + x + ", y = " + y);
After Swapping: x = 5, y = 10

How to Create a Reminder Notification


You need two things:

● AlarmManager: to schedule your notification at a regular bases (daily, weekly,..).


● Service: to launch your notification when the AlarmManager goes off.

Here is a basic example:

In your Activity:

Intent​ myIntent = ​new​ ​Intent​(​this​ , ​NotifyService​.​class​);

​AlarmManager​ alarmManager = (​AlarmManager​)getSystemService(ALARM_SERVICE);


PendingIntent​ pendingIntent = ​PendingIntent​.getService(​this​, ​0​, myIntent, ​0​);
Calendar​ calendar = ​Calendar​.getInstance();

calendar.​set​(​Calendar​.SECOND, ​0​);

calendar.​set​(​Calendar​.MINUTE, ​0​);

calendar.​set​(​Calendar​.HOUR, ​0​);

calendar.​set​(​Calendar​.AM_PM, ​Calendar​.AM);
[Link](​Calendar​.DAY_OF_MONTH,​1​);
[Link](​AlarmManager​.RTC_WAKEUP, [Link](),
1000​*​60​*​60​*​24​ , pendingIntent);

This will trigger Alarm ​each day at midnight (12 am).​ You can change that if you want.

Now, create a Service ​NotifyService​ and put this code in its ​onCreate()​:

@Override​ ​public​ ​void​ onCreate() {

NotificationManager​ mNM =
(​NotificationManager​)getSystemService(NOTIFICATION_SERVICE);

​Notification​ notification = ​new​ ​Notification​([Link].notification_icon,


"Notify Alarm strart"​, ​System​.currentTimeMillis());

​Intent​ myIntent = ​new​ ​Intent​(​this​ , ​MyActivity​.​class​);

​PendingIntent​ contentIntent = ​PendingIntent​.getActivity(​this​, ​0​, intent, ​0​);


[Link](​this​, ​"Notify label"​, ​"Notify text"​,
contentIntent);

[Link](NOTIFICATION, notification); }

And this code will show the notification when the Alarm is received.
Good Luck!

You might also like