敞开生长之旅!这是我参加「日新计划 12 月更文挑战」的第9天,点击检查活动概况
要想了解 Flutter,你必须先了解它的底层图画烘托引擎 Skia。由于,Flutter 只关心如何向 GPU 供给视图数据,而 Skia 便是它向 GPU 供给视图数据的好帮手。
Skia是一个用C++开发的开源的2D烘托引擎,支撑多个硬件和软件渠道。而且他是Google chrome, android, Flutter产品里边用到的图形引擎。
Skia简略应用
1、Java外壳
1. public class SkiaView extends View {
2.
3. /** TAG标识 */
4. private static final String TAG = "SkiaView";
5.
6. /** 载入动态库 */
7. static {
8. • try {
9. • System.loadLibrary("SkiaJni");
10. • } catch(UnsatisfiedLinkError e) {
11. • Log.e(TAG, "Couldn't load native libs");
12. • e.printStackTrace();
13. • }
14. }
15.
16. public SkiaView(Context context) {
17. • super(context);
18. }
19.
20. @Override
21. protected void onDraw(Canvas canvas) {
22. • super.onDraw(canvas);
23. • Log.i(TAG, "==draw start==");
24. • // 调用本地办法
25. • native_renderCanvas(canvas);
26. • Log.i(TAG, "==draw end==");
27. }
28.
29. /** 本地烘托画布办法 */
30. private native void native_renderCanvas(Canvas canvas);
31.
32. }
2、C/C++封装
2.1我的环境
XP+Eclipse+Cygwin。预备源码。
2.2树立工程
- 工程地址:AndroidSkia工程根目录jni文件夹。
- Build command:bash –login -c “cd WORKSPACE/AndroidSkia && NDKROOT/ndk-build”
$WORKSPACE、$NDKROOT为作业空间、NDK途径。在Cygwin根目录\home[your name]\ .bash_profile文件内装备。
3.includes jni、skia等需求的头文件。当前如下:
2.3Android.mk
1. LOCAL_PATH := $(call my-dir)
2. include $(CLEAR_VARS)
3.
4. MY_ANDROID_SOURCE = F:/01.软件/01.开发/05.android/android_sys_src/2.3.3_r1
5. MY_ANDROID_SYSLIB = $(MY_ANDROID_SOURCE)/out/target/product/generic/system/lib
6. #也可以在cygwin\home\Join.bash_profile文件内装备,如下:
7. # export MY_ANDROID_SOURCE="/cygdrive/f/..."
8. # export MY_ANDROID_SYSLIB="/cygdrive/f/..."
9.
10. LOCAL_MODULE := libSkiaJni
11. LOCAL_SRC_FILES := \
12. jniLoad.cpp \
13. org_join_skia_SkiaView.cpp
14.
15. LOCAL_C_INCLUDES := \
16. $(MY_ANDROID_SOURCE)/dalvik/libnativehelper/include/nativehelper \
17. $(MY_ANDROID_SOURCE)/frameworks/base/include \
18. $(MY_ANDROID_SOURCE)/system/core/include \
19. $(MY_ANDROID_SOURCE)/frameworks/base/native/include \
20. $(MY_ANDROID_SOURCE)/frameworks/base/core/jni/android/graphics \
21. $(MY_ANDROID_SOURCE)/external/skia/include/core \
22. $(MY_ANDROID_SOURCE)/external/skia/include/config \
23. $(MY_ANDROID_SOURCE)/external/skia/include/p_w_picpaths
24. #同时在工程Properties->C/C++ General->Paths and Symbols属性内include相应文件目录
25. #不然编程时找不到.h文件,不方便写代码,但不会影响编译。而LOCAL_LDLIBS/LOCAL_LDFLAGS必需增加。
26.
27. #LOCAL_LDLIBS := -L$(MY_ANDROID_SYSLIB) -llog -ljnigraphics -lskia -landroid_runtime
28. #也可以用以下方法指定so库
29. LOCAL_LDFLAGS := \
30. $(MY_ANDROID_SYSLIB)/liblog.so \
31. $(MY_ANDROID_SYSLIB)/libjnigraphics.so \
32. $(MY_ANDROID_SYSLIB)/libskia.so \
33. $(MY_ANDROID_SYSLIB)/libskiagl.so \
34. $(MY_ANDROID_SYSLIB)/libandroid_runtime.so
35.
36. include $(BUILD_SHARED_LIBRARY)
LOCAL_C_INCLUDES的头文件途径,第一个是jni的,最后三是lskia的,倒数四是ljnigraphics的,其他为基础的(如llog,除了某一是landroid_runtime的,忘了哪个==)。
MY_ANDROID_SYSLIB也可从模拟器导出。
2.4org_join_skia_SkiaView.cpp
1. #include "jniLoad.h"
2.
3. #include <GraphicsJNI.h>
4. #include <SkCanvas.h>
5. #include <SkPaint.h>
6. #include <SkRect.h>
7. #include <SkColor.h>
8. #include <SkTypes.h>
9. #include <SkGraphics.h>
10.
11. static void drawFlag(SkCanvas* canv);
12.
13. static void native_renderCanvas(JNIEnv* env, jobject obj, jobject canvas) {
14. MY_LOGI("==c method start==");
15.
16. SkCanvas* canv = GraphicsJNI::getNativeCanvas(env, canvas);
17. if (!canv) {
18. • MY_LOGE("==canv is NULL==");
19. • return;
20. }
21.
22. canv->save();
23. canv->translate(100, 100);
24. drawFlag(canv);
25. canv->restore();
26.
27. MY_LOGI("==c method end==");
28. }
29.
30. /** 画旗帜 */
31. static void drawFlag(SkCanvas* canv) {
32. SkPaint* paint = new SkPaint();
33. paint->setFlags(paint->kAntiAlias_Flag);
34.
35. SkRect* rect = new SkRect();
36. rect->set(0, 0, 200, 100);
37. paint->setColor(SK_ColorRED);
38. canv->drawRect(*rect, *paint);
39.
40. paint->setColor(SK_ColorGRAY);
41. paint->setStrokeWidth(10);
42. canv->drawLine(5, 100, 5, 300, *paint);
43.
44. paint->setTextSize(30);
45. paint->setColor(SK_ColorBLUE);
46. paint->setTextAlign(paint->kCenter_Align);
47. const char* text = "Hello World";
48. canv->drawText(text, strlen(text), 100, 60, *paint);
49. }
50.
51. /**
52. * JNI registration.
53. */
54. static JNINativeMethod methods[] = { { "native_renderCanvas",
55. • "(Landroid/graphics/Canvas;)V", (void*) native_renderCanvas } };
56.
57. int register_org_join_skia_SkiaView(JNIEnv *env) {
58. return jniRegisterNativeMethods(env, "org/join/skia/SkiaView", methods,
59. • sizeof(methods) / sizeof(methods[0]));
60. }
2.5jniLoad.h
1. #ifndef JNILOAD_H_
2. #define JNILOAD_H_
3.
4. #include <jni.h>
5. #include <utils/Log.h>
6.
7. #define MY_LOG_TAG "JNI_LOG"
8. #define MY_LOGI(...) __android_log_print(ANDROID_LOG_INFO, MY_LOG_TAG, __VA_ARGS__)
9. #define MY_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, MY_LOG_TAG, __VA_ARGS__)
10.
11. #ifdef __cplusplus
12. extern "C" {
13. #endif
14.
15. int jniRegisterNativeMethods(JNIEnv* env, const char* className,
16. • const JNINativeMethod* gMethods, int numMethods);
17.
18. #ifdef __cplusplus
19. }
20. #endif
21.
22. #endif /* JNILOAD_H_ */
2.6jniLoad.cpp
1. #include "jniLoad.h"
2.
3. #include <stdlib.h>
4.
5. int register_org_join_skia_SkiaView(JNIEnv *env);
6.
7. int jniRegisterNativeMethods(JNIEnv* env, const char* className,
8. • const JNINativeMethod* gMethods, int numMethods) {
9.
10. jclass clazz;
11. MY_LOGI("Registering %s natives\n", className);
12. clazz = env->FindClass(className);
13.
14. if (clazz == NULL) {
15. • MY_LOGE("Native registration unable to find class '%s'\n", className);
16. • return JNI_ERR;
17. }
18. if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
19. • MY_LOGE("RegisterNatives failed for '%s'\n", className);
20. • return JNI_ERR;
21. }
22. return JNI_OK;
23. }
24.
25. jint JNI_OnLoad(JavaVM* vm, void* reserved) {
26. JNIEnv* env = NULL;
27. jint result = JNI_ERR;
28.
29. if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
30. • MY_LOGE("GetEnv failed!");
31. • return result;
32. }
33.
34. MY_LOGI("loading . . .");
35.
36. if(register_org_join_skia_SkiaView(env) != JNI_OK) {
37. • MY_LOGE("can't load org_join_skia_SkiaView");
38. • goto end;
39. }
40. /**
41. * register others
42. */
43.
44. MY_LOGI("loaded");
45.
46. result = JNI_VERSION_1_4;
47. end:
48. return result;
49. }
3、运转作用
Cygwin问题
运用Cygwin时或许遇到的问题,之前都没提到过,现在补上==。
1、make 3.81 bug – error: multiple target patterns. Stop.
[http://cygwin.com/ml/cygwin/2009-04/msg00007.html](https://cygwin.com/ml/cygwin/2009-04/msg00007.html)
•下载http://www.cmake.org/files/cygwin/make.exe替换本来的make.exe
2、增加当前工程下的头文件和库文件
增加include途径:project->properties->c/c++ build->settings->cygwin c compiler->includes->include paths->"${workspace_loc:/${ProjName}}"
•增加链接库:同上,在cygwin c linker->libraries下增加。
3、cygwin warning: MS-DOS style path detected:…
增加环境变量CYGWIN=nodosfilewarning,可取消报警。
文末到这儿Flutter skia简略应用就介绍到这儿。本文主要简介了Flutter学习中的发动流程的 skia引擎他,关于Flutter的学习,还需求学习很多知识点;它的基础语法dart、UI、线程、发动、功能监控。