7-12 6,042 views
Getting Source code
Install depot_tools
Clone the depot_tools repository:
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
Add depot_tools to the end of your PATH (you will probably want to put this in your ~/.bashrc or ~/.zshrc). Assuming you cloned depot_tools to /path/to/depot_tools:
export PATH=`pwd`/depot_tools:$PATH
Set Proxy
export http_proxy=http://127.0.0.1:4000
export https_proxy=https://127.0.0.1:4000
Getting the code
- Create an empty directory for your copy of the repository. For best results, call it
engine: some of the tools assume this name when working across repositories. (They can be configured to use other names too, so this isn't a strict requirement.) - Create a
.gclientfile in theenginedirectory with the following contents, replacing<your_name_here>with your GitHub account name:
solutions = [
{
"managed": False,
"name": "src/flutter",
"url": "https://github.com/flutter/engine.git",
"custom_deps": {},
"deps_file": "DEPS",
"safesync_url": "",
},
]
cd engine(Change to the directory in which you put the.gclientfile.)gclient syncThis will fetch all the source code that Flutter depends on. Avoid interrupting this script, it can leave your repository in an inconsistent state that is tedious to clean up.cd src/flutter(Change to theflutterdirectory of thesrcdirectory thatgclient synccreated in yourenginedirectory.)git remote add upstream git@github.com:flutter/engine.git(So that you fetch from the masterflutter/enginerepository, not your clone, when runninggit fetchet al.)cd ..(Return to thesrcdirectory thatgclient synccreated in yourenginedirectory.)- If you're on Linux, run
sudo ./build/install-build-deps-android.sh - If you're on Linux, run
sudo ./build/install-build-deps.sh - If you're on Mac, install Oracle's Java JDK, version 1.7 or later.
- If you're on Mac, install
ant:brew install ant - If you're on Windows, install Visual Studio (non-Google developers only)
- If you're planning on working on the buildroot repository as well, and have a local checkout of that repository, run the following commands in the
srcdirectory to update your git remotes accordingly:
git remote rename origin upstream
git remote add origin git@github.com:<your_name_here>/buildroot.git
Android
FlutterApplication
Flutter的大致原理是在Application的入口函数 onCreate 通过 System.loadLibrary("flutter") 加载 FlutterEngine 库来实现
首先将源码定位到 engine/shell/platform/android/io/flutter/app/FlutterApplication.java
public class FlutterApplication extends Application {
@Override
@CallSuper
public void onCreate() {
super.onCreate();
FlutterMain.startInitialization(this); // 1️⃣
}
...
}
engine/shell/platform/android/io/flutter/view/FlutterMain.java
public static void startInitialization(Context applicationContext, Settings settings) {
...
initConfig(applicationContext);
initAot(applicationContext);
initResources(applicationContext);
System.loadLibrary("flutter"); // 2️⃣
...
}
FlutterActivity
engine/shell/platform/android/io/flutter/app/FlutterActivity.java
public class FlutterActivity extends Activity implements FlutterView.Provider, PluginRegistry, ViewFactory {
private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this);
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
eventDelegate.onCreate(savedInstanceState);
}
}
engine/shell/platform/android/io/flutter/app/FlutterActivityDelegate.java
public final class FlutterActivityDelegate
implements FlutterActivityEvents,
FlutterView.Provider,
PluginRegistry {
@Override
public void onCreate(Bundle savedInstanceState) {
...
// 3️⃣
FlutterMain.ensureInitializationComplete(activity.getApplicationContext(), args);
flutterView = viewFactory.createFlutterView(activity);
if (flutterView == null) {
FlutterNativeView nativeView = viewFactory.createFlutterNativeView();
flutterView = new FlutterView(activity, null, nativeView); // 4️⃣
flutterView.setLayoutParams(matchParent);
activity.setContentView(flutterView);
launchView = createLaunchView();
if (launchView != null) {
addLaunchView();
}
}
// When an activity is created for the first time, we direct the
// FlutterView to re-use a pre-existing Isolate rather than create a new
// one. This is so that an Isolate coming in from the ViewFactory is
// used.
final boolean reuseIsolate = true;
if (loadIntent(activity.getIntent(), reuseIsolate)) {
return;
}
if (!flutterView.getFlutterNativeView().isApplicationRunning()) {
String appBundlePath = FlutterMain.findAppBundlePath(activity.getApplicationContext());
if (appBundlePath != null) {
flutterView.runFromBundle(appBundlePath, null, "main", reuseIsolate);
}
}
}
}
engine/shell/platform/android/io/flutter/app/FlutterMain.java
public static void ensureInitializationComplete(Context applicationContext, String[] args) {
...
nativeInit(applicationContext, shellArgs.toArray(new String[0]), // 5️⃣
appBundlePath);
...
}
nativeInit 对应 FlutterMain::Init
engine/shell/platform/android/flutter_main.cc
void FlutterMain::Init(JNIEnv* env,
jclass clazz,
jobject context,
jobjectArray jargs,
jstring bundlePath) {
std::vector<std::string> args;
args.push_back("flutter");
for (auto& arg : fml::jni::StringArrayToVector(env, jargs)) {
args.push_back(std::move(arg));
}
auto command_line = fxl::CommandLineFromIterators(args.begin(), args.end());
auto settings = SettingsFromCommandLine(command_line);
settings.assets_path = fml::jni::JavaStringToString(env, bundlePath);
// 6️⃣
if (!blink::DartVM::IsRunningPrecompiledCode()) {
// Check to see if the appropriate kernel files are present and configure
// settings accordingly.
auto platform_kernel_path =
fml::paths::JoinPaths({settings.assets_path, "platform.dill"});
auto application_kernel_path =
fml::paths::JoinPaths({settings.assets_path, "kernel_blob.bin"});
if (files::IsFile(application_kernel_path)) {
settings.application_kernel_asset = application_kernel_path;
if (files::IsFile(platform_kernel_path)) {
settings.platform_kernel_path = platform_kernel_path;
}
}
}
settings.task_observer_add = [](intptr_t key, fxl::Closure callback) {
fml::MessageLoop::GetCurrent().AddTaskObserver(key, std::move(callback));
};
settings.task_observer_remove = [](intptr_t key) {
fml::MessageLoop::GetCurrent().RemoveTaskObserver(key);
};
// Not thread safe. Will be removed when FlutterMain is refactored to no
// longer be a singleton.
g_flutter_main.reset(new FlutterMain(std::move(settings)));
}
AndroidSurface
engine/shell/platform/android/io/flutter/view/FlutterView.java
public FlutterView(Context context, AttributeSet attrs, FlutterNativeView nativeView) {
......
Activity activity = (Activity) getContext();
// 1️⃣
if (nativeView == null) {
mNativeView = new FlutterNativeView(activity.getApplicationContext());
} else {
mNativeView = nativeView;
}
mNativeView.attachViewAndActivity(this, activity);
......
mSurfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
assertAttached();
// 2️⃣
nativeSurfaceCreated(mNativeView.get(), holder.getSurface(), backgroundColor);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
assertAttached();
nativeSurfaceChanged(mNativeView.get(), width, height);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
assertAttached();
nativeSurfaceDestroyed(mNativeView.get());
}
};
getHolder().addCallback(mSurfaceCallback);
......
}
先看 1️⃣ 处代码 FlutterNativeView
engine/shell/platform/android/io/flutter/view/FlutterNativeView.java
public FlutterNativeView(Context context) {
mContext = context;
mPluginRegistry = new FlutterPluginRegistry(this, context);
attach(this); // 3️⃣
assertAttached();
mMessageHandlers = new HashMap<>();
}
attach 方法调用了 nativeAttach 方法,在其内部创建 AndroidSurface
private void attach(FlutterNativeView view) {
mNativePlatformView = nativeAttach(view);
}
engine/shell/platform/android/platform_view_android_jni.cc
// Called By Java
static jlong Attach(JNIEnv* env, jclass clazz, jobject flutterView) {
fml::jni::JavaObjectWeakGlobalRef java_object(env, flutterView);
auto shell_holder = std::make_unique<AndroidShellHolder>( // 4️⃣ 创建 AndroidShellHolder
FlutterMain::Get().GetSettings(), java_object);
if (shell_holder->IsValid()) {
return reinterpret_cast<jlong>(shell_holder.release());
} else {
return 0;
}
}
engine/shell/platform/android/android_shell_holder.cc
AndroidShellHolder::AndroidShellHolder(
blink::Settings settings,
fml::jni::JavaObjectWeakGlobalRef java_object)
: settings_(std::move(settings)), java_object_(java_object) {
......
fml::WeakPtr<PlatformViewAndroid> weak_platform_view;
Shell::CreateCallback<PlatformView> on_create_platform_view =
[java_object, &weak_platform_view](Shell& shell) {
// 5️⃣ 创建 PlatformViewAndroid
auto platform_view_android = std::make_unique<PlatformViewAndroid>(
shell, // delegate
shell.GetTaskRunners(), // task runners
java_object, // java object handle for JNI interop
shell.GetSettings()
.enable_software_rendering // use software rendering
);
weak_platform_view = platform_view_android->GetWeakPtr();
return platform_view_android;
};
......
}
engine/shell/platform/android/platform_view_android.cc
PlatformViewAndroid::PlatformViewAndroid(
PlatformView::Delegate& delegate,
blink::TaskRunners task_runners,
fml::jni::JavaObjectWeakGlobalRef java_object,
bool use_software_rendering)
: PlatformView(delegate, std::move(task_runners)),
java_object_(java_object),
// 6️⃣ 创建 AndroidSurface
android_surface_(AndroidSurface::Create(use_software_rendering)) {
FXL_CHECK(android_surface_)
<< "Could not create an OpenGL, Vulkan or Software surface to setup "
"rendering.";
}
AndroidSurface 有三中实现 AndroidSurfaceSoftware 、 AndroidSurfaceVulkan 和 AndroidSurfaceGL
engine/shell/platform/android/android_surface.cc
std::unique_ptr<AndroidSurface> AndroidSurface::Create(
bool use_software_rendering) {
if (use_software_rendering) {
auto software_surface = std::make_unique<AndroidSurfaceSoftware>();
return software_surface->IsValid() ? std::move(software_surface) : nullptr;
}
#if SHELL_ENABLE_VULKAN
auto vulkan_surface = std::make_unique<AndroidSurfaceVulkan>();
return vulkan_surface->IsValid() ? std::move(vulkan_surface) : nullptr;
#else // SHELL_ENABLE_VULKAN
auto gl_surface = std::make_unique<AndroidSurfaceGL>();
return gl_surface->IsOffscreenContextValid() ? std::move(gl_surface)
: nullptr;
#endif // SHELL_ENABLE_VULKAN
}
再看 FlutterView 2️⃣ 处的代码
engine/shell/platform/android/platform_view_android_jni.cc
static const JNINativeMethod view_methods[] = {
{
.name = "nativeSurfaceCreated",
.signature = "(JLandroid/view/Surface;I)V",
.fnPtr = reinterpret_cast<void*>(&shell::SurfaceCreated),
},
......
}
定位到 SurfaceCreated 方法:
engine/shell/platform/android/platform_view_android_jni.cc
static void SurfaceCreated(JNIEnv* env,
jobject jcaller,
jlong shell_holder,
jobject jsurface,
jint backgroundColor) {
// Note: This frame ensures that any local references used by
// ANativeWindow_fromSurface are released immediately. This is needed as a
// workaround for https://code.google.com/p/android/issues/detail?id=68174
fml::jni::ScopedJavaLocalFrame scoped_local_reference_frame(env);
auto window = fxl::MakeRefCounted<AndroidNativeWindow>(
ANativeWindow_fromSurface(env, jsurface));
// 7️⃣
ANDROID_SHELL_HOLDER->GetPlatformView()->NotifyCreated(std::move(window));
}
engine/shell/platform/android/platform_view_android.cc
void PlatformViewAndroid::NotifyCreated(
fxl::RefPtr<AndroidNativeWindow> native_window) {
InstallFirstFrameCallback();
// 8️⃣
android_surface_->SetNativeWindow(native_window);
// 9️⃣
PlatformView::NotifyCreated();
}
先看 8️⃣ 处的代码,由于 AndroidSurface 有三种实现,这里只看 android_surface_software
engine/shell/platform/android/android_surface_software.cc
bool AndroidSurfaceSoftware::SetNativeWindow(
fxl::RefPtr<AndroidNativeWindow> window) {
native_window_ = std::move(window);
if (!(native_window_ && native_window_->IsValid()))
return false;
int32_t window_format = ANativeWindow_getFormat(native_window_->handle());
if (window_format < 0)
return false;
if (!GetSkColorType(window_format, &target_color_type_, &target_alpha_type_))
return false;
return true;
}
接着继续看 9️⃣ 的代码:
engine/shell/common/platform_view.cc
void PlatformView::NotifyCreated() {
delegate_.OnPlatformViewCreated(*this, CreateRenderingSurface());
}
delegate_ 的值为:
engine/shell/common/shell.cc
// |shell::PlatformView::Delegate|
void Shell::OnPlatformViewCreated(const PlatformView& view,
std::unique_ptr<Surface> surface) {
FXL_DCHECK(is_setup_);
FXL_DCHECK(&view == platform_view_.get());
FXL_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
// Note:
// This is a synchronous operation because certain platforms depend on
// setup/suspension of all activities that may be interacting with the GPU in
// a synchronous fashion.
fxl::AutoResetWaitableEvent latch;
auto gpu_task = fxl::MakeCopyable([rasterizer = rasterizer_->GetWeakPtr(), //
surface = std::move(surface), //
&latch]() mutable {
if (rasterizer) {
rasterizer->Setup(std::move(surface));
}
// Step 2: All done. Signal the latch that the platform thread is waiting
// on.
latch.Signal();
});
auto ui_task = [engine = engine_->GetWeakPtr(), //
gpu_task_runner = task_runners_.GetGPUTaskRunner(), //
gpu_task //
] {
if (engine) {
// ?
engine->OnOutputSurfaceCreated();
}
// Step 1: Next, tell the GPU thread that it should create a surface for its
// rasterizer.
fml::TaskRunner::RunNowOrPostTask(gpu_task_runner, gpu_task);
};
// Step 0: Post a task onto the UI thread to tell the engine that it has an
// output surface.
fml::TaskRunner::RunNowOrPostTask(task_runners_.GetUITaskRunner(), ui_task);
latch.Wait();
}
engine/shell/common/engine.cc
void Engine::OnOutputSurfaceCreated() {
have_surface_ = true;
StartAnimatorIfPossible();
ScheduleFrame();
}
engine/shell/common/rasterizer.cc
void Rasterizer::Setup(std::unique_ptr<Surface> surface) {
surface_ = std::move(surface);
compositor_context_->OnGrContextCreated();
}
Canvas
engine/lib/ui/painting/canvas.cc
engine/lib/ui/dart_ui.cc
void DartUI::InitForGlobal() {
if (!g_natives) {
g_natives = new tonic::DartLibraryNatives();
Canvas::RegisterNatives(g_natives);
CanvasGradient::RegisterNatives(g_natives);
CanvasImage::RegisterNatives(g_natives);
CanvasPath::RegisterNatives(g_natives);
CanvasPathMeasure::RegisterNatives(g_natives);
...
Window::RegisterNatives(g_natives);
}
}
engine/lib/ui/painting.dart
包名:
part of dart.ui;
Canvas
class Canvas extends NativeFieldWrapperClass2 {
Canvas(PictureRecorder recorder, [ Rect cullRect ]) : assert(recorder != null) {
if (recorder.isRecording)
throw new ArgumentError('"recorder" must not already be associated with another Canvas.');
cullRect ??= Rect.largest;
_constructor(recorder, cullRect.left, cullRect.top, cullRect.right, cullRect.bottom);
}
void _constructor(PictureRecorder recorder,
double left,
double top,
double right,
double bottom) native 'Canvas_constructor';
void save() native 'Canvas_save';
...
}
类似 Java 的 native 方法,dart native extensions
static void Canvas_constructor(Dart_NativeArguments args) {
DartCallConstructor(&Canvas::Create, args);
}
void Canvas::RegisterNatives(tonic::DartLibraryNatives* natives) {
natives->Register({{"Canvas_constructor", Canvas_constructor, 6, true},
FOR_EACH_BINDING(DART_REGISTER_NATIVE)});
}
fxl::RefPtr<Canvas> Canvas::Create(PictureRecorder* recorder,
double left,
double top,
double right,
double bottom) {
if (!recorder)
Dart_ThrowException(
ToDart("Canvas constructor called with non-genuine PictureRecorder."));
FXL_DCHECK(!recorder->isRecording()); // verified by Dart code
fxl::RefPtr<Canvas> canvas = fxl::MakeRefCounted<Canvas>(
recorder->BeginRecording(SkRect::MakeLTRB(left, top, right, bottom)));
recorder->set_canvas(canvas);
return canvas;
}
flutter/packages/flutter/lib/src/rendering/object.dart
/// The canvas on which to paint.
///
/// The current canvas can change whenever you paint a child using this
/// context, which means it's fragile to hold a reference to the canvas
/// returned by this getter.
Canvas get canvas {
if (_canvas == null)
_startRecording();
return _canvas;
}
void _startRecording() {
assert(!_isRecording);
_currentLayer = new PictureLayer(estimatedBounds);
_recorder = new ui.PictureRecorder();
_canvas = new Canvas(_recorder);
_containerLayer.append(_currentLayer);
}
FlutterEngineRun
engine/shell/platform/embedder/embedder.cc
FlutterResult FlutterEngineRun(size_t version,
const FlutterRendererConfig* config,
const FlutterProjectArgs* args,
void* user_data,
FlutterEngine* engine_out) {
......
// Step 1: Create the engine.
auto embedder_engine =
std::make_unique<shell::EmbedderEngine>(std::move(thread_host), //
std::move(task_runners), //
settings, //
on_create_platform_view, //
on_create_rasterizer //
);
if (!embedder_engine->IsValid()) {
return kInvalidArguments;
}
// Step 2: Setup the rendering surface.
if (!embedder_engine->NotifyCreated()) {
return kInvalidArguments;
}
// Step 3: Run the engine.
auto run_configuration = shell::RunConfiguration::InferFromSettings(settings);
run_configuration.AddAssetResolver(
std::make_unique<blink::DirectoryAssetBundle>(
fml::Duplicate(settings.assets_dir)));
run_configuration.AddAssetResolver(
std::make_unique<blink::DirectoryAssetBundle>(fml::OpenFile(
settings.assets_path.c_str(), fml::OpenPermission::kRead, true)));
if (!embedder_engine->Run(std::move(run_configuration))) {
return kInvalidArguments;
}
// Finally! Release the ownership of the embedder engine to the caller.
*engine_out = reinterpret_cast<FlutterEngine>(embedder_engine.release());
return kSuccess;
}
Thanks in support of sharing such a nice thought, piece of writing is fastidious, thats
why i have read it completely https://www.manosmaravillosas.com/index.php/enviar-amigo/?url=http://www.mbet88vn.com
Thanks in support of sharing such a nice thought, piece
of writing is fastidious, thats why i have read it completely https://www.manosmaravillosas.com/index.php/enviar-amigo/?url=http://www.mbet88vn.com
If you would like to improve your knowledge only keep visiting this web page and be
updated with the most up-to-date information posted here. http://Distributors.Maitredpos.com/forwardtoafriend.aspx?returnurl=http://alternatif188bet.com
If you would like to improve your knowledge only keep visiting this web page and be updated with the most
up-to-date information posted here. http://Distributors.Maitredpos.com/forwardtoafriend.aspx?returnurl=http://alternatif188bet.com
Howdy! I’m at work browsing your blog from my new iphone 3gs!
Just wanted to say I love reading through your blog and look
forward to all your posts! Carry on the great work! http://alternatif188bet.com
Howdy! I’m at work browsing your blog from my new iphone 3gs!
Just wanted to say I love reading through your blog and look forward to all
your posts! Carry on the great work! http://alternatif188bet.com
I loved as much as you will receive carried out right here.
The sketch is attractive, your authored subject matter stylish.
nonetheless, you command get bought an nervousness over that you wish be delivering the following.
unwell unquestionably come more formerly again as exactly the same nearly a lot often inside case you shield this hike. http://alternatif188bet.com
I loved as much as you will receive carried out right here.
The sketch is attractive, your authored subject matter stylish.
nonetheless, you command get bought an nervousness over that you wish be delivering the following.
unwell unquestionably come more formerly again as exactly
the same nearly a lot often inside case you shield this hike. http://alternatif188bet.com
Hurrah! In the end I got a webpage from where I be able to truly take helpful facts concerning my study and knowledge. http://www.petsay.com/url.php?url=http://alternatif188bet.com
Hurrah! In the end I got a webpage from where I be able to
truly take helpful facts concerning my study and knowledge. http://www.petsay.com/url.php?url=http://alternatif188bet.com
http://buyamlodipine.top/ – amlodipine 5 mg buy amlodipine online
http://buyamlodipine.top/
http://buyamlodipine.top/ – amlodipine 10 mg online amlodipine 5 mg
http://buyamlodipine.top/
http://buyamlodipine.top/ – buy amlodipine 2.5 mg online amlodipine 10 mg
http://buyamlodipine.top/
http://buyamlodipine.top/ – buy amlodipine 2.5 mg online amlodipine 2.5 mg online
http://buyamlodipine.top/
http://buyamlodipine.top/ – amlodipine 2.5 mg url
http://buyamlodipine.top/
whoah this blog is magnificent i really like reading your
articles. Stay up the great work! You recognize, many people are looking around for this
information, you can help them greatly.