Monthly Archives: February 2016

Android maintain Fragment State

In this post I would like to focus on one unclear issue during the Android development.

Every body who has worked with Fragment object in Android and he spend at least 1-2 hours to understand how those objects work, he will know that onCreateView() of the Fragment object is called when the fragment is showing for the first time and also when the fragment is resume when user press back button and return to it from previous screen (does not matter Activity or Fragment).

So this point is a little bit sensitive and if you want to have good performance in your app you have to manage it very well. There have 3 base opinions about,  which way is the right way. I will put here them and at the end I will leave my comment about this issue.

  1. Use onSaveInstanceState() in Fragment object to handle the fragment state.
  2. Create instance inside your Fragment of the rootview and keep it until this Fragment is live;
  3. Leave Fragment object to recreate its views by it self every time when it is created/returned from the activity back stack in onCreateView() method;

Well I think the the most right way is the 3-th one and I am applying it in all my fragments.

The second decision is also fine and easy but it have one big problem, when you have to use more then 2-3 instances of your fragments this will consume a lot of memory and the GC will not release this unnecessary objects. Look at this code:

public class SomeFragment extends Fragment {
    View rootView;
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        if (rootView == null) {
            rootView = inflater.inflate(R.layout.fragment_a, container, false);
            // Setup subviews
        } else {
            // Do not inflate the layout again.
            // The returned View of onCreateView will be added into the fragment.
            // However it is not allowed to be added twice even if the parent is same.
            // So we must remove _rootView from the existing parent view group
            // (it will be added back).
            ((ViewGroup)rootView.getParent()).removeView(rootView);
        }
        return rootView;
    }
}

It seems that you will create only ones your views (inflate) and after that you will miss that part, easy but it will cost problems with the memory for future. You can use this method only if your app has 2-3 screens in one Activity and it doesn’t need more memory and more screens, but if you need then DON’T DO IT.

And the end of this talk I will finally say my solution about the issue:

Leave your Fragment to recreate it’s views  every time when it create it self for the first time or return from the activity back stack. Keep references to your data (Lists) or save them state on the Fragment  onSaveInstanceState() and after that reuse only the data.

Note: Every time when you recreate your views you need to load all fragment data to the new views (they will have new references in the memory, they will be totally new objects), because for example if you have Adapter attached to the RecyclerView, and you recreate your recycler view, the new recycler view need to be associated with this old adapter object. You don’t need to recreate your data list and attached to the adapter ,it is already  there. You just need to tell to the news recyclerview that it’s adapter is the old adapter, otherwise you will see empty recyclerview object without any dat in it.

I hope this explanation  will be useful to somebody and the issue will be clear for all of us.

Android Development – Good Quick Tips

You can download file with more description : – > ANDROID_USEFUL_TIPS

 

Android SDK

Place your Android SDK somewhere in your home directory or some other application-independent location. Some IDEs include the SDK when installed, and may place it under the same directory as the IDE. This can be bad when you need to upgrade (or reinstall) the IDE, or when changing IDEs. Also avoid putting the SDK in another system-level directory that might need sudo permissions, if your IDE is running under your user and not under root.

Project structure

There are two popular options: the old Ant & Eclipse ADT project structure, and the new Gradle & Android Studio project structure. You should choose the new project structure. If your project uses the old structure, consider it legacy and start porting it to the new structure.
Old structure:
old-structure
├─ assets
├─ libs
├─ res
├─ src
│ └─ com/futurice/project
├─ AndroidManifest.xml
├─ build.gradle
├─ project.properties
└─ proguard-rules.pro
New structure:
new-structure
├─ library-foobar
├─ app
│ ├─ libs
│ ├─ src
│ │ ├─ androidTest
│ │ │ └─ java
│ │ │ └─ com/futurice/project
│ │ └─ main
│ │ ├─ java
│ │ │ └─ com/futurice/project
│ │ ├─ res
│ │ └─ AndroidManifest.xml
│ ├─ build.gradle
│ └─ proguard-rules.pro
├─ build.gradle
└─ settings.gradle
The main difference is that the new structure explicitly separates ‘source sets’ (main, androidTest), a concept from Gradle. You could, for instance, add source sets ‘paid’ and ‘free’ into src which will have source code for the paid and free flavours of your app.
Having a top-level app is useful to distinguish your app from other library projects (e.g., library-foobar) that will be referenced in your app. The settings.gradle then keeps references to these library projects, which app/build.gradlecan reference to.

There are short list with useful tips:

      Use Gradle and its recommended project structure

 

      Put passwords and sensitive data in gradle.properties

 

      Use the Jackson library to parse JSON data

 

      Don’t write your own HTTP client, use Volley or OkHttp libraries

 

      Avoid Guava and use only a few libraries due to the 65k method limit

 

      Use Fragments to represent a UI screen

 

      Use Activities just to manage Fragments

 

      Layout XMLs are code, organize them well

 

      Use styles to avoid duplicate attributes in layout XMLs

 

      Use multiple style files to avoid a single huge one

 

      Keep your colors.xml short and DRY, just define the palette

 

      Also keep dimens.xml DRY, define generic constants

 

      Do not make a deep hierarchy of ViewGroups

 

      Avoid client-side processing for WebViews, and beware of leaks

 

      Use Robolectric for unit tests, Robotium for connected (UI) tests

 

      Use Genymotion as your emulator

 

      Always use ProGuard or DexGuard

 

      Use SharedPreferences for simple persistence, otherwise ContentProviders

 

    Use Stetho to debug your application