Keep GridView when resuming from sleep mode
Asked Answered
T

4

12

I got a problem with a quite large GridView.(about 70 children) The GridView works fine if I start it on onCreate or after resumeing after pressing the home button and then return. But when I resume after coming back from sleep mode, my BaseAdapter starts again and ruin the changes I have done to it during runtime. This also make getChildAt() give a NullPointerException if I am calling it just after restart.

How can I make it just do what regular onPause(home button) does to the GridView, and avoid that the GridView is wiped out everytime I am resumeing from sleep mode?

Edit: I have tried setting a wakelock for my Activity class that calls the BaseAdpter with no luck

2.Edit: Since I posted this question I have played around with trying to restore the GridView using this code in onPause:

 SparseArray<Parcelable> array = new SparseArray<Parcelable>();
    gridView.saveHierarchyState(array);
    bundle = new Bundle();
    bundle.putSparseParcelableArray("state", array);

And this in onResume:

 try{
    gridView.restoreHierarchyState(bundle.getSparseParcelableArray("state"));
    }
    catch(Exception e){
        //Most likely first start
        Log.i("SomeTag", "No GridView state found");
    }

    }

The strange thing is everything I seems to have jumped from one place to another on the screen and it is still crashing when I try to getChildAt(). It is also failing to get it after sleep mode.

  1. Edit Here is the code from BaseAdapter getView(Note! some of this code is irrelevant)

public View getView (int position, View convertView, ViewGroup parent) {

mParentView = parent;


DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;

    //sets the height for every individual box
int box = width/7*6/10;

ImageCell v = null;
if (convertView == null) {
    // If it's not recycled, create a new ImageCell.
    v = new ImageCell (mContext);
    v.setLayoutParams(new GridView.LayoutParams(box, box));
    v.setScaleType(ImageView.ScaleType.CENTER_CROP);
    v.setPadding(0, 0, 0, 0);


} else {
    v = (ImageCell) convertView;
}

v.mCellNumber = position;
v.mGrid = (GridView) mParentView;
v.mEmpty = true;
int id = 200;
v.setId(++id);

String map = str[position];
int pos = position;
int up = pos-10;
int down = pos+10;
int left = pos-1;
int right = pos+1;
if(up>=0){
above = str[up];
}
else{
    //Do nothing
}
if(down<70){
    under = str[down];
    }
else{
    //Do nothing
}
if(left<=-1){
   //Do nothing
}

else{
    lefte=str[left];
}
if(right>=70){
    //Do nothing
 }     
 else{
    righte=str[right];
 }
//if(left>-1|left!=9|left!=19|left!=29|left!=39|left!=49|left!=59){
   // lefte = str[left];
  //  }
 // else{
 //     Log.i("ImageCellAdapter", "Left is trying to break walls "+left);
    //Do nothing
  // }


if (map.equals("mountain")) {
    //Checks surroundings to find out witch drawable to set  
    v.setBackgroundResource(R.color.cell_empty);
     v.mEmpty = false;
     //All
     if(above=="mountain"&&under=="mountain"&&lefte=="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_full);
        }
     //Single
     else if(above=="mountain"&&under!="mountain"&&lefte!="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_down);
        }
     else if(above!="mountain"&&under=="mountain"&&lefte!="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_up);
        }
     else if(above!="mountain"&&under!="mountain"&&lefte!="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_left);
        }
     else if(above!="mountain"&&under!="mountain"&&lefte=="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_right);
        }
     //Double
     else if(above=="mountain"&&under!="mountain"&&lefte!="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_left_down);
        }
     else if(above!="mountain"&&under=="mountain"&&lefte!="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_left_up);
        }
     else if(above=="mountain"&&under!="mountain"&&lefte=="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_right_down);
        }
     else if(above!="mountain"&&under=="mountain"&&lefte=="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_up_right);
        }
     else if(above!="mountain"&&under!="mountain"&&lefte=="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_up_down);
        }
     else if(above=="mountain"&&under=="mountain"&&lefte!="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_up_down);
        }
     //Triple
     else if(above!="mountain"&&under=="mountain"&&lefte=="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_left_right_down);
        }
     else if(above=="mountain"&&under=="mountain"&&lefte=="mountain"&&righte!="mountain"){
            v.setImageResource(R.drawable.mountain_left_up_down);
        }
     else if(above=="mountain"&&under!="mountain"&&lefte=="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_left_up_right);
        }
     else if(above=="mountain"&&under=="mountain"&&lefte!="mountain"&&righte=="mountain"){
            v.setImageResource(R.drawable.mountain_up_right_down);
        }
     //None
        else{
    v.setImageResource(R.drawable.mountain);
        }

}
else if(map=="start"){
    List<String> posOf = Arrays.asList(str);
    startPos=posOf.indexOf("start");
    v.mEmpty=false;
    v.setBackgroundResource(R.color.cell_empty);
    getDur();

     BitmapDrawable first = (BitmapDrawable)mContext.getResources().getDrawable(R.drawable.gress);
     BitmapDrawable second =(BitmapDrawable)mContext.getResources().getDrawable(R.drawable.ic_launcher);
     BitmapDrawable third = (BitmapDrawable)mContext.getResources().getDrawable(R.drawable.gress);
     BitmapDrawable fourth = (BitmapDrawable)mContext.getResources().getDrawable(R.drawable.ic_launcher);

    final AnimationDrawable ani = new AnimationDrawable();       
       ani.addFrame(first, duration);
       ani.addFrame(second, duration);
       ani.addFrame(third, duration);
       ani.addFrame(fourth, duration);
       ani.setOneShot(true);
     v.setImageDrawable(ani);        
       checkIfAnimationDone(ani); 
    v.post(new Runnable() {   
        public void run() {
               ani.start();
                }
        });
}
else if(map=="stop"){
    v.mEmpty=false;
    v.setBackgroundResource(R.color.cell_empty);
    v.setImageResource(R.drawable.ic_launcher);
    v.setTag(1);
}
else if(map=="grass"){
    v.mEmpty=false;
    v.setBackgroundResource(R.drawable.gress);


}
else{
   //    v.setBackgroundResource (R.color.drop_target_enabled);
v.setBackgroundResource (R.color.cell_empty);
}
//v.mGrid.requestDisallowInterceptTouchEvent (true);

//v.setImageResource (R.drawable.hello);

// Set up to relay events to the activity.
// The activity decides which events trigger drag operations.
// Activities like the Android Launcher require a long click to get a drag operation started.


return v;

}

