当前位置:网站首页>Flutter启动流程(Skia引擎)介绍与使用
Flutter启动流程(Skia引擎)介绍与使用
2022-08-04 23:19:00 【守住Android最后的光】
要想了解 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、运行效果
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DH4a2eR4-1659606665079)(https://www.likecs.com/default/index/img?u=aHR0cHM6Ly9waWFuc2hlbi5jb20vaW1hZ2VzLzM0OC83NjRiNGE4Mjg2NDA1NDMxMTgzY2U1MGNjMjZjMmVmYy5wbmc=)]](/img/0f/ae30546382248663133ed700740b71.png)
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、线程、启动、性能监控、以及framework框架的学习进阶。区分出来的知识点很多,我整理出如下知识导图:
根据这些知识脑图划分,我花费半个月时间整理出一套Flutter学习笔记,里面很详细归纳了各个知识点的重点,从基础介绍-技术点原理-源码分析-作用实战演练。
##资料整理和思维脑图整理在这里:【戳我获取】《Flutter3.0》下面是一些PDF细分的学习知识点图解:

资料整理不易,还需大家多多支持;助力Android开发。咱们下期继续Android技术分享。
Android路漫漫,关注多点赞!
边栏推荐
- 小黑leetcode冲浪:94. 二叉树的中序遍历
- The role of @Async annotation and how to implement asynchronous listening mechanism
- 【3D建模制作技巧分享】如何使用ZBrush导出效果图
- [Cultivation of internal skills of string functions] strlen + strstr + strtok + strerror (3)
- Linux系统重启和停止Mysql服务教程
- 仪表板展示 | DataEase看中国:数据呈现中国资本市场
- 年薪50W+的测试工程师都在用这个:Jmeter 脚本开发之——扩展函数
- typeScript-部分应用函数
- PID控制器改进笔记之七:改进PID控制器之防超调设定
- 线性DP(下)
猜你喜欢

ffplay视频播放原理分析

【3D建模制作技巧分享】在zbrush中如何雕刻头发 ZBrush头发雕刻小技巧

Ab3d.PowerToys and Ab3d.DXEngine Crack

轮播图动态渲染

MySQL的安装与卸载

3年,从3K涨薪到20k?真是麻雀啄了牛屁股 — 雀食牛逼呀

【3D建模制作技巧分享】ZBrush如何重新拓扑

逆序对的数量

Pytorch分布式训练/多卡/多GPU训练DDP的torch.distributed.launch和torchrun
![[Cultivation of internal skills of string functions] strcpy + strcat + strcmp (1)](/img/b6/5a1c8b675dc7f67f359c25908403e1.png)
[Cultivation of internal skills of string functions] strcpy + strcat + strcmp (1)
随机推荐
【3D建模制作技巧分享】ZBrush如何使用Z球
4-《PyTorch深度学习实践》-反向传播
node中package解析、npm 命令行npm详解,node中的common模块化,npm、nrm两种方式查看源和切换镜像
I was rejected by the leader for a salary increase, and my anger rose by 9.5K after switching jobs. This is my mental journey
MYS-6ULX-IOT 开发板测评——使用 Yocto 添加软件包
请你说一下final关键字以及static关键字
~ hand AHB - APB Bridge 】 【 AMBA AHB bus
[Cultivation of internal skills of string functions] strcpy + strcat + strcmp (1)
Service Mesh落地路径
【3D建模制作技巧分享】zbrush贴图映射小技巧
【字符串函数内功修炼】strncpy + strncat + strncmp(二)
七牛云图片上传
Shell expect 实战案例
The market value of 360 has evaporated by 390 billion in four years. Can government and enterprise security save lives?
文章占位 文章占位
C语言实现扫雷 附带源代码
一点点读懂cpufreq(一)
C5750X7R2E105K230KA(电容器)MSP430F5249IRGCR微控制器资料
生成回文数
亿流量大考(3):不加机器,如何抗住每天百亿级高并发流量?