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