And defining the GridView in onCreate:

gridView= new BoxView(this);

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH){

              w.getDefaultDisplay().getSize(size);

              Measuredwidth = size.x;
              Measuredheight = size.y; 
            }else{
              Display d = w.getDefaultDisplay(); 
              Measuredwidth = d.getWidth(); 
              Measuredheight = d.getHeight(); 
            }
        int width = Measuredwidth/7*6;

    gridView.setLayoutParams(new GridView.LayoutParams(width,LayoutParams.FILL_PARENT, Gravity.CENTER_HORIZONTAL));
    gridView.setNumColumns(columns);
    gridView.setVerticalSpacing(0);
    gridView.setHorizontalSpacing(0);
    gridView.setPadding(0, 0, 0, 0);
    gridView.setId(101);
    gridView.setSelector(android.R.color.transparent);
    gridView.setAdapter (new ImageCellAdapter(this, MAP));
Task answered 26/11, 2012 at 17:38 Comment(7)
You don't want to keep the huge GridView around when your activity is destroyed, as this will lead to Out-of-Memory situations. How are you populating the view?Archivist
@Archivist I have to have it this big (I am makeing a GridView based game) and it has to be visible all the time and show all children at the same time. Using another View will set me back days.Task
I am asking: how are you populating the view when your Activity starts? From a database, a save file, whatever?Archivist
@Archivist I am populating it by a BaseAdapter. Each children has a Background resource and some an ImageResource. This is based on an array. I have had no trouble with running out of memory so far. (I use drawables that only uses a couple of bytes each)Task
Oh, the size of the view isn't a problem; it's keeping the view around after the Activity is destroyed that is a problem. It sounds to me like you need to read up on the Activity lifecycle and handle saving the state of your game in the onPause method, then populate the gridView in your onResume/onRestoreInstanceState method. I can write up a real answer with more detail if you wish.Archivist
@Archivist That would be awsome! I have been stuck with these problem for a week. If you make a working example I would sertanly approve it and give it +1Task
a volatile GridView in a volatile world xDSuitable
Y
2

