Do not allocate new objects in onDraw

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Paint paint = new Paint(); //Do not allocate here
}

Instead of drawing drawables in canvas…

drawable.setBounds(boundsRect);

drawable.draw(canvas);

Use a Bitmap for faster drawing:

canvas.drawBitmap(bitmap, srcRect, boundsRect, paint);

Do not redraw the entire view to update just a small part of it. Instead redraw the specific part of view.

invalidate(boundToBeRefreshed);

If your view is doing some continuous animation, for instance a watch-face showing each and every second, at least stop the animation at onStop() of the activity and start it back on onStart() of the activity.

Do not do any calculations inside the onDraw method of a view, you should instead finish drawing before calling invalidate(). By using this technique you can avoid frame dropping in your view.

Rotations

The basic operations of a view are translate, rotate, etc… Almost every developer has faced this problem when they use bitmap or gradients in their custom view. If the view is going to show a rotated view and the bitmap has to be rotated in that custom view, many of us will think that it will be expensive. Many think that rotating a bitmap is very expensive because in order to do that, you need to translate the bitmap’s pixel matrix. But the truth is that it is not that tough! Instead of rotating the bitmap, just rotate the canvas itself!

// Save the canvas state
int save = canvas.save();
// Rotate the canvas by providing the  center point as pivot and angle
canvas.rotate(pivotX, pivotY, angle);
// Draw whatever you want
// Basically whatever you draw here will be drawn as per the angle you rotated the canvas
canvas.drawBitmap(...);
// Now restore your your canvas to its original state
canvas.restore(save);
// Unless canvas is restored to its original state, further draw will also be rotated.