Android Native drawing method

Most  Android  application programs, should all do all the work with Java Code, including drawings. However, in some cases, you'll want to plot a faster reaction; for example game, then native code may be an option.

In  Android  on, there is a  Graphic  Engine, called Skia. Skia function is approximately equal to Cairo, functionally similar, but did not support Skia Cairo wide. In fact,  Android  's Java Code Skia are carried out through drawing, while Skia major class type is SkCanvas, the graphics are all in the construction of this class. So, if we can get the code Native  Android  SkCanvas established, can be used directly on the screen do Skia output.

In  Android  the UI design where every UI component is a view; for example: button, label and so on, all view. When  Android  To draw a view, calls the view of onDraw () to draw the appearance of the component. And Android  will be a android.graphics.Canvas type of objects as parameters to onDraw (). the onDraw () outputs appearance of this component in the canvas, for example, a draw button. The canvas fact mapped to a SkCanvas, as long as we paint on this canvas, painting is equivalent to an area on the screen.

 

Native code

Android  is calling through the JNI native code, so we define a View in the Java side, so that the canvas View transmits through the JNI to our native code, so native code in the drawing.

 

001	package com.example;
002	import android.view.View;
003	import android.graphics.Canvas;
004	
005	class myview extends View {
006	    public void onDraw(Canvas canvas) {
007	        nativedraw(canvas);
008	    }
009	    native void nativedraw(Canvas canvas);
010	    static {
011	        System.loadLibrary("mynative");
012	    }
013	}

In this class one, we will canvas pass through JNI native code, then we define the JNI native function.

001	#include <SkCanvas.h>
002	
003	extern "C" {
004	
005	#include <jni.h>
006	
007	void
008	Java_com_example_myview_nativedraw(JNIEnv *env, jobject thiz, jobject obj) {
009	    jclass cls;
010	    jfieldID fid;
011	    SkCanvas *canvas;
012	    
013	    cls = env->GetObjectClass(obj);
014	    fid = env->GetFieldID(cls, "mNativeCanvas", "I");
015	    canvas = (SkCanvas *)env->GetIntField(obj, fid);
016	    /* ..... draw on canvas .... */
017	}
018	
019	}

obj This parameter is the Java side of the canvas, while SkCanvas is on the Java side canvas of mNativeCanvas field, is an integer. This integer is actually SkCanvas of address, we direct casting into SkCanvas the pointer, so we get SkCanvas, can interface directly plotted through Skia.

Note !! JNI is defined in the  C  language, which is Skia  C ++  's library. Therefore, we use  C ++  to write native code, but in the function definition of the JNI, must use extern " C " wrap, told  C ++  Compiler This function is to use the C  calling rules.

 

Animation

If you want to make movies in native code inside, then he will need to be able to update the screen. If you just save up the canvas of addresses, continue to make updates on the canvas, you will find that the screen does not follow the updates. The correct approach is to call the View invalidate () function, so that  Android  operated updates.

When to View.invalidate. () Is called,  the Android  Framework calls the View of the onDraw (), call Native code for drawing at this time, the updated results appear on the screen. Therefore, animation, Java side. Periodically call View.invalidate (), to update the screen.

 

SurfaceView

SurfaceView also View, but has a separate buffer, called the surface. Since this buffer without transmission  Android as screen updating Framework, can correspond directly to the blocks on the screen, for better performance. (In fact, to update or indirectly on the screen, but less  Android  Framework this layer, but also through  hardware  acceleration. Acceleration functionality is platform dependent.)

When you need better performance, but also a way to inherit SurfaceView. Through time SurfaceView, canvas is no longer through onDraw () achieved. You can () to obtain surface holder by calling SurfaceView.getHolder, and SurfaceHolder.lockCanvas () returns SkCanvas. Native code on the paint can SkCanvas, then call SurfaceHolder.unlockCanvasAndPost (), the content updates to the screen.

Before each screen update, to be () made a new person of SkCanvas through SurfaceHolder.lockCanvas, on this canvas painting job. After the call for all necessary SurfaceHolder.unlockCanvasAndPost () to update. If you can correctly update the screen.

In addition, SurfaceHolder.lockCanvas () returned SkCanvas does not save the contents of the last drawing. Please pay special attention.

SurfaceHolder.lockCanvas () can pass a parameter that specifies the part to be updated. Designating specific areas, I just need to redraw the part without the need to update the whole picture, and improve performance updates.

 

Epilogue

Will study this part, because now porting MadButterfly to  Android  on. Under some experience along the Notes.

 

Original Post Address: http://www.codemud.net/~thinker/GinGin_CGI.py/show_id_doc/404

Reproduced in: https: //my.oschina.net/lendylongli/blog/226811

Guess you like

Origin blog.csdn.net/weixin_34174132/article/details/92576598