Best practice for instantiating a new Android Fragment

If Android decides to recreate your Fragment later, it’s going to call the no-argument constructor of your fragment. So overloading the constructor is not a solution.

With that being said, the way to pass stuff to your Fragment so that they are available after a Fragment is recreated by Android is to pass a bundle to the setArguments method.

So, for example, if we wanted to pass an integer to the fragment we would use something like:

public static MyFragment newInstance(int someInt) {
    MyFragment myFragment = new MyFragment();

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    myFragment.setArguments(args);

    return myFragment;
}

And later in the Fragment you can access that integer by using:

getArguments().getInt("someInt", 0);

This Bundle will be available even if the Fragment is somehow recreated by Android.

Also note: setArguments can only be called before the Fragment is attached to the Activity.

Android Studio Rename Package

In Android Studio, you can do this:

For example, if you want to change com.example.app to my.awesome.game, then:

  1. In your Project pane, click on the little gear icon ( Gears icon )
  2. Uncheck / De-select the Compact Empty Middle Packages option

Compact Empty Middle Packages

  1. Your package directory will now be broken up in individual directories
  2. Individually select each directory you want to rename, and:
    • Right-click it
    • Select Refactor
    • Click on Rename
    • In the Pop-up dialog, click on Rename Package instead of Rename Directory
    • Enter the new name and hit Refactor
    • Allow a minute to let Android Studio update all changes
    • Note: When renaming com in Android Studio, it might give a warning. In such case, selectRename All

enter image description here

  1. Now open your Gradle Build File (build.gradle – Usually app or mobile). Update the applicationId to your new Package Name and Sync Gradle, if it hasn’t already been updated automatically:

Refactor Directories

  1. Done! Anyways, Android Studio needs to make this process a little simpler.

Floating Action Buttons in Android Lollipop

At 2014 Google I/O, Google announced a new visual language called Material Design. Material Design guides creation of user experiences that work well on different devices, with different input methods and on different platforms. Google is gradually implementing Material Design in their apps and products, and we can start playing with it, too.

One interesting new design pattern is the promoted action, implemented as a floating action button. This pattern exemplifies the underlying principles of Material Design and is a good place to start adapting existing applications to the new version of Android.

You can see from Google’s guidelines that there are many ways to apply this pattern incorrectly, as evidenced by the various “Don’ts” on that page. Today, I want to show you how to implement a floating action button without creating a “Don’t” yourself.

Float Like a Button, Sting Like an Action

If you are just as excited as I am to get my hands dirty and create clean user interfaces with Google’s Material Design, you have probably already downloaded Android Studio 1.0 and Android Lollipop emulator images. If not, go ahead and do so now.

Our Criminal Intent project is a perfect fit for this tutorial. If you haven’t done so, grab your copy ofAndroid Programming: The Big Nerd Ranch Guide and work through Chapters 7-22. (If you’ve done this a long time ago and can’t locate your code, you can also get the solutions from our website).

In the Criminal Intent app, the “Add New Crime” button appears in the Action Bar. It’s a good candidate to be the promoted action, so we will update the app for Lollipop. This is what our final result will look like:

Floating action button

Replacing the Menu Item

Before we work on the button, we need to remove the “Add New Crime” menu item, by creating the res/menu-v21/fragment_crime_list.xml file:

    <!-- res/menu-v21/fragment_crime_list.xml -->
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@+id/menu_item_show_subtitle"
              android:title="@string/show_subtitle"
              android:showAsAction="never"/>
    </menu>

Now it’s time to add the button. Since CrimeListFragment is a subclass of ListFragment, we didn’t have to define a layout for it. We’ll do this here, by creating fragment_crime_list.xml in layout-v21:

    <!-- res/layout-v21/fragment_crime_list.xml -->
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent">

        <include layout="@android:layout/list_content"/>

        <ImageButton
            android:id="@+id/add_button"
            android:layout_width="@dimen/round_button_diameter"
            android:layout_height="@dimen/round_button_diameter"
            android:layout_gravity="end|bottom"
            android:layout_marginBottom="@dimen/add_button_margin"
            android:layout_marginEnd="@dimen/add_button_margin"
            android:src="@android:drawable/ic_input_add"/>

    </FrameLayout>

