Search code examples
androidfragmentstatepageradapter

Grid-view is not formed in horizontal-scrolling-pages like home screen when app is in Background or Process is died


I am developing Horizontal Scrolling pages and tabs

MY app is working well in all devices in foreground, but when it goes to background, after one hour, the logs saying that Process com.example.myapp has died. When i reopen the app , the gridview data is not appearing but when scrolling horizontally , getView() method displaying all data like images and text.

that means app has data but view is not formed when process has died. And if i press back button and re-open the app, It is working good

My MainActivity.java is here

package com.bbgusa.bbgdemo.ui.phone;

import java.util.List;
import java.util.Vector;

import org.json.JSONObject;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.TabHost;

import com.bbgusa.bbgdemo.R;
import com.bbgusa.bbgdemo.listener.phone.CustomViewPager;
import com.bbgusa.bbgdemo.ui.chat.phone.ChatFragmentTab;
import com.bbgusa.bbgdemo.ui.dialpad.phone.DialerFragment;
import com.bbgusa.bbgdemo.ui.home.phone.AlarmFragmentPhone;
import com.bbgusa.bbgdemo.ui.home.phone.HomeFragment;
import com.bbgusa.bbgdemo.ui.home.phone.HomeFragmentTab;
import com.bbgusa.bbgdemo.ui.home.phone.InfoFragPhone;
import com.bbgusa.bbgdemo.ui.home.phone.MapPhone;
import com.bbgusa.bbgdemo.ui.home.phone.WeatherFragmentPhone;
import com.bbgusa.bbgdemo.ui.messages.phone.MessagesFragment;
import com.bbgusa.bbgdemo.ui.settings.phone.AboutFragment;
import com.bbgusa.bbgdemo.ui.tablet.ConstantsManager;
import com.bbgusa.bbgdemo.ui.tablet.OnFragmentChangedListenerPhone;
import com.bbgusa.bbgdemo.utils.common.UConnectUtils;