Try using this tag:

android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
Yeager answered 19/12, 2012 at 9:52 Comment(1)
Adding screen-size to the other answers solved my problem! Thank you so much and make good use of the bounty ;)Task
T
4

I have noticed one thing in you code:

gridView.setLayoutParams(new GridView.LayoutParams(width,LayoutParams.FILL_PARENT, Gravity.CENTER_HORIZONTAL));

Even if GridView is a ViewGroup, you can't access it's LayoutParams. Just think it trough, if this would be possible that means you could put a GridView inside another GridView.

Fix this before going further because is messing with you.

If you want your GridView to be inside a LinearLayout, for example, try this:

gridView.setLayoutParams(new LinearLayout.LayoutParams(width,LayoutParams.FILL_PARENT, Gravity.CENTER_HORIZONTAL));

Here is the correct implementation of this answer:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /*You have to implement what things from the gridView sould be "saved"*/
        GridView gridView = new GridView(this) {

            @Override
            public Parcelable onSaveInstanceState() {
                // Create the Parceable object with the things you want to save
                                Parceable stateOfGrid = ....etc
                return stateOfGrid;
            }

                        @Override
            public void onRestoreInstanceState(Parcelable state) {
                // Restore your grid's parameters that you previously implemented in onSaveInstanceState
                super.onRestoreInstanceState(state);
                                ...
            }

        };

    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onRestoreInstanceState(savedInstanceState);

                if (savedInstanceState != null) {
                    Parcelable state = savedInstanceState.getParcelable("state");
                    if (state != null) {
                        gridView.onRestoreInstanceState(state);
                        Log.d(this.getClass().getName(), "state restored!");                
                    }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // Put your grid's Parceable into the bundle
        super.onSaveInstanceState(outState);
                Parcelable state = gridView.onSaveInstanceState();
                outState.putParcelable("state", state);
    }


}
Teeming answered 5/12, 2012 at 18:46 Comment(4)
Thanks a lot! I have never thought of that. I replaced it with a RelativeLayout instead of LinearLayout, but I now do not generate a GridView inside another.Task
The problem with that is that if you get 2 upvotes you get the bounty. I am quite low on reputation right now, and this has for now not made any difference. I give you +1 when the bounty is ended :)Task
I already know how to use the save and restore instance methods. What I need to know is what to save and how to restore it afterwards.Task
+1 for finding and error that I was not aware of. But the answer did not solve my problem, and therefore you do not get the bounty...this time ;)Task
Y
2

Try using this tag:

android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
Yeager answered 19/12, 2012 at 9:52 Comment(1)
Adding screen-size to the other answers solved my problem! Thank you so much and make good use of the bounty ;)Task
S
1

You can use onSaveInstanceState (Bundle outState) to save state of your gridview

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Parcelable state = gridView.onSaveInstanceState();
    outState.putParcelable("state", state);
}

then in onCreate after you seted adapter to grdiview add this code

if (savedInstanceState != null) {
  Parcelable state = savedInstanceState.getParcelable("state");
  if (state != null) {
    gridView.onRestoreInstanceState(state);
    Log.d(this.getClass().getName(), "state restored!");                
  }
}
Sidonnie answered 3/12, 2012 at 18:59 Comment(2)
@Task does this help? #3470447Necromancy
@Necromancy Done! Please tell me if I have to post LogCat or any more codeTask
E
0

Is your application running in Landscape Mode?

if yes, then you should consider adding the tag

"android:configChanges="keyboard|keyboardHidden|orientation" for your activity in Manifest.xml, which will prevent android system from killing your activity and restarting it when you unlock the screen.

Essentialism answered 18/12, 2012 at 7:38 Comment(1)
No good. It works for WebView(I have used this code for WebView before) but not on my GridView.Task

© 2022 - 2024 — McMap. All rights reserved.