We will use this layout for Lollipop and fall back to the super implementation for previous versions (in CrimeListFragment.java):

    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        View v;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            v = inflater.inflate(R.layout.fragment_crime_list, parent, false);
        } else {
            v = super.onCreateView(inflater, parent, savedInstanceState);
        }

At the time of the original post Lollipop hadn’t come out yet. Because Android L was a preview release, things worked a bit differently. Build.VERSION_CODES.L did exist, but its value was set to 10000. The Android L emulator’s Build.VERSION.SDK_INT was 20. Thus we had to use code KITKAT_WATCH, even though it referred to v20 and not v21. Now that Lollipop is out, we don’t have to play with numbers.

Changing the Look and Feel

So far, the button doesn’t look like the floating action button we want. Let’s change the tint and background:

android:tint="@android:color/white"
android:background="@drawable/oval"

Better! But it’s still not floating. For that, we need to change its elevation:

android:elevation="@dimen/elevation_low"

Because the button is still rectangular, the elevated button drops a rectangular shadow. Fortunately, we can change the button’s outline and clip it (in CrimeListFragment.java):

    // CrimeListFragment.java - onCreateView()
    View addButton = v.findViewById(R.id.add_button);
    addButton.setOutlineProvider(new ViewOutlineProvider() {
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void getOutline(View view, Outline outline) {
            int diameter = getResources().getDimensionPixelSize(R.dimen.diameter);
            outline.setOval(0, 0, diameter, diameter);
        }
    });
    addButton.setClipToOutline(true);

In Lollipop, the API changed a bit. Thanks to our commenters for pointing it out. Instead of setOutline, we now use setOutlineProvider.

The evolution of the button:

Button 1Button 2Button 3Button 4

Adding the Ripple Effect and Shadow

We’re almost done! We just need to do two things. First, we need to bring back the ripple effect. Second, we need to change the size of the shadow when the button is pressed.

To re-enable the ripple, we need to change the button’s background from a static shape to a rippleandroid:background="@drawable/oval_ripple" and create the oval_ripple drawable:

    <!-- res/drawable/oval_ripple.xml -->
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:colorControlHighlight">
        <item>
            <shape android:shape="oval">
                <solid android:color="?android:colorAccent"/>
            </shape>
        </item>
    </ripple>

The last effect is to increase the size of the shadow, and we need to lift the button up after we push down on it. To make it happen, add one more property to the button: android:stateListAnimator="@anim/button_elevation" and create the button_elevation animation:

    <!-- res/anim/button_elevation.xml -->
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true">
            <objectAnimator
                android:propertyName="translationZ"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueFrom="@dimen/elevation_low"
                android:valueTo="@dimen/elevation_high"
                android:valueType="floatType"/>
        </item>
        <item>
            <objectAnimator
                android:propertyName="translationZ"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueFrom="@dimen/elevation_high"
                android:valueTo="@dimen/elevation_low"
                android:valueType="floatType"/>
        </item>
    </selector>

These are the values in dimens.xml:

    <!-- res/values/dimens.xml -->
    <dimen name="diameter">48dp</dimen>
    <dimen name="elevation_low">1dp</dimen>
    <dimen name="elevation_high">4dp</dimen>
    <dimen name="add_button_margin">16dp</dimen>

Finally, the button needs to perform the action that used to be accessible via the Action Bar, so we add the OnClickListener:

    addButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            addNewCrime();
        }
    });

Here’s the zoomed in view of the finished result:

Final floating action button

