title: Android: Android app crashing when trying to load saved Bitmap data to Canvas
body: <p>First of all thanks in advance for the help.
  My app is basically a sketchbook with multiple canvas. Here after drawing on first canvas and when I click on <strong>Next</strong> button new canvas is loaded and previous canvas is saved into an Bitmap array. After drawing on the new canvas that has been loaded, when I click on <strong>Prev</strong> button, the present drawing is saved in bitmap array and the new canvas should load the previously drawn image onto canvas. </p>
  
  <p>But instead of that when i click on <strong>Prev</strong> button the app is crashing.</p>
  
  <p>Please help me with this issue.</p>
  
  <p>Here is the code of both <strong>Next</strong> and <strong>Prev</strong> buttons.</p>
  
  <p><strong>Next</strong> Button</p>
  
  <pre><code>if(view.getId()==R.id.next){
          bitArrayStore(i);
          drawView.startNew();
          i++;
      }
  </code></pre>
  
  <p><strong>Prev</strong> Button</p>
  
  <pre><code>if(view.getId() == R.id.prev){
          bitArrayStore(i);
          drawView.startNew();
          i--;
          drawView.redraw(bits, i);
      }
  </code></pre>
  
  <p><strong>bitArrayStore()</strong></p>
  
  <pre><code> public void bitArrayStore(int k){
  
      drawView.buildDrawingCache();
      drawView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
      bits[k] = drawView.getDrawingCache();
      drawView.destroyDrawingCache();
  }
  </code></pre>
  
  <p><strong>drawView.redraw()</strong></p>
  
  <pre><code> public void redraw(Bitmap[] bits, int i) {
      drawCanvas.drawBitmap(bits[i], 0, 0, null);
      invalidate();
  }
  </code></pre>
  
  <p>Here is my logcat</p>
  
  <pre><code>10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime: FATAL EXCEPTION: main
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime: Process: com.example.jishnu.notestest, PID: 18856
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@c0446aa
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at android.graphics.Canvas.throwIfCannotDraw(Canvas.java:1282)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at android.graphics.Canvas.drawBitmap(Canvas.java:1337)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at com.example.jishnu.notestest.DrawingView.redraw(DrawingView.java:136)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at com.example.jishnu.notestest.MainActivity.onClick(MainActivity.java:245)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at android.view.View.performClick(View.java:4780)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at android.view.View$PerformClick.run(View.java:19866)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:135)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5254)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:372)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
  10-16 03:23:45.816 18856-18856/com.example.jishnu.notestest E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
  </code></pre>
  
  <p>Here is my rest of the code in case of reference</p>
  
  <p><strong>MainActivity.java</strong></p>
  
  <pre><code>public class MainActivity extends AppCompatActivity implements OnClickListener {
  
      private DrawingView drawView;
      private ImageButton currPaint,drawBtn,eraseBtn,newBtn,saveBtn;
      private float smallBrush, mediumBrush, largeBrush;
      String ucolor;
      private Button nextbtn,prevbtn;
      int i=0;
      Bitmap[] bits;
  
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
  
          drawView = (DrawingView) findViewById(R.id.drawing);
          LinearLayout paintLayout = (LinearLayout) findViewById(R.id.paint_colors);
          currPaint = (ImageButton) paintLayout.getChildAt(0);
          currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
          smallBrush = getResources().getInteger(R.integer.small_size);
          mediumBrush = getResources().getInteger(R.integer.medium_size);
          largeBrush = getResources().getInteger(R.integer.large_size);
          drawBtn = (ImageButton)findViewById(R.id.draw_btn);
          drawBtn.setOnClickListener(this);
          drawView.setBrushSize(mediumBrush);
          eraseBtn = (ImageButton)findViewById(R.id.erase_btn);
          eraseBtn.setOnClickListener(this);
          newBtn = (ImageButton)findViewById(R.id.new_btn);
          newBtn.setOnClickListener(this);
          saveBtn = (ImageButton)findViewById(R.id.save_btn);
          saveBtn.setOnClickListener(this);
  
          bits=new Bitmap[40];
          nextbtn=(Button)findViewById(R.id.next);
          prevbtn=(Button)findViewById(R.id.prev);
          nextbtn.setOnClickListener(this);
          prevbtn.setOnClickListener(this);
          drawView.setDrawingCacheEnabled(true);
  
      }
  
      public void paintClicked(View view) {
          //use chosen color
  
          drawView.setErase(false);
          drawView.setBrushSize(drawView.getLastBrushSize());
          if (view != currPaint) {
  
              ImageButton imgView = (ImageButton)view;
              String color = view.getTag().toString();
              drawView.setColor(color);
  
              imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
              currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
              currPaint=(ImageButton)view;
          }
      }
  
      @Override
      public void onClick(View view) {
          if(view.getId()==R.id.draw_btn){
              //draw button clicked
              final Dialog brushDialog = new Dialog(this);
              brushDialog.setTitle("Brush size:");
              brushDialog.setContentView(R.layout.brush_chooser);
              ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
              smallBtn.setOnClickListener(new OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      drawView.setBrushSize(smallBrush);
                      drawView.setLastBrushSize(smallBrush);
                      drawView.setErase(false);
  
                      brushDialog.dismiss();
                  }
              });
              ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
              mediumBtn.setOnClickListener(new OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      drawView.setBrushSize(mediumBrush);
                      drawView.setLastBrushSize(mediumBrush);
                      drawView.setErase(false);
  
                      brushDialog.dismiss();
                  }
              });
  
              ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
              largeBtn.setOnClickListener(new OnClickListener(){
                  @Override
                  public void onClick(View v) {
                      drawView.setBrushSize(largeBrush);
                      drawView.setLastBrushSize(largeBrush);
                      drawView.setErase(false);
  
                      brushDialog.dismiss();
                  }
              });
              brushDialog.show();
          }
          else if(view.getId()==R.id.erase_btn){
              //switch to erase - choose size
              final Dialog brushDialog = new Dialog(this);
              brushDialog.setTitle("Eraser size:");
              brushDialog.setContentView(R.layout.brush_chooser);
              ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
              smallBtn.setOnClickListener(new OnClickListener(){
                  @Override
                  public void onClick(View v) {
                      drawView.setErase(true);
                      drawView.setBrushSize(smallBrush);
                      brushDialog.dismiss();
                  }
              });
              ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
              mediumBtn.setOnClickListener(new OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      drawView.setErase(true);
                      drawView.setBrushSize(mediumBrush);
                      brushDialog.dismiss();
                  }
              });
              ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
              largeBtn.setOnClickListener(new OnClickListener() {
                  @Override
                  public void onClick(View v) {
                      drawView.setErase(true);
                      drawView.setBrushSize(largeBrush);
                      brushDialog.dismiss();
                  }
              });
              brushDialog.show();
          }
          else if(view.getId()==R.id.new_btn){
              //new button
              AlertDialog.Builder newDialog = new AlertDialog.Builder(this);
              newDialog.setTitle("New drawing");
              newDialog.setMessage("Start new drawing (you will lose the current drawing)?");
              newDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
                  public void onClick(DialogInterface dialog, int which){
                      drawView.startNew();
                      dialog.dismiss();
                  }
              });
              newDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
                  public void onClick(DialogInterface dialog, int which){
                      dialog.cancel();
                  }
              });
              newDialog.show();
          }
  
          else if(view.getId()==R.id.save_btn){
              //save drawing
              AlertDialog.Builder saveDialog = new AlertDialog.Builder(this);
              saveDialog.setTitle("Save drawing");
              saveDialog.setMessage("Save drawing to device Gallery?");
              saveDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
                  public void onClick(DialogInterface dialog, int which){
                      //save drawing
                      drawView.setDrawingCacheEnabled(true);
                      drawView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
                      Bitmap bitmap = drawView.getDrawingCache();
                      String path = Environment.getExternalStorageDirectory().getAbsolutePath();
                      File file = new File(path+File.separator+"Pictures"+File.separator+"image.png");
                      FileOutputStream ostream;
                      try {
                          file.createNewFile();
                          ostream = new FileOutputStream(file);
                          bitmap.compress(Bitmap.CompressFormat.PNG, 100, ostream);
                          ostream.flush();
                          ostream.close();
                          Toast.makeText(getApplicationContext(), "image saved :"+path, Toast.LENGTH_SHORT).show();
  
  
                      } catch (Exception e) {
                          e.printStackTrace();
                          Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_SHORT).show();
                      }
                      drawView.destroyDrawingCache();
                  }
              });
              saveDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
                  public void onClick(DialogInterface dialog, int which){
                      dialog.cancel();
                  }
              });
              saveDialog.show();
          }
  
          if(view.getId()==R.id.next){
              bitArrayStore(i);
              drawView.startNew();
              i++;
          }
          if(view.getId() == R.id.prev){
              bitArrayStore(i);
              drawView.startNew();
              i--;
              drawView.redraw(bits, i);
          }
  
      }
  
      public void bitArrayStore(int k){
  
          drawView.buildDrawingCache();
          drawView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
          bits[k] = drawView.getDrawingCache();
          drawView.destroyDrawingCache();
      }
  
  }
  </code></pre>
  
  <p><strong>DrawingView.java</strong></p>
  
  <pre><code>public class DrawingView extends View {
  
      //drawing path
      private Path drawPath;
      //drawing and canvas paint
      private Paint drawPaint, canvasPaint;
      //initial color
      private int paintColor = 0xFF660000;
      //canvas
      private Canvas drawCanvas;
      //canvas bitmap
      private Bitmap canvasBitmap;
      private float brushSize, lastBrushSize;
      private boolean erase=false;
  
      public DrawingView(Context context, AttributeSet attrs) {
          super(context, attrs);
          setupDrawing();
      }
  
      private void setupDrawing() {
  //get drawing area setup for interaction
          brushSize = getResources().getInteger(R.integer.medium_size);
          lastBrushSize = brushSize;
          drawPath = new Path();
          drawPaint = new Paint();
          drawPaint.setColor(paintColor);
          drawPaint.setAntiAlias(true);
          drawPaint.setStrokeWidth(brushSize);
          drawPaint.setStyle(Paint.Style.STROKE);
          drawPaint.setStrokeJoin(Paint.Join.ROUND);
          drawPaint.setStrokeCap(Paint.Cap.ROUND);
  
          canvasPaint = new Paint(Paint.DITHER_FLAG);
      }
  
      @Override
      protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  //view given size
          super.onSizeChanged(w, h, oldw, oldh);
          canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
          drawCanvas = new Canvas(canvasBitmap);
      }
  
      @Override
      protected void onDraw(Canvas canvas) {
  //draw view
          canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
          canvas.drawPath(drawPath, drawPaint);
      }
  
      @Override
      public boolean onTouchEvent(MotionEvent event) {
  //detect user touch
          float touchX = event.getX();
          float touchY = event.getY();
          switch (event.getAction()) {
              case MotionEvent.ACTION_DOWN:
                  drawPath.moveTo(touchX, touchY);
                  break;
              case MotionEvent.ACTION_MOVE:
                  drawPath.lineTo(touchX, touchY);
                  break;
              case MotionEvent.ACTION_UP:
                  drawCanvas.drawPath(drawPath, drawPaint);
                  drawPath.reset();
                  break;
              default:
                  return false;
          }
          invalidate();
          return true;
      }
  
      public void setColor(String newColor) {
  //set color
          invalidate();
          paintColor = Color.parseColor(newColor);
          drawPaint.setColor(paintColor);
      }
  
      public void setBrushSize(float newSize) {
  //update sizefloat pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
          float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                  newSize, getResources().getDisplayMetrics());
          brushSize = pixelAmount;
          drawPaint.setStrokeWidth(brushSize);
      }
      public void setLastBrushSize(float lastSize){
          lastBrushSize=lastSize;
      }
      public float getLastBrushSize(){
          return lastBrushSize;
      }
  
      public void setErase(boolean isErase){
  //set erase true or false
          erase=isErase;
          if(erase) drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
          else drawPaint.setXfermode(null);
      }
  
      public void startNew(){
          drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
          invalidate();
  
  
  //        Bitmap b= BitmapFactory.decodeFile("/storage/emulated/0/Pictures/image.png");
  //        drawCanvas.drawBitmap(b, 0, 0, null);
  //
  //        invalidate();
  
      }
  
  
      public void redraw(Bitmap[] bits, int i) {
          drawCanvas.drawBitmap(bits[i], 0, 0, null);
          invalidate();
      }
  }
  </code></pre>
  
  <p>Problem is when i click on <strong>Prev</strong> button the app is crashing. Can anyone please help me with this issue ?!</p>