I am making a puzzle game and every time the user completes the puzzle, a recreate button appears which is simply calling the recreate() method to restart the puzzle activity.
I override onSaveInstanceState because i want to save the image selected for the puzzle and the 4 pieces in case of screen orientation change.
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("originalBM", originalBm);
outState.putParcelable("bm1", bm1);
outState.putParcelable("bm2", bm2);
outState.putParcelable("bm3", bm3);
outState.putParcelable("bm4", bm4);
}
So, when the user clicks the recreate button, the recreate() method is being called which also calls onSaveInstanceState by default because this is how android works and the user will have to play the puzzle with the same image again and again.
I don't want to implement the same code that i have on my onCreate method to select a new random image because this is causing memory leaks and my app crashes after 10-12 recreates.
I simply want it to restart the activity clean and fresh!
Instead of using recreate() inside my recreatePuzzle method, I also also tried this
Intent intent = getIntent();
finish();
startActivity(intent);
But this again is causing my app to crash after 10-12 recreates. It is also causing memory leaks.
So, i believe the best way to do this would be by skipping the Override of saveInstanceState when my recreatePuzzle is being called (if this is possible) or by passing a null Bundle when onSaveInstanceState is being called.
Is there any way to implement any of these solutions above?
Any help would be highly appreciated.
Thank you all in advance.
EDIT:
Full code of my class
package kidsbook.jok.kidsbook;
public class Puzzle extends AppCompatActivity {
private String[] puzzleIMGS;
private String randomPuzzleIMG;
private int corrects = 0, tries = 0;
private ImageView part1, part2, part3, part4;
private TextView piece1, piece2, piece3, piece4;
private Button againButton;
private Bitmap bm1, bm2, bm3, bm4, originalBm;
private Intent i;
private MediaPlayer mp = new MediaPlayer();
private List<Bitmap> parts = new ArrayList<>();
private boolean recreatePuzzle = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_puzzle);
mp = MediaPlayer.create(getApplicationContext(), R.raw.pop);
//Select random image
puzzleIMGS = getResources().getStringArray(R.array.all_animal_imgs);
randomPuzzleIMG = puzzleIMGS[new Random().nextInt(puzzleIMGS.length)];
//Get all elements
againButton = (Button) findViewById(R.id.againPuzzleButton);
part1 = (ImageView) findViewById(R.id.part1);
part2 = (ImageView) findViewById(R.id.part2);
part3 = (ImageView) findViewById(R.id.part3);
part4 = (ImageView) findViewById(R.id.part4);
piece1 = (TextView) findViewById(R.id.piece1);
piece2 = (TextView) findViewById(R.id.piece2);
piece3 = (TextView) findViewById(R.id.piece3);
piece4 = (TextView) findViewById(R.id.piece4);
part1.setOnTouchListener(new MyTouchListener());
part2.setOnTouchListener(new MyTouchListener());
part3.setOnTouchListener(new MyTouchListener());
part4.setOnTouchListener(new MyTouchListener());
piece1.setOnDragListener(new MyDragListener());
piece2.setOnDragListener(new MyDragListener());
piece3.setOnDragListener(new MyDragListener());
piece4.setOnDragListener(new MyDragListener());
if(savedInstanceState!=null) {
Log.i("debug","inside saved instance");
//Convert randomly selected resource image to bitmap
originalBm = savedInstanceState.getParcelable("originalBM");
bm1 = savedInstanceState.getParcelable("bm1");
bm2 = savedInstanceState.getParcelable("bm2");
bm3 = savedInstanceState.getParcelable("bm3");
bm4 = savedInstanceState.getParcelable("bm4");
} else {
Log.i("debug","inside null instance");
//Convert randomly selected resource image to bitmap
originalBm = BitmapFactory.decodeResource(getResources(), getImageId(this, randomPuzzleIMG));
//Split bitmap to 4 parts
bm1 = Bitmap.createBitmap(originalBm, 0, 0, (originalBm.getWidth() / 2), (originalBm.getHeight() / 2));
bm2 = Bitmap.createBitmap(originalBm, (originalBm.getWidth() / 2), 0, (originalBm.getWidth() / 2), (originalBm.getHeight() / 2));
bm3 = Bitmap.createBitmap(originalBm, 0, (originalBm.getHeight() / 2), (originalBm.getWidth() / 2), (originalBm.getHeight() / 2));
bm4 = Bitmap.createBitmap(originalBm, (originalBm.getWidth() / 2), (originalBm.getHeight() / 2), (originalBm.getWidth() / 2), (originalBm.getHeight() / 2));
}
//Make the background transparent
piece1.setBackgroundDrawable(new BitmapDrawable(getResources(), bm1));
piece1.setAlpha(0.2f);
piece2.setBackgroundDrawable(new BitmapDrawable(getResources(), bm2));
piece2.setAlpha(0.2f);
piece3.setBackgroundDrawable(new BitmapDrawable(getResources(), bm3));
piece3.setAlpha(0.2f);
piece4.setBackgroundDrawable(new BitmapDrawable(getResources(), bm4));
piece4.setAlpha(0.2f);
//Place parts in an array
parts.add(bm1);
parts.add(bm2);
parts.add(bm3);
parts.add(bm4);
//Shuffle the array
Collections.shuffle(parts);
//Assign the correct piece tag to each part
for(int i=0;i<4;i++){
if(i==1) {
part1.setImageBitmap(parts.get(i));
if (parts.get(i).equals(bm1)){
part1.setTag("piece1");
} else if (parts.get(i).equals(bm2)){
part1.setTag("piece2");
} else if (parts.get(i).equals(bm3)){
part1.setTag("piece3");
} else {
part1.setTag("piece4");
}
} else if(i==2){
part2.setImageBitmap(parts.get(i));
if (parts.get(i).equals(bm1)){
part2.setTag("piece1");
} else if (parts.get(i).equals(bm2)){
part2.setTag("piece2");
} else if (parts.get(i).equals(bm3)){
part2.setTag("piece3");
} else {
part2.setTag("piece4");
}
} else if(i==3){
part3.setImageBitmap(parts.get(i));
if (parts.get(i).equals(bm1)){
part3.setTag("piece1");
} else if (parts.get(i).equals(bm2)){
part3.setTag("piece2");
} else if (parts.get(i).equals(bm3)){
part3.setTag("piece3");
} else {
part3.setTag("piece4");
}
} else {
part4.setImageBitmap(parts.get(i));
if (parts.get(i).equals(bm1)){
part4.setTag("piece1");
} else if (parts.get(i).equals(bm2)){
part4.setTag("piece2");
} else if (parts.get(i).equals(bm3)){
part4.setTag("piece3");
} else {
part4.setTag("piece4");
}
}
}
}
private static int getImageId(Context context, String imageName) {
return context.getResources().getIdentifier("drawable/" + imageName, null, context.getPackageName());
}
private final class MyTouchListener implements View.OnTouchListener {
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
ClipData data = ClipData.newPlainText("", "");
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(data, shadowBuilder, view, 0);
return true;
} else {
return false;
}
}
}
class MyDragListener implements View.OnDragListener {
@Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (action) {
case DragEvent.ACTION_DRAG_STARTED:
// do nothing
break;
case DragEvent.ACTION_DRAG_ENTERED:
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DROP:
// Dropped, reassign View to ViewGroup
View view = (View) event.getLocalState();
ViewGroup owner = (ViewGroup) view.getParent();
if(view.getTag().equals(v.getTag())){
if(view.getTag().equals("piece1")){
owner.removeView(view);
useMediaPlayer();
piece1.setBackgroundDrawable(new BitmapDrawable(getResources(), bm1));
piece1.setAlpha(0.9f);
corrects++;
} else if (view.getTag().equals("piece2")){
owner.removeView(view);
useMediaPlayer();
piece2.setBackgroundDrawable(new BitmapDrawable(getResources(), bm2));
piece2.setAlpha(0.9f);
corrects++;
} else if (view.getTag().equals("piece3")){
owner.removeView(view);
useMediaPlayer();
piece3.setBackgroundDrawable(new BitmapDrawable(getResources(), bm3));
piece3.setAlpha(0.9f);
corrects++;
} else if (view.getTag().equals("piece4")) {
owner.removeView(view);
useMediaPlayer();
piece4.setBackgroundDrawable(new BitmapDrawable(getResources(), bm4));
piece4.setAlpha(0.9f);
corrects++;
}
}
tries++;
if(corrects==4){
finish();
}
break;
case DragEvent.ACTION_DRAG_ENDED:
break;
default:
break;
}
return true;
}
}
public void useMediaPlayer(){
mp.start();
}
public void againPuzzle(View v){
recreatePuzzle = true;
recreate();
}
public void finish(){
againButton.setVisibility(View.VISIBLE);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("originalBM", originalBm);
outState.putParcelable("bm1", bm1);
outState.putParcelable("bm2", bm2);
outState.putParcelable("bm3", bm3);
outState.putParcelable("bm4", bm4);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_games, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case android.R.id.home:
i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
return true;
case R.id.menu_about:
i = new Intent(this, About.class);
startActivity(i);
return true;
case R.id.menu_help:
i = new Intent(this, Help.class);
startActivity(i);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onBackPressed() {
i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}