That’s it! With just a handful of new XML files and code, we kicked off the redesign of the Criminal Intent app and implemented a floating action button. There is a lot more to Material Design; read the guidelines, but keep in mind that they’re still being refined.

Android Tab Layout with Swipeable Views

My previous article explains about Android Tab Layoutand it got very good ranking in search engines. But unfortunately TabHost is deprecated by android in favor of fragments. So it is suggested that use fragment to achieve tab layout.

This article shows you how to create tab layout using fragments and viewpager. Also you can swipe between tab view as it is the functionality of viewpager which is not possible when using TabHost.

VIDEO DEMO

ViewPager and Fragments

Before getting into this tutorial it is suggested to have knowledge on Fragments and ViewPager as these two are main concepts used here. Unfortunately I haven’t covered about fragements and viewpager on androidhive :(

Layout Overview

Checkout the following pic which explains the complete overview of layout architecture. Basically we are using ViewPager as main layout and for individual pager views we use Fragments. The tabs are part of Action Bar.

android tab layout with swipeable views

Creating new Project

Even though you are not familiar with ViewPager or Fragments, don’t worry. You will get an idea about what those are and how to use them once you are done through this article. So let’s start by creating a new project.

1. Create a new project in Eclipse from File ⇒ New ⇒ Android ⇒ Application Project. While creating the project select the app theme which has Action Bar as shown in the below image.

android tabs with swipe gesture

2. As we are going to use Fragments, extend your main activity from FragmentActivity. Alsoimplement this class from ActionBar.TabListener as we are adding Tabs too.

public class MainActivity extends FragmentActivity implements
        ActionBar.TabListener {

3. Open main activity layout file and add ViewPager element. (My layout file for main activity isactivity_main.xml)

activity_main.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</android.support.v4.view.ViewPager>

4. I normally prefer to create a separate package for adapter classes just to separate them from activity classes. So create a new package named your_package_name.adapter. I named my new package asinfo.androidhive.tabsswipe.adapter

5. I am creating a FragmentPagerAdapter class to provide views to tab fragments. Create a class called TabsPagerAdapter.java under adapter package. This adapter provides fragment views to tabs which we are going to create them later in this tutorial.

TabsPagerAdapter.java
package info.androidhive.tabsswipe.adapter;
import info.androidhive.tabsswipe.GamesFragment;
import info.androidhive.tabsswipe.MoviesFragment;
import info.androidhive.tabsswipe.TopRatedFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
public class TabsPagerAdapter extends FragmentPagerAdapter {
    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
    }
    @Override
    public Fragment getItem(int index) {
        switch (index) {
        case 0:
            // Top Rated fragment activity
            return new TopRatedFragment();
        case 1:
            // Games fragment activity
            return new GamesFragment();
        case 2:
            // Movies fragment activity
            return new MoviesFragment();
        }
        return null;
    }
    @Override
    public int getCount() {
        // get item count - equal to number of tabs
        return 3;
    }
}

Adding Tabs to Action Bar

6. In order to display tabs we don’t have to use any other UI element like TabHost. Action bar has the inbuilt capability of adding tabs. All we have to do is enable it usingsetNavigationMode(ActionBar.NAVIGATION_MODE_TABS) method. Open your MainActivity.javado the following.

Here I am adding three tabs Top Rated, Games, Movies to action bar. So I just stored all the tab names in a String array and added them to action bar using a for loop.

MainActivity.java
public class MainActivity extends FragmentActivity implements
        ActionBar.TabListener {
    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    // Tab titles
    private String[] tabs = { "Top Rated", "Games", "Movies" };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Initilization
        viewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getActionBar();
        mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(mAdapter);
        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);       
        // Adding Tabs
        for (String tab_name : tabs) {
            actionBar.addTab(actionBar.newTab().setText(tab_name)
                    .setTabListener(this));
        }

If you run the project, you can see the tabs displaying under action bar.

android action bar adding tabs

Adding Views for Tabs

We already returned respected fragments for tabs in the adapter class. To make it simple I am creating very simple layout for each tab and leaving it to you to build your own UI depending on your requirement. For now I just displayed a label in the view with some background color.

» First Tab View

7. The first tab I added is Top Rated. Create a new layout file under src ⇒ res folder namedfragment_top_rated.xml and paste the following code.

fragment_top_rated.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#fa6a6a" >
    
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Design Top Rated Screen"
        android:textSize="20dp"
        android:layout_centerInParent="true"/>
    
</RelativeLayout>

8. Also create respected Fragment activity class for this view. Create a new class namedTopRatedFragment.java under your main package.

TopRatedFragment.java
package info.androidhive.tabsswipe;
import info.androidhive.tabsswipe.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class TopRatedFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);
        
        return rootView;
    }
}

