Android

Android Singleton with Serializable aspects looked at.
Author : Ishtek

Using Android API Level : 7 

In this very article, as an Author of this Page, I shall be showing few ways to 
work with a design pattern that makes a class always a single instance in 
a classloader within a single JVM. Yes, you have guess it right, it is Singleton design
pattern I am going to discuss about on this page.

First of all, how to write code for making a class file to be always having a single
instance across a classloader in a JVM. There are few points to remember, such as:
1. There should be only one constructor defined with a private access specifier, so as
   to disable any direct instantiation of this class using new operator.
   
   For example, if this class is having a name as DemoSingleton, then,
   
private DemoSingleton() { .... }
2. This class should have final as class-level access specifier, so as to restrict sub-classing of this class, and by this, avoiding risk of applying cloning to the object. For example,
public final class DemoSingleton
3. There should be a class-level variable with private as access scope for this variable. For example,
private static DemoSingleton demoInstance;
4. A static method, ideally named as getInstance (I think, for easy readability), should have a return type as this Singleton class, internally this method instantiate this Singleton class, once and only once and returns it before exiting this method. For example,
public static DemoSingleton getInstance() { .. }
5. Some additional precautions are to be taken care of, such as if this class to be used as a Singleton in a multi-threaded execution environment, then special care has to be taken while coding. By writing check for the instance-static-variable has for null, synchronizing block for this class-level as argument, checking null again, before instantiating this class and then returning appropriate object of this singleton class. The above mentioned code-path will be executed for the very first-time this method getting called by any thread, then after any call to this method would return that same instance-level variable only.
public static DemoSingleton getInstance() { if(demoInstance == null) { synchronized (DemoSingleton.class) { if(demoInstance == null) { demoInstance = new DemoSingleton(); } } } return demoInstance; }
Here is the code for the DemoSingleton:
import java.io.Serializable; public final class DemoSingleton implements Serializable { private static DemoSingleton demoInstance; private DemoSingleton() { } public static DemoSingleton getInstance() { if(demoInstance == null) { synchronized (DemoSingleton.class) { if(demoInstance == null) { demoInstance = new DemoSingleton(); } } } return demoInstance; } }
Yes, you might have noticed that this class is implementing java.io.Serializable interface, why?? let me explain this: In this page I shall demonstrate a typical scenario, whereby how this class that we have defined as Singleton, behaves when serialized and de-serialized again. Whether de-serialized object is same as that of the serialized object or not? Following text client class checks this only:
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class DemoMain { public DemoMain() { File file = new File("tmp.txt"); DemoSingleton demoSingleton = DemoSingleton.getInstance(); writeToFile(file, demoSingleton); DemoSingleton demoingletonSerialized = readFromFile(file); System.out.println(demoSingleton+" "+demoingletonSerialized); } private DemoSingleton readFromFile(File file) { DemoSingleton demoSignle = null; FileInputStream fin = null; ObjectInputStream din = null; try { fin = new FileInputStream(file); din = new ObjectInputStream(fin); demoSignle = (DemoSingleton) din.readObject(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { din.close(); fin.close(); } catch (IOException e) { e.printStackTrace(); } } return demoSignle; } public void writeToFile(File file, DemoSingleton obj) { FileOutputStream fout = null; ObjectOutputStream dout = null; try { fout = new FileOutputStream(file); dout = new ObjectOutputStream(fout); dout.writeObject(obj); } catch (IOException e) { e.printStackTrace(); } finally { try { dout.close(); fout.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * @param args */ public static void main(String[] args) { new DemoMain(); } }
Whileing running this Java client program, following result is observed.
DemoSingleton@1ef8cf3 DemoSingleton@ecd7e
The first one is the singleton object before serializing, and the other object reference is after de-serializing this singleton object. This means this DemoSingleton class is not behaving appropriately in serialization process, so to make it behave properly in multi-threaded and serialization process, we need to override readResolve method as shown below:
import java.io.Serializable; public final class DemoSingleton implements Serializable { private static DemoSingleton demoInstance; private DemoSingleton() { } public static DemoSingleton getInstance() { if(demoInstance == null) { synchronized (DemoSingleton.class) { if(demoInstance == null) { demoInstance = new DemoSingleton(); } } } return demoInstance; } protected Object readResolve() { return demoInstance; } }
Now whileing running this client program, following is the result/output as shown on screen.
DemoSingleton@1ef8cf3 DemoSingleton@1ef8cf3
Both these object references are the same, this means we have identical object for the pre-serializing and post de-serializing effects to this DemoSingleton class. Please share your thought or anything missing in this approach, or any better ways of coding this, by writing on this page. Now let us explore this Singleton code in an Android Emulator, For this we got to create an application for Android Platform, and for this I have used Eclipse with ADT plugin. Idea of this example is to create two activities and a DemoSingleton class files. In the first/main activity, I am going to get a reference to the DemoSingleton instance, set the textview with the initialState value as 'Hello' and then setting the initialState with a piece of text, such as 'I am Good'. There will be a button to start other activity by using Intent. This second activity is going to get an intance of DemoSingleton, and retrieve initialState value and show on screen text view. The what will we get to see on screen is shown in the images below,
Various code/files are as follows: First/Main Activity Java file: MainActivity.java
package com.example.singletonexample; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DemoSingleton demoSingleton = DemoSingleton.getInstance(); TextView txtView = (TextView) findViewById(R.id.txtView); txtView.setText(demoSingleton.getInitialState()); demoSingleton.setInitialState("I am good !!"); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Intent intent = new Intent(getApplicationContext(),DemoActivity.class); startActivity(intent); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
Second Activity Java file: DemoActivity.java
package com.example.singletonexample; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.TextView; public class DemoActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo); TextView txtView = (TextView) findViewById(R.id.txtViewDemo); txtView.setText(DemoSingleton.getInstance().getInitialState()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_demo, menu); return true; } }
And the DemoSingleton Java file as follows: DemoSingleton.java
package com.example.singletonexample; public final class DemoSingleton { private String initialState="Hello"; private static DemoSingleton demoInstance; private DemoSingleton() { } public static DemoSingleton getInstance() { if(demoInstance == null) { synchronized (DemoSingleton.class) { if(demoInstance == null) { demoInstance = new DemoSingleton(); } } } return demoInstance; } protected Object readResolve() { return demoInstance; } public String getInitialState() { return initialState; } public void setInitialState(String initialState) { this.initialState = initialState; } }
Rest of the file you can get it soon, I shall be creating a GITHUB repository for these files. Please keep an watch on this Page for more details to follow. The complete source code is listed below :
Singleton-Example-Android/.classpath

<?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="gen"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> <classpathentry kind="output" path="bin/classes"/> </classpath>


Singleton-Example-Android/.project

<?xml version="1.0" encoding="UTF-8"?> <projectDescription> <name>SingletonExample</name> <comment></comment> <projects> </projects> <buildSpec> <buildCommand> <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name> <arguments> </arguments> </buildCommand> <buildCommand> <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name> <arguments> </arguments> </buildCommand> <buildCommand> <name>org.eclipse.jdt.core.javabuilder</name> <arguments> </arguments> </buildCommand> <buildCommand> <name>com.android.ide.eclipse.adt.ApkBuilder</name> <arguments> </arguments> </buildCommand> </buildSpec> <natures> <nature>com.android.ide.eclipse.adt.AndroidNature</nature> <nature>org.eclipse.jdt.core.javanature</nature> </natures> </projectDescription>


Singleton-Example-Android/AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.singletonexample" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" /> <application android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".DemoActivity" android:label="@string/title_activity_demo" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

Singleton-Example-Android/project.properties

# This file is automatically generated by Android Tools. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This file must be checked in Version Control Systems. # # To customize properties used by the Ant build system edit # "ant.properties", and override values to adapt the script to your # project structure. # # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. target=android-7


Singleton-Example-Android/res/layout/activity_demo.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/txtViewDemo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" tools:context=".DemoActivity" /> </RelativeLayout>


Singleton-Example-Android/res/layout/activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/txtView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" tools:context=".MainActivity" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click Me!!"/> </RelativeLayout>


Singleton-Example-Android/res/menu/activity_demo.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_settings" android:title="@string/menu_settings" android:orderInCategory="100" /> </menu>


Singleton-Example-Android/res/menu/activity_main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_settings" android:title="@string/menu_settings" android:orderInCategory="100" /> </menu>


Singleton-Example-Android/res/values/strings.xml

<resources> <string name="app_name">SingletonExample</string> <string name="hello_world">Hello world!</string> <string name="menu_settings">Settings</string> <string name="title_activity_main">MainActivity</string> <string name="title_activity_demo">DemoActivity</string> </resources>


Singleton-Example-Android/res/values/styles.xml

<resources> <style name="AppTheme" parent="android:Theme.Light" /> </resources>


Singleton-Example-Android/src/com/example/singletonexample/DemoActivity.java

/** * @author Ishteak * @Contact reaching@techiecommunity.net * THESE SOURCE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THESE * SOURCE CODE. */ package com.example.singletonexample; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.TextView; public class DemoActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_demo); TextView txtView = (TextView) findViewById(R.id.txtViewDemo); txtView.setText(DemoSingleton.getInstance().getInitialState()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_demo, menu); return true; } }


