Audio and video development series (26) drawing pictures in three ways - android Development

In android development, the most commonly used way to draw pictures is ImageView and set src. So is there any other scheme to draw pictures?

Three schemes

  1. Set setImageBitmap through Imageview

 final String path = Environment.getExternalStorageDirectory().getPath() + File.separator + "Pictures" + File.separator + "tmp.jpg";

        Bitmap bitmap = BitmapFactory.decodeFile(path);
  1. Define Paint and read Bitmap through custom View, and then use Canvas to draw Bitmap in onDraw

public class CustomView extends View {
    private Paint paint;
    private Bitmap bitmap;

    public CustomView(Context context) {

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint = new Paint();
    String path = Environment.getExternalStorageDirectory().getPath() + File.separator + "Pictures" + File.separator + "tmp.jpg";

        bitmap = BitmapFactory.decodeFile(path);

    protected void onDraw(Canvas canvas) {
        if(bitmap!=null&&!bitmap.isRecycled()) {
            canvas.drawBitmap(bitmap, 0, 0, paint);
  1. Through the surfaceview and the SufaceHolder of the surfaceview, get it to the canvas and draw it.

surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            public void surfaceCreated(SurfaceHolder holder) {
                if(holder == null){
                Paint paint = new Paint();
//                                paint.setStyle(Paint.Style.STROKE);

       String path = Environment.getExternalStorageDirectory().getPath() + File.separator + "Pictures" + File.separator + "tmp.jpg";

                Bitmap bitmap1 = BitmapFactory.decodeFile(path);

                Canvas canvas = null;
                try {
                    canvas = holder.lockCanvas();
                }catch (Exception e){
                } finally {


                Log.d(TAG, "surfaceCreated: ");

            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                Log.d(TAG, "surfaceChanged: format"+format+" w="+width+" h="+height);


            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.d(TAG, "surfaceDestroyed: ");


Comparison between SurfaceView and View and usage scenarios

Through the above example, we can see the difference between the use of SurfaceView and view. View can be drawn directly through the API encapsulated by ImageView or Canvas obtained from onDraw of view. The SurfaceView is drawn through the Canvas through the SurfaceHolder.
Let's talk about the difference between SurfaceView and view

All views in a window share a window, corresponding to a surface (drawing surface). There is a Canvas in the surface, which can be used for drawing. In WMS, only the DecorView of the top Layer can be seen. In WMS, corresponding to WindowState, when app requests to refresh the surface, it will establish a corresponding Layer in the SurfaceFlinger.

Follow me + background private letter, get 2022 latest and complete learning improvement package + interview questions, including (C/C + +, Linux, FFmpeg, webRTC, rtmp, hls, rtsp, ffplay, srs)



  1. It can be drawn in the sub thread -- "is applicable to the passive and frequently refreshed interface, such as video playback or games

  2. Refresh only refreshes itself, not all viewHierchy in other views. To avoid causing the whole viewHierchy to refresh, the performance will be better.

  3. Double buffer mechanism to avoid flicker and improve performance.

  4. The animation of view is not valid for sureface
    Turn off the hardware acceleration of all view s in the window to make it opaque.

How to use:
And sureface Lockcavas obtains the canvas, performs the canvas operation, and then sureface Unlock cavasandpost to update the page.

Why is surfacetested called when the surfaceView is invisible and re create d when it is visible again?
Because the double buffering mechanism of surfaceview consumes a lot of memory, Android stipulates that when surfaceview is not visible, the SurfaceHolder of surfaceview will be destroyed to save system resources.

Acquisition of Android 10 + storage permission

When writing the demo, we will encounter trouble in obtaining the permission of external storage due to the use of reading a picture from external storage for drawing. google's acquisition of user permission is becoming more and more convergent, which is a good thing. The granting of permissions to users can be controlled by themselves, which makes a better guarantee for privacy and security. So how should developers get the storage permission of users? There are three steps to do

  1. Android mainfest is registered in the manifest file

  2. Application add android:requestLegacyExternalStorage="true"

  3. Dynamic acquisition through AppOpsManager


Through this chapter, we know that the root of drawing pictures is to get Canvas and draw bitmap on it.
You can use the API provided by ImageView; You can customize the View and draw the drawbitmap of canvas in the onDraw method; You can also use the SurfaceView to go through the lockCanvas of the surface when onSurfaceCreate, then draw the drawbitmap of the canvas, and finally draw in the unlockCanvasAndPost.

The biggest difference between surfaceview and View is that surfaceview has its own separate window and its own independent layer layer in the corresponding WMS. It can be drawn in the sub thread. The refresh will not affect other views in the View tree structure. It is suitable for scenes with passive frequent refresh. The corresponding disadvantage is that the View animation has no effect on the surfaceview, such as moving and zooming. The most obvious performance is that the page is transparent when the animation enters or slides out of the surfaceview page. But in fact, it is possible to turn off the hardware acceleration of View.
About the life cycle of SurfaceHolder of surfaceview, the surfaceview is destroyed when it is invisible and re created when it is visible. The reason is that the surfaceview adopts a double buffer mechanism to ensure that the refresh does not flicker. But double buffering consumes more memory than, so android does the above strategy.

The permissions of reading sd card content above Android 10 are converged by google. First, it is necessary to register in Android manifest, and then obtain it dynamically before use. It is also necessary to add it in the Application of Android manifest

Tags: C++ webrtc

Posted by smudge on Fri, 15 Apr 2022 15:21:24 +0930