» Second Tab View

The second tab in the list is Games. Just like above create a layout file and activity file for this tab.

9. Create a new layout file under src ⇒ res folder named fragment_games.xml

fragment_games.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#ff8400" >
    
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Design Games Screen"
        android:textSize="20dp"
        android:layout_centerInParent="true"/>
    
</RelativeLayout>

10. Create a new class named GamesFragment.java with following code.

package info.androidhive.tabsswipe;
import info.androidhive.tabsswipe.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class GamesFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_games, container, false);
        
        return rootView;
    }
}

» Third Tab View

This third tab is Movies. This one need a layout file and activity class.

11. Create a layout file called fragment_movies.xml

fragment_movies.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#17df0d">
    
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Design Movies Screen"
        android:textSize="20dp"
        android:layout_centerInParent="true"/>
    
</RelativeLayout>

12. Also create activity class for this view named MoviesFragment.java

MoviesFragment.java
package info.androidhive.tabsswipe;
import info.androidhive.tabsswipe.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MoviesFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_movies, container, false);
        
        return rootView;
    }
}

Run the project and check whether the views for tabs are added or not.

Android Tab Layout with Swipeable Views

And this is how it looks in landscape mode

Android-Tab-Layout-with-Swipeable-Views-landscape

Tab Change Listener

If you run the project you can see the swiping views working, but if you select a tab, view won’t change automatically. This is because ViewPager didn’t know about the tab change event. We have to manually change the view using Tab change listener.

13. In your MainActivity.java class add following code.

@Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }
    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // on tab selected
        // show respected fragment view
        viewPager.setCurrentItem(tab.getPosition());
    }
    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    }

View Change Listener

14. As well if you swipe the view, you can’t see respected tab selected. Here also using ViewPagersetOnPageChangeListener() we have to select the respected tab manually.

/**
 * on swiping the viewpager make respective tab selected
 * */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageSelected(int position) {
        // on changing the page
        // make respected tab selected
        actionBar.setSelectedNavigationItem(position);
    }
    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {
    }
    @Override
    public void onPageScrollStateChanged(int arg0) {
    }
});

After adding these two listeners, if you run the project you can see everything working good.

Complete Code

Below is the complete code for MainActivity.java class

MainActivity.java
package info.androidhive.tabsswipe;
import info.androidhive.tabsswipe.adapter.TabsPagerAdapter;
import info.androidhive.tabsswipe.R;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.Menu;
public class MainActivity extends FragmentActivity implements
        ActionBar.TabListener {
    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    // Tab titles
    private String[] tabs = { "Top Rated", "Games", "Movies" };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Initilization
        viewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getActionBar();
        mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(mAdapter);
        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);       
        // Adding Tabs
        for (String tab_name : tabs) {
            actionBar.addTab(actionBar.newTab().setText(tab_name)
                    .setTabListener(this));
        }
        /**
         * on swiping the viewpager make respective tab selected
         * */
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }
            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }
            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });
    }
    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }
    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // on tab selected
        // show respected fragment view
        viewPager.setCurrentItem(tab.getPosition());
    }
    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    }
}

