当前位置:网站首页>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路漫漫,关注多点赞!
边栏推荐
- typeScript-promise
- Vscode连接远程服务器(一套配置成功)
- 软件测试技术之如何编写测试用例(4)
- The role of @Async annotation and how to implement asynchronous listening mechanism
- 如何根据地址获取函数名
- Ab3d.PowerToys and Ab3d.DXEngine Crack
- [Cultivation of internal skills of string functions] strncpy + strncat + strncmp (2)
- Literature reading ten - Detect Rumors on Twitter by Promoting Information Campaigns with Generative Adversarial Learn
- Nuclei(二)进阶——深入理解workflows、Matchers和Extractors
- 【SSR服务端渲染+CSR客户端渲染+post请求+get请求+总结】
猜你喜欢
![[Cultivation of internal skills of memory operation functions] memcpy + memmove + memcmp + memset (4)](/img/08/e115e1b0d801fcebef440ad4932610.png)
[Cultivation of internal skills of memory operation functions] memcpy + memmove + memcmp + memset (4)

2022年全网最全接口自动化测试框架搭建,没有之一

js中小数四则运算精度问题原因及解决办法

MySQL的JSON 数据类型1
![[Cultivation of internal skills of string functions] strlen + strstr + strtok + strerror (3)](/img/96/946bbef52bd017ac6142c6b7485a86.png)
[Cultivation of internal skills of string functions] strlen + strstr + strtok + strerror (3)

地面高度检测/平面提取与检测(Fast Plane Extraction in Organized Point Clouds Using Agglomerative Hierarchical Clu)

MySQL基础篇【聚合函数】

【七夕快乐篇】Nacos是如何实现服务注册功能的?

App测试和Web测试的区别

360市值四年蒸发3900亿,政企安全能救命吗?
随机推荐
功耗控制之DVFS介绍
一点点读懂cpufreq(一)
【3D建模制作技巧分享】ZBrush如何重新拓扑
一点点读懂thermal(一)
C语言实现扫雷 附带源代码
Nuclei(二)进阶——深入理解workflows、Matchers和Extractors
The Go Programming Language (Introduction)
js中小数四则运算精度问题原因及解决办法
【软件测试】常用ADB命令
typeScript-promise
测试技术:关于上下文驱动测试的总结
从“草原牛”到“数字牛”:蒙牛的数字化转型之道
正则表达式绕过
MySQL的JSON 数据类型2
安全软件 Avast 与赛门铁克诺顿 NortonLifeLock 合并案获英国批准,市值暴涨 43%
MySQL的安装与卸载
NebulaGraph v3.2.0 Release Note, many optimizations such as the performance of querying the shortest path
生产者消费者问题
质量管理大师爱德华·戴明博士经典的质量管理14条原则
[Cultivation of internal skills of string functions] strlen + strstr + strtok + strerror (3)