Singleton-Example-Android/src/com/example/singletonexample/DemoSingleton.java

/** * @author Ishteak * @Contact reaching@techiecommunity.net * THESE SOURCE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THIS * SOURCE CODE. */ package com.example.singletonexample; public final class DemoSingleton { private String initialState="Hello"; private static DemoSingleton demoInstance; private DemoSingleton() { } public static DemoSingleton getInstance() { if(demoInstance == null) { synchronized (DemoSingleton.class) { if(demoInstance == null) { demoInstance = new DemoSingleton(); } } } return demoInstance; } protected Object readResolve() { return demoInstance; } public String getInitialState() { return initialState; } public void setInitialState(String initialState) { this.initialState = initialState; } }


Singleton-Example-Android/src/com/example/singletonexample/MainActivity.java

/** * @author Ishteak * @Contact reaching@techiecommunity.net * THESE SOURCE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THIS * SOURCE CODE. */ package com.example.singletonexample; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DemoSingleton demoSingleton = DemoSingleton.getInstance(); TextView txtView = (TextView) findViewById(R.id.txtView); txtView.setText(demoSingleton.getInitialState()); demoSingleton.setInitialState("I am good !!"); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Intent intent = new Intent(getApplicationContext(),DemoActivity.class); startActivity(intent); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }


If interested in commenting related to Android Singleton Serializable
Click Here

Name (To be shown on this Page:*

Email (Not to be shown):*

Website (To be shown on this Page)

Your Comments here (To be shown on this Page):*

(You can use <a> Tag in your comments)

Please enter same number as shown here 698




Android Thread Example

REST Interview Questions

JAX-WS Webservice Example

Android Overlap SurfaceView Example

Spring3 Integration of File Endpoint

JAXWS Webservice Example

Android WebView Example

Android Context Menu Example

Setting up Eclipse for Android App Development

Android SensorEvent Orientation Example

Android ImageSwitcher Example

REST API Design for Android App

Android ExpandableListView Example

Singleton Serializable on Android

Android GPS with Google MAP Example

Android Project With Example

Android Project Manageing Files

Project Ideas for App on Android Platform

Android EditText with Background

Android SQLite Database Example

Android AutoCompleteTextView Example

Android Tester

Android Interview Questions

Android ListView Example

Android Intent Notification Example

Android Intent Broadcast Example

Android TextView Link Example

Android Sensor List

Android Sensor Orientation Example

Android Intent Broadcast Receiver

Android Gallery SurfaceViews Example

Android Location Example

Android Text to Speech Example

Android Intent Example

Android Layout Example

Android Download File Example

Android Expandable ListView Example

Android Tab Example

Android RelativeLayout Example

Android Intent Example

Android Text to Speech Example

Android SQLite Example

Android CustomView Example

Android Canvas Example

Android SharedPreferences Example

Android Shape Background Example

Android ShapeButton Example

Android ViewFlipper Example

Android Gallery Example

Android TimePickerDialog Example





If interested commenting on this Page :

comments powered by Disqus
Any source code found on any of the page(s) in Techiecommunity.net is associated with following notice: 
   /*
     * TECHIECOMMUNITY.NET MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
     * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
     * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
     * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. TECHIECOMMUNITY.NET SHALL NOT BE LIABLE FOR
     * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
     * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
     *
     * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
     * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
     * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
     * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
     * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
     * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
     * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). TECHIECOMMUNITY.NET
     * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
     * HIGH RISK ACTIVITIES.
     */
   
The content provided in this page is NOT warranted and/or NOT guaranteed by techiecommunity.net .
techiecommunity.net is not liable for any negative consequences that may result/arise from 
implementing directly/indirectly any information covered in these pages/articles/tutorials.

For any of the content, if you would like to bring it to notice for removal from this web site, 
please write to this web site administrator @ EMAIL-ID (please remove space before and after @),
with appropriate concern and supporting proof(s). After thorough review and if found genuine concern,
we would take appropriate action and remove disputed content from this web site within 24 hours 
starting from the time it has brought to techiecommunity.net Administrator notice.

This website uses cookies and third party cookies to improve the user experience. 
And to provide more relevant ads. 
In case of continued use of this website implies that you accept the use of cookies on this website.
		
While using this web site, you agree to have read and accepted techiecommunity.net terms of use and privacy policy.