Don’t Store Data in the Application Object

There is always some information that is needed in many places in your app. It can be a session token, the result of an expensive computation, etc. It is often tempting to avoid the overhead of passing objects between activities or keeping those in persistent storage.

A pattern that is sometimes suggested is to dump your data in the Application object with the idea that it will be available across all activities. This solution is simple, elegant and… totally wrong.

If you assume that your data will stay there, your application will eventually crash with a NullPointerException.

A Simple Test Case

The Code

The Application object:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// access modifiers omitted for brevity
class MyApplication extends Application {

    String name;

    String getName() {
        return name;
    }

    void setName(String name) {
        this.name = name;
    }
}

The first activity, where we store the name of the user in the application object:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// access modifiers omitted for brevity
class WhatIsYourNameActivity extends Activity {

    void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.writing);

        // Just assume that in the real app we would really ask it!
        MyApplication app = (MyApplication) getApplication();
        app.setName("Developer Phil");
        startActivity(new Intent(this, GreetLoudlyActivity.class));

    }

}

The second activity, where we shout the name of the user:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// access modifiers omitted for brevity
class GreetLoudlyActivity extends Activity {

    TextView textview;

    void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.reading);
        textview = (TextView) findViewById(R.id.message);
    }

    void onResume() {
        super.onResume();

        MyApplication app = (MyApplication) getApplication();
        textview.setText("HELLO " + app.getName().toUpperCase());
    }
}

The Scenario

  1. The user starts the app.
  2. In WhatIsYourNameActivity, you ask for the name of the user and you store it in MyApplication.
  3. In GreetLoudlyActivity, you fetch the user’s name from the MyApplication object and display it.
  4. The user leaves the app using the home button.
  5. A few hours later, Android silently kills the app to reclaim some memory.

    So far, so good!

    But here comes the crashy part…

  6. The user reopens the app.
  7. Android creates a new MyApplication instance and restores GreetLoudlyActivity.
  8. GreetLoudlyActivity fetches the user’s name, which is now null, and crashes with a NullPointerException.

Why Does it Crash?

In this sample, we crash because the Application object is brand new, so the name variable is null, leading to a NullPointerException when we call String#toUpperCase() on it.

Which brings us to the core of the problem: The application object will not stay in memory forever, it will get killed. Contrary to popular belief, the app won’t be restarted from scratch. Android will create a new Application object and start the activity where the user was before to give the illusion that the application was never killed in the first place.

Which means that if you expect some data to be in your application object just because your user is not supposed to be able to open activity B before activity A, you are in for a crashy surprise.

What Are The Alternatives

There is no magic solution here, you can do one of the following:

  • Explicitly pass the data to the Activity through the intent.
  • Use one of the many ways to persist the data to disk.
  • Always do a null-check and handle it manually.

How To Simulate The Application Being Killed

EDIT: As pointed out by Daniel Lew, an easier way to kill your app is to simply use the “Stop Process” feature in DDMS. This will work on any phone as long as your application is debuggable.**

To test this, you must use an emulator or a rooted phone.

  1. Exit your app using the home button.
  2. In a terminal:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# find the process id
adb shell ps
# then find the line with the package name of your app

# Mac/Unix: save some time by using grep:
adb shell ps | grep your.app.package

# The result should look like:
# USER      PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
# u0_a198   21997 160   827940 22064 ffffffff 00000000 S your.app.package

# Kill the app by PID
adb shell kill -9 21997

# the app is now killed
  1. Now return to the app using the task switcher.
    You are now on a new application instance.

The Bottom Line

Storing data in the application object is error prone and can crash your app. Prefer storing your global data on disk if it is really needed later or explicitly pass it to your activity in the intent’s extras.

Also remember that while this is true for the application object, it is also true for any singleton or public static field that you might have in your app.

Creating Global Session Variables for all Activities Android Example

