That's one way, but you should really avoid doing so. Flush the uncompressed data into a buffer, use gpu_pal_apply and use DMA to transfer the data to VRAM during a vblank. That's all you need to do. If you want examples, check how FireRed does the PC box's BG graphics.
No, I mean wait for the vblank before drawing to the BG. If you use gpu_pal_apply, it should write during the next vblank too. This idea of writing during vblanks is called vsyncing.
Also Jiang, I appreciate you trying to learn and stuff, but can you ask your questions in help threads? I'd like for other people who may have similar questions to you be able to see my answers to these questions. Often times I've answered your questions privately with someone else. It'd help to spread the knowledge
I'm not 100% sure about that example with rand actually.
I know you'd need to define the function header for "rand" inorder to be able to even use it as a parameter, but in general adding +1 in BPRE.ld should not affect functionality (I'm not 100% sure, just pretty sure).