public class MainActivity extends FragmentActivity implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener, OnFragmentChangedListenerPhone {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main_phone);

        this.initialiseTabHost(savedInstanceState);
        initialiseViewPager();
    }


    /**
     * Initialise ViewPager
     */
    private void initialiseViewPager() {

        List<Fragment> fragments = new Vector<Fragment>();
        fragments.add(Fragment.instantiate(this,HomeFragmentTab.class.getName()));
        fragments.add(Fragment.instantiate(this, DialerFragment.class.getName()));
        fragments.add(Fragment.instantiate(this,MessagesFragment.class.getName()));
        fragments.add(Fragment.instantiate(this,ChatFragmentTab.class.getName()));
        fragments.add(Fragment.instantiate(this, AboutFragment.class.getName()));
        this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments);

        this.mViewPager = (CustomViewPager) findViewById(R.id.tabviewpager);
        this.mViewPager.setAdapter(this.mPagerAdapter);
        this.mViewPager.setOnPageChangeListener(this);
        this.mViewPager.setOffscreenPageLimit(5);
        this.mViewPager.setCurrentItem(0);
    }

    @Override
    public void onFragmentChangePhone(JSONObject response, String whichView, String title, String mPhoneNo) {
            Bundle b = new Bundle();
            if(response != null)
                b.putString("JSONObject", response.toString());
            if(title != null)
                b.putString("Title", title);

            String propertyId = UConnectUtils.getPropertyId(mPref, getString(R.string.property_id));
            b.putString(UConnectUtils.PROPERTY_ID_KEY, propertyId);

            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction ft = fragmentManager.beginTransaction();
            Fragment fragment = null;

            if (whichView.equals(ConstantsManager.GRIDVIEWPAGER)) {
//              getSupportFragmentManager().popBackStack();
                fragment = new HomeFragment();
            } else if (whichView.equals(ConstantsManager.WEATHER)) {
                fragment = new WeatherFragmentPhone();
            }else if (whichView.equals(ConstantsManager.ALARM)) {
                fragment = new AlarmFragmentPhone();
            }else if (whichView.equals(ConstantsManager.MAPS)) {
                fragment = new MapPhone();
            }else if (whichView.equals(ConstantsManager.HELP)) {
            fragment = new InfoFragPhone();
            }

            if (whichView.equals(ConstantsManager.MAPS)) { // to show plus-icon on map top right corner
                HomeFragment.getInstance().onGridViewVisibilityChanged(true);
                HomeFragmentTab.getInstance().onFragmentTabChange(View.VISIBLE , title, "", View.VISIBLE);
            } else if (!whichView.equals(ConstantsManager.GRIDVIEWPAGER)) {
                HomeFragment.getInstance().onGridViewVisibilityChanged(true);
                HomeFragmentTab.getInstance().onFragmentTabChange(View.VISIBLE , title, mPhoneNo, View.GONE);
            } 

            fragment.setArguments(b);
            ft.add(R.id.main_home_frag, fragment);
            if (whichView.equals(ConstantsManager.GRIDVIEWPAGER)) {
                fragmentManager.popBackStack();
            } else {
                ft.addToBackStack(fragment.toString());
            }
            ft.commit();

        }

    @Override
    public void onPageScrollStateChanged(int arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onPageSelected(int arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabChanged(String tabId) {
        // TODO Auto-generated method stub

    }

}

and my HomeFragmentTab.java is

package com.bbgusa.bbgdemo.ui.home.phone;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.bbgusa.bbgdemo.R;
import com.bbgusa.bbgdemo.ui.phone.MainActivity;
import com.bbgusa.bbgdemo.ui.tablet.ConstantsManager;
import com.bbgusa.bbgdemo.ui.tablet.OnFragmentTabChangedListener;

@SuppressLint("NewApi")
public class HomeFragmentTab extends Fragment implements OnFragmentTabChangedListener{
    private static final String TAG = HomeFragmentTab.class.getSimpleName();
    private static HomeFragmentTab tab;
    private MainActivity activityPhone;

    public static HomeFragmentTab getInstance() {
        return tab;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        activityPhone = (MainActivity) activity;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v;
        if (container == null) {
            return null;
        }
        Log.i(TAG, "onCreateView");


        v = inflater.inflate(R.layout.hometab_phone, container, false);

        tab = this;

        activityPhone.onFragmentChangePhone(null, ConstantsManager.GRIDVIEWPAGER, getResources().getString(R.string.app_name), "");


        return v;
    }

    @Override
    public void onFragmentTabChange(int i, String title, String mPhoneNo, int mapV) {

    }

}

and HomeFragment.java is

package com.bbgusa.bbgdemo.ui.home.phone;

import java.util.Locale;

import org.json.JSONArray;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.bbgusa.bbgdemo.R;
import com.bbgusa.bbgdemo.ui.ImageCacheManager;
import com.bbgusa.bbgdemo.ui.cms.tablet.TestTopics;
import com.bbgusa.bbgdemo.ui.cms.tablet.TopicList;
import com.bbgusa.bbgdemo.ui.phone.MainActivity;
import com.bbgusa.bbgdemo.ui.tablet.onGridViewVisibilityChangedListener;
import com.bbgusa.bbgdemo.utils.common.UCConstants;
import com.bbgusa.bbgdemo.utils.common.UConnectUtils;
import com.viewpagerindicator.IconPageIndicator;
import com.viewpagerindicator.IconPagerAdapter;
import com.viewpagerindicator.PageIndicator;

public class HomeFragment extends Fragment implements onGridViewVisibilityChangedListener{

    private static final String TAG = HomeFragment.class.getSimpleName();
    private ViewPager mViewPager;
    private MainActivity activity;
    private PageIndicator mIndicator;
    private Animation mRotateAnim;
    private Dialog indiacatorDialog;
    private LinearLayout homeFragmentLL;
    private static HomeFragment homeFragment;

    public static final HomeFragment getInstance() {
        return homeFragment;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        this.activity = (MainActivity) activity;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "onCreate");
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        if (container == null) {
            return null;
        }

        View v = inflater.inflate(R.layout.home_phone, container, false);
        homeFragment = this;

        UConnectUtils.setLauncher(true);
        mViewPager = (ViewPager) v.findViewById(R.id.viewpager);
        mIndicator = (IconPageIndicator) v.findViewById(R.id.indicator);
        homeFragmentLL = (LinearLayout) v.findViewById(R.id.homeFragment);

        indiacatorDialog = new Dialog(getActivity());
        indiacatorDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        indiacatorDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        indiacatorDialog.setContentView(R.layout.indicator_dialog);
        indiacatorDialog.setCanceledOnTouchOutside(false);

        Window window = indiacatorDialog.getWindow();
        window.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

        mRotateAnim = AnimationUtils.loadAnimation(getActivity(), R.anim.rotate_and_scale);
        UConnectUtils.addAnimationFrameCount(mRotateAnim);
        indicatorAnim();


         // for property id
//      if (activity.isInterNetAvailable()) {
        Log.i(TAG, "onCreateView========== isInterNetAvailable");
        new CmsPropertyAsync(activity).execute(UCConstants.CMS_CONFIG_URL, UCConstants.CMS_CONFIG_KEY);
//      }
        return v;
    }

    protected void parseJson(JSONObject rootResponce) {
        TestTopics.imageUrls.clear();
        TestTopics.titles.clear();
        TestTopics.mMainMenuID.clear();
        TestTopics.mViewType.clear();
        TestTopics.mPhoneNo.clear();
        try {
            //get the Version
            String version = rootResponce.optString("VERSION");

            SharedPreferences mPref;
            SharedPreferences.Editor edit;

            mPref = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
            edit = mPref.edit();
            edit.putString(getResources().getString(R.string.pref_cms_version_key), version).commit();

            JSONArray jsonArray = rootResponce.getJSONArray("MAINMENU");
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject childMenuObject = jsonArray.getJSONObject(i);
                int mainMenuID = childMenuObject.optInt("mainMenuId");
                String title = childMenuObject.optString("title");
                String viewType = childMenuObject.optString("viewType");
                String imageUrl = childMenuObject.optString("imageUrl");
                String phoneNo = childMenuObject.optString("phoneNo");

                TestTopics.mMainMenuID.add(mainMenuID);
                TestTopics.imageUrls.add(imageUrl);
                TestTopics.titles.add(title);
                TestTopics.mViewType.add(viewType);
                TestTopics.mPhoneNo.add(phoneNo);
            }

            // Create a TopicList for this demo. Save it as the shared instance
            // in
            // TopicList
            String sampleText = getResources().getString(R.string.sample_topic_text);
            TopicList tlist = new TopicList(sampleText);
            TopicList.setInstance(tlist);

            // Create an adapter object that creates the fragments that we need
            // to display the images and titles of all the topics.

            MyAdapter mAdapter = new MyAdapter(getActivity().getSupportFragmentManager(), tlist, getResources());
//          mViewPager.removeAllViews();
            mViewPager.setAdapter(mAdapter);
            //  mViewPager.setPageTransformer(true, new DepthPageTransformer());
            mIndicator.setViewPager(mViewPager);
            mIndicator.setCurrentItem(0);
            mIndicator.notifyDataSetChanged();

            ViewTreeObserver observer = mViewPager.getViewTreeObserver();
            observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

                @SuppressLint("NewApi")
                @SuppressWarnings("deprecation")
                @Override
                public void onGlobalLayout() {
                   mViewPager.bringChildToFront(mViewPager.getChildAt(0));

                    if(Build.VERSION.SDK_INT >= UCConstants.ICE_CREAM_SANDWICH_MR1){
                        mViewPager.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    }else{
                        mViewPager.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }
                }
            });

            /*Fragment f = new GridViewFragment();
            FragmentTransaction t = getFragmentManager().beginTransaction();
            t.replace(R.id.main_home_frag, f);
            t.commit();*/

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Adapter class
     * 
     * This adapter class sets up GridFragment objects to be displayed by a
     * ViewPager.
     */

    public static class MyAdapter extends FragmentStatePagerAdapter implements IconPagerAdapter {

        private TopicList mTopicList;
        private int mNumItems = 0;
        private int mNumFragments = 0;

        /**
         * Return a new adapter.
         */

        public MyAdapter(FragmentManager fm, TopicList db, Resources res) {
            super(fm);
            setup(db, res);
        }

        /**
         * Get the number of fragments to be displayed in the ViewPager.
         */

        @Override
        public int getCount() {
            Log.i(TAG, "getCount : mNumFragments = "+mNumFragments);
            return mNumFragments;
        }

        /**
         * Return a new GridFragment that is used to display n items at the
         * position given.
         * 
         * @param position
         *            int - the position of the fragement; 0..numFragments-1
         */

        @Override
        public Fragment getItem(int position) {
            // Create a new Fragment and supply the fragment number, image
            // position, and image count as arguments.
            // (This was how arguments were handled in the original pager
            // example.)
            Bundle args = new Bundle();
            args.putInt("num", position + 1);
            args.putInt("firstImage", position * mNumItems);

            // The last page might not have the full number of items.
            int imageCount = mNumItems;
            if (position == (mNumFragments - 1)) {
                int numTopics = mTopicList.getNumTopics();
                int rem = numTopics % mNumItems;
                if (rem > 0)
                    imageCount = rem;
            }
            args.putInt("imageCount", imageCount);
            args.putSerializable("topicList", TopicList.getInstance());

            // Return a new GridFragment object.
            Log.i(TAG, "created fragmenat number:==== "+position+" "+1);
            GridViewFragmentPhone f = new GridViewFragmentPhone();
            f.setArguments(args);
            Log.i(TAG, "getItem : imageCount = "+imageCount);

            return f;
        }

        /**
         * Set up the adapter using information from a TopicList and resources
         * object. When this method completes, all the instance variables of the
         * adapter are valid;
         * 
         * @param tlist
         *            TopicList
         * @param res
         *            Resources
         * @return void
         */

        void setup(TopicList tlist, Resources res) {
            mTopicList = tlist;

            if ((tlist == null) || (res == null)) {
                mNumItems = 2;//DEFAULT_NUM_ITEMS;
                mNumFragments = 2;//DEFAULT_NUM_FRAGMENTS;
            } else {
                int numTopics = tlist.getNumTopics();
                int numRowsGV = res.getInteger(R.integer.num_of_rows_gridview);
                int numColsGV = res.getInteger(R.integer.num_of_cols_gridview);
                int numTopicsPerPage = numRowsGV * numColsGV;
                int numFragments = numTopics / numTopicsPerPage;
                if (numTopics % numTopicsPerPage != 0)
                    numFragments++; // Add one if there is a partial page

                mNumFragments = numFragments;
                mNumItems = numTopicsPerPage;
            }
        } // end setup

        @Override
        public int getIconResId(int index) {
             int[] ICON = new int[mNumFragments];

            for (int i = 0; i < mNumFragments; i++) {
                ICON[i] = R.drawable.slidericon;
            }
             return ICON[index % ICON.length];
        }
    } // end class MyAdapter


    @Override
    public void onGridViewVisibilityChanged(boolean hide) {
        if(hide){
            homeFragmentLL.setVisibility(View.GONE);
        }else {
            homeFragmentLL.setVisibility(View.VISIBLE);
        }

    }


    @Override
    public void onDetach() {
        super.onDetach();
        activity = null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    private class CmsPropertyAsync extends AsyncTask<String, Void, String> {

        MainActivity context;

        CmsPropertyAsync(MainActivity activityTab) {
            context = activityTab;
        }

        @Override
        protected String doInBackground(String... params) {
            String propertyId = UConnectUtils.getPropertyId(PreferenceManager.getDefaultSharedPreferences(context),getResources().getString(R.string.property_id));
            if(propertyId != null && propertyId.length() > 0){
                return propertyId;
            }
            return UConnectUtils.requestPropertyId(params[0], params[1]);
        }

        @Override
        protected void onPostExecute(String propertyId) {
            if(propertyId == null){
                indiacatorDialog.dismiss();
                showPropertyIdTimeoutAlert(getActivity());
                return;
            }

            SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
            editor.putString(getString(R.string.property_id),propertyId).commit();

            String url = null;
            String locale = Locale.getDefault().getLanguage();
            url = UCConstants.CMS_BASE_URL+"mainMenu?propertyId="+propertyId+"&lang="+locale;
            JsonObjectRequest jsObjRequest = new JsonObjectRequest(
            Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    parseJson(response);
                    indiacatorDialog.dismiss();
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    if (activity != null) {
//                      activity.getConnection(error);
                    }
                    indiacatorDialog.dismiss();
                }
            });
            ImageCacheManager.getInstance().getQueueForMainmenu().add(jsObjRequest);
        }
    }

    private void indicatorAnim() {
        if (indiacatorDialog != null) {
            ImageView alertIndicator = (ImageView) indiacatorDialog.findViewById(R.id.alert_indicator);
            alertIndicator.startAnimation(mRotateAnim);
            if (!getActivity().isFinishing()) {
                indiacatorDialog.show();
            }
        }
    }

    //  Show alert for Time out
     private void showPropertyIdTimeoutAlert(final Activity context) {

        AlertDialog.Builder alertDialog = new AlertDialog.Builder(context);
        alertDialog.setIcon(R.drawable.alert_dialog_icon);
        alertDialog.setTitle(context.getString(R.string.timeout_msg));
        alertDialog.setMessage(context.getString(R.string.timeout_msg2));
        alertDialog.setPositiveButton("OK",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        indicatorAnim();
                        //  for property id
                        new CmsPropertyAsync(activity).execute(UCConstants.CMS_CONFIG_URL, UCConstants.CMS_CONFIG_KEY);
                    }
            });

         alertDialog.setNegativeButton("Cancel", new OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                getActivity().finish();
            }
         });
         AlertDialog alert = alertDialog.create();
         alert.setCancelable(false);
         alert.setCanceledOnTouchOutside(false);
         if (context != null && !context.isFinishing()) {
             alert.show();
         }
     }
}

Solution

  • Actually, some data is being saved with onSavedInstaceState(). The data is not being deleted when process has been killed on LowMemory.

    I fixed this with

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        //super.onSaveInstanceState(outState);
    }
    

    Just do not call super class. Just comment like above