Here is an Android example of how to share variables through out your activities and your project. There is many ways including preferences, extending from a base activity or using  a database to share variables. I like this one because it can be accessed through the whole project and it is easy to implement. The down side is that the variables are only available through a session. For example if the user restarts the application then all the variable will also be cleared. So they can be viewed as session variables.

GlobalState Class:

-Note this extends Application

import android.app.Application;

public class GlobalState extends Application{
	
	 public File sd = null;
	 boolean refresh = true;
	 pictureData [] picturemarkers = null;
	 
	 public File getFilePath(){
		 return sd;
	 }
	 
	 public void setFilePath(File sd){
          this.sd = sd;		 
	 }

	 public pictureData[] getPictureData(){
		 return picturemarkers;
	 }
	  
	 public void setPictureData(pictureData [] picData){
		 picturemarkers = picData;
	 }
	 
	 public void setRefresh(boolean refresh){
		 this.refresh = refresh;
	 }
	 
	 public boolean getRefresh(){
		 return refresh;
	 }
			 
}

ExampleActivity Class:

public class ExampleActivity extends Activity {

        GlobalState gs;

	public void onCreate(Bundle savedInstanceState) {
              gs = (GlobalState) getApplication();
        }

        public void examples(){  
            File temp = gs.getFilePath();
            if(gs.refresh()){
                gs.setRefresh(false);
             }
        }
} 


Manifest

-I do not fully understand why but it is needed for it to work.  Set the ‘name’ of your application to the path where the file is located.

<application
        android:name="your.package.name.GlobalState"

How to use static variables in activities

As previously described in Leaving an Android application, when you exit an app by pressing back button its resources are not completely destroyed immediately.

I would like to explain a concrete mistake I met multiple times, in connection with this behavior, which is easy to commit, if you forget this.

When you use static member variables in an activity you, should think about, how static variables are handled when instantiating, and how android instantiates activities.

If a static variable has an initial value it is only applied when creating the first instance. When the activity is started, when starting from app browser or by an Intent programmatically by you it becomes instantiated. When the app is first started, the first instance will be created, so obviously the static variables will get the initial values.

During the run the static variables may be killed if the activity they belong to are not visible, in this case they will have their default values when returning to the activity. If you want to restore their values in this case from some kind of stored source read this article: Maintaining global Application state

And the problem I recently met, that the opposite can also happen, the static variables may keep their values when you did not expect this. It is very easy to confirm this, just exit the application by pressing back and quickly restart it from the app browser. In such a sort time the android system will not kill the entire activity, and static variables will retain values.

So you should think over why the variable become static, to decide if it is the desired behavior for you or not. For example you can reinitialize the static variables in onCreate or onResume methods if that fits you.

How to get QuickTime Pro – FREE!!! –

STEP 1: Download QuickTime from …

http://www.apple.com/quicktime/d.

STEP 2: Open QuickTime Player.

STEP 3: GOTO Edit – Preferences – Register.

STEP 4: Enter username and password.

Pc Serials:
Registered To: CORE MAFIA
Registration Code: DFXY-5TJN-HU3N-DQXF-WDQ3

Register Name: Dawn M Fredette
Register Code: 4UJ2-5NLF-HFFA-9JW3-X2KV
===========================================
Mac Users:
Registered To: Pablo/nop
Registration code:
SMH2-6F4K-8SK9-ST5W-QKU3

===========================================
Others:
Register Name = In Memory of Abysm
Register Code = YBN7Y-9K77Y-F67B5-PNCCQ

Register Name: http://www.macmofo.com
Register Code: 3DX76-9KJ4F-CBQL9-BJBKH

Registered To: Apple Sales
Registration Code: TTVN-B66S-28V6-X84D-EBWN
===========================================

Disclaimer – This Info is for educational use it is not intentioned nor was it made in order to cause any infringements with the original creator of the software

THAT’S IT!
Hope This Helps.
datroubleshooter.