mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Improve Sky READMEs
TBR=ojan@chromium.org Review URL: https://codereview.chromium.org/1037163002
This commit is contained in:
parent
ffce153d8a
commit
8aff978b43
89
README.md
89
README.md
@ -1,90 +1,7 @@
|
||||
Sky
|
||||
===
|
||||
|
||||
Sky is an experimental, high-performance UI framework for mobile apps. Sky helps
|
||||
you create apps with beautiful user interfaces and high-quality interactive
|
||||
design that run smoothly at 120 Hz.
|
||||
For information about using Sky, please see the
|
||||
[Sky SDK](https://github.com/domokit/sky_sdk/).
|
||||
|
||||
Sky consists of two components:
|
||||
|
||||
1. *The Sky engine.* The [engine](engine) is the core of the system system.
|
||||
Written in C++, the engine provides the muscle of the Sky system. The engine
|
||||
provides several primitives, including a soft real-time scheduler and a
|
||||
hierarchial, retained-mode graphics system, that let you build high-quality
|
||||
apps.
|
||||
|
||||
2. *The Sky framework.* The [framework](framework) makes it easy to build apps
|
||||
using Sky by providing familiar user interface widgets, such as buttons,
|
||||
infinite lists, and animations, on top of the engine using Dart. These
|
||||
extensible components follow a functional programming style inspired by
|
||||
React.
|
||||
|
||||
Sky is still experimental. We're experimenting with different ideas and
|
||||
exploring various approaches, many of which won't work and will need to be
|
||||
discarded, but, if we're lucky, some of which might turn out to be useful.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
The simplest Sky app is, appropriately, HelloWorldApp:
|
||||
|
||||
```dart
|
||||
import 'package:sky/framework/fn.dart';
|
||||
|
||||
class HelloWorldApp extends App {
|
||||
Node build() {
|
||||
return new Text('Hello, world!');
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
new HelloWorldApp();
|
||||
}
|
||||
```
|
||||
|
||||
Execution starts in `main`, which creates the `HelloWorldApp`. The framework
|
||||
then marks `HelloWorldApp` as dirty, which schedules it to build during the next
|
||||
animation frame. Each animation frame, the framework calls `build` on all the
|
||||
dirty components and diffs the virtual `Node` hierarchy returned this frame with
|
||||
the hierarchy returned last frame. Any differences are then applied as mutations
|
||||
to the physical heiarchy retained by the engine.
|
||||
|
||||
For a more featureful example, please see the
|
||||
[example stocks app](examples/stocks/lib/stocks_app.dart).
|
||||
|
||||
Services
|
||||
--------
|
||||
|
||||
Sky apps can access services from the host operating system using Mojo. For
|
||||
example, you can access the network using the `network_service.mojom` interface.
|
||||
Although you can use these low-level interfaces directly, you might prefer to
|
||||
access these services via libraries in the framework. For example, the
|
||||
`fetch.dart` library wraps the underlying `network_service.mojom` in an
|
||||
ergonomic interface:
|
||||
|
||||
```dart
|
||||
import 'package:sky/framework/net/fetch.dart';
|
||||
|
||||
void foo() {
|
||||
fetch('example.txt').then((Response response) {
|
||||
print(response.bodyAsString());
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Supported platforms
|
||||
-------------------
|
||||
|
||||
Currently, Sky supports the Android and Mojo operating systems.
|
||||
|
||||
Specifications
|
||||
--------------
|
||||
|
||||
We're documenting Sky with a [set of technical specifications](specs) that
|
||||
define precisely the behavior of the engine. Currently both the implementation
|
||||
and the specification are in flux, but hopefully they'll converge over time.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Instructions for building and testing Sky are contained in [HACKING.md](HACKING.md).
|
||||
For information about contributing to Sky, please see [HACKING.md](HACKING.md).
|
||||
|
||||
13
examples/README.md
Normal file
13
examples/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
Sky Examples
|
||||
============
|
||||
|
||||
This directory contains several examples of using Sky.
|
||||
|
||||
1. *Hello, world.* The [hello world app](hello_world) is a basic app that shows
|
||||
the text "hello, world."
|
||||
|
||||
2. *Stocks.* The [stocks app](stocks) is an example of a typical mobile app
|
||||
built using Sky. The app shows a list of all the stocks in the NASDAQ.
|
||||
|
||||
3. *Widgets.* The [widgets app](widgets) contains a number of Sky widgets so
|
||||
you can experiment with them in a simple container.
|
||||
11
examples/hello_world/hello_world.dart
Normal file
11
examples/hello_world/hello_world.dart
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:sky/framework/fn.dart';
|
||||
|
||||
class HelloWorldApp extends App {
|
||||
Node build() {
|
||||
return new Text('Hello, world!');
|
||||
}
|
||||
}
|
||||
7
examples/hello_world/main.sky
Normal file
7
examples/hello_world/main.sky
Normal file
@ -0,0 +1,7 @@
|
||||
<script>
|
||||
import 'hello_world.dart';
|
||||
|
||||
void main() {
|
||||
new HelloWorldApp();
|
||||
}
|
||||
</script>
|
||||
@ -8,7 +8,7 @@
|
||||
<script>
|
||||
// TODO(abarth): Should this be package:stocks/stocks_app.dart?
|
||||
import 'lib/stock_app.dart';
|
||||
main() {
|
||||
void main() {
|
||||
new StocksApp();
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
name: stocks
|
||||
author: Chromium Authors <sky-dev@googlegroups.com>
|
||||
description: A demo application using Sky that shows stock data
|
||||
homepage: https://github.com/domokit/mojo/tree/master/sky/examples/stocks-fn
|
||||
homepage: https://github.com/domokit/sky_sdk/tree/master/examples/stocks
|
||||
version: 0.0.1
|
||||
dependencies:
|
||||
sky: '>=0.0.1 <1.0.0'
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
<import src="/sky/framework/debug/shake-to-reload.sky" />
|
||||
<script>
|
||||
import 'widgets_app.dart';
|
||||
main() {
|
||||
void main() {
|
||||
new WidgetsApp();
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,14 +1,17 @@
|
||||
Effen (fn)
|
||||
===
|
||||
Sky Framework
|
||||
=============
|
||||
|
||||
Effen is a prototype of a functional-reactive framework for sky which takes inspiration from [React](http://facebook.github.io/react/).
|
||||
Effen is a functional-reactive framework for Sky which takes inspiration from
|
||||
[React](http://facebook.github.io/react/). Effen is comprised of three main
|
||||
parts: a virtual-dom and diffing engine, a component mechanism and a very early
|
||||
set of widgets for use in creating applications.
|
||||
|
||||
Effen is comprised of three main parts: a virtual-dom and diffing engine, a component mechanism and a very early set of widgets for use in creating applications.
|
||||
|
||||
The central idea is that you build your UI out of components. Components describe what their view should look like given their current configuration & state. The diffing engine ensures that the DOM looks how the component describes by applying minimal diffs to transition it from one state to the next.
|
||||
|
||||
If you just want to dive into code, see the [stocks example](../examples/stocks).
|
||||
The central idea is that you build your UI out of components. Components
|
||||
describe what their view should look like given their current configuration &
|
||||
state. The diffing engine ensures that the DOM looks how the component describes
|
||||
by applying minimal diffs to transition it from one state to the next.
|
||||
|
||||
If you just want to dive into code, see the [stocks example](../../../../examples/stocks).
|
||||
|
||||
Hello World
|
||||
-----------
|
||||
@ -16,9 +19,8 @@ Hello World
|
||||
To build an application, create a subclass of App and instantiate it.
|
||||
|
||||
```HTML
|
||||
<!-- In hello.sky -->
|
||||
<script>
|
||||
import 'helloworld.dart';
|
||||
import 'hello_world.dart';
|
||||
|
||||
main() {
|
||||
new HelloWorldApp();
|
||||
@ -26,68 +28,136 @@ main() {
|
||||
</script>
|
||||
```
|
||||
|
||||
```JavaScript
|
||||
// In helloworld.dart
|
||||
import '../fn/lib/fn.dart';
|
||||
```dart
|
||||
// In hello_world.dart
|
||||
import 'package:sky/framework/fn.dart';
|
||||
|
||||
class HelloWorldApp extends App {
|
||||
Node build() {
|
||||
return new Text('Hello, World!');
|
||||
return new Text('Hello, world!');
|
||||
}
|
||||
}
|
||||
```
|
||||
An app is comprised of (and is, itself, a) components. A component's main job is to implement `Node build()`. The idea here is that the `build` method describes the DOM of a component at any given point during its lifetime. In this case, our `HelloWorldApp`'s `build` method just returns a `Text` node which displays the obligatory line of text.
|
||||
|
||||
An app is comprised of (and is, itself, a) components. A component's main job is
|
||||
to implement `Node build()`. The idea here is that the `build` method describes
|
||||
the DOM of a component at any given point during its lifetime. In this case, our
|
||||
`HelloWorldApp`'s `build` method just returns a `Text` node which displays the
|
||||
obligatory line of text.
|
||||
|
||||
Nodes
|
||||
-----
|
||||
A component's `build` method must return a single `Node` which *may* have children (and so on, forming a *subtree*). Effen comes with a few built-in nodes which mirror the built-in nodes/elements of sky: `Text`, `Anchor` (`<a />`, `Image` (`<img />`) and `Container` (`<div />`). `build` can return a tree of Nodes comprised of any of these nodes and plus any other imported object which extends `Component`.
|
||||
|
||||
A component's `build` method must return a single `Node` which *may* have
|
||||
children (and so on, forming a *subtree*). Effen comes with a few built-in nodes
|
||||
which mirror the built-in nodes/elements of sky: `Text`, `Anchor` (`<a />`,
|
||||
`Image` (`<img />`) and `Container` (`<div />`). `build` can return a tree of
|
||||
Nodes comprised of any of these nodes and plus any other imported object which
|
||||
extends `Component`.
|
||||
|
||||
How to structure you app
|
||||
------------------------
|
||||
If you're familiar with React, the basic idea is the same: Application data flows *down* from components which have data to components & nodes which they construct via construction parameters. Generally speaking, View-Model data (data which is derived from *model* data, but exists only because the view needs it), is computed during the course of `build` and is short-lived, being handed into nodes & components as configuration data.
|
||||
|
||||
If you're familiar with React, the basic idea is the same: Application data
|
||||
flows *down* from components which have data to components & nodes which they
|
||||
construct via construction parameters. Generally speaking, View-Model data (data
|
||||
which is derived from *model* data, but exists only because the view needs it),
|
||||
is computed during the course of `build` and is short-lived, being handed into
|
||||
nodes & components as configuration data.
|
||||
|
||||
What does "data flowing down the tree" mean?
|
||||
--------------------------------------------
|
||||
Consider the case of a checkbox. (i.e. `widgets/checkbox.dart`). The `Checkbox` constructor looks like this:
|
||||
|
||||
```JavaScript
|
||||
Consider the case of a checkbox. (i.e. `widgets/checkbox.dart`). The `Checkbox`
|
||||
constructor looks like this:
|
||||
|
||||
```dart
|
||||
ValueChanged onChanged;
|
||||
bool checked;
|
||||
|
||||
Checkbox({ Object key, this.onChanged, this.checked }) : super(key: key);
|
||||
```
|
||||
|
||||
What this means is that the `Checkbox` component is *never* "owns" the state of the checkbox. It's current state is handed into the `checked` parameter, and when a click occurs, the checkbox invokes its `onChanged` callback with the value it thinks it should be changed to -- but it never directly changes the value itself. This is a bit odd at first look, but if you think about it: a control isn't very useful unless it gets its value out to someone and if you think about databinding, the same thing happens: databinding basically tells a control to *treat some remote variable as its storage*. That's all that is happening here. In this case, some owning component probably has a set of values which describe a form.
|
||||
What this means is that the `Checkbox` component is *never* "owns" the state of
|
||||
the checkbox. It's current state is handed into the `checked` parameter, and
|
||||
when a click occurs, the checkbox invokes its `onChanged` callback with the
|
||||
value it thinks it should be changed to -- but it never directly changes the
|
||||
value itself. This is a bit odd at first look, but if you think about it: a
|
||||
control isn't very useful unless it gets its value out to someone and if you
|
||||
think about databinding, the same thing happens: databinding basically tells a
|
||||
control to *treat some remote variable as its storage*. That's all that is
|
||||
happening here. In this case, some owning component probably has a set of values
|
||||
which describe a form.
|
||||
|
||||
Stateful vs. Stateless components
|
||||
---------------------------------
|
||||
All components have access to two kinds of state: (1) configuration data (constructor arguments) and (2) private data (data they mutate themselves). While react components have explicit property bags for these two kinds of state (`this.prop` and `this.state`), Effen maps these ideas to the public and private fields of the component. Constructor arguments should (by convention) be reflected as public fields of the component and state should only be set on private (with a leading underbar `_`) fields.
|
||||
|
||||
All (non-component) Effen nodes are stateless. Some components will be stateful. This state will likely encapsulate transient states of the UI, such as scroll position, animation state, uncommitted form values, etc...
|
||||
All components have access to two kinds of state: (1) configuration data
|
||||
(constructor arguments) and (2) private data (data they mutate themselves).
|
||||
While react components have explicit property bags for these two kinds of state
|
||||
(`this.prop` and `this.state`), Effen maps these ideas to the public and private
|
||||
fields of the component. Constructor arguments should (by convention) be
|
||||
reflected as public fields of the component and state should only be set on
|
||||
private (with a leading underbar `_`) fields.
|
||||
|
||||
A component can become stateful in two ways: (1) by passing `super(stateful: true)` to its call to the superclass's constructor, or by calling `setState(Function fn)`. The former is a way to have a component start its life stateful, and the latter results in the component becoming statefull *as well as* scheduling the component to re-build at the end of the current animation frame.
|
||||
All (non-component) Effen nodes are stateless. Some components will be stateful.
|
||||
This state will likely encapsulate transient states of the UI, such as scroll
|
||||
position, animation state, uncommitted form values, etc...
|
||||
|
||||
What does it mean to be stateful? It means that the diffing mechanism retains the specific *instance* of the component as long as the component which builds it continues to require its presence. The component which constructed it may have provided new configuration in form of different values for the constructor parameters, but these values (public fields) will be copied (using reflection) onto the retained instance whose privates fields are left unmodified.
|
||||
A component can become stateful in two ways: (1) by passing `super(stateful:
|
||||
true)` to its call to the superclass's constructor, or by calling
|
||||
`setState(Function fn)`. The former is a way to have a component start its life
|
||||
stateful, and the latter results in the component becoming statefull *as well
|
||||
as* scheduling the component to re-build at the end of the current animation
|
||||
frame.
|
||||
|
||||
What does it mean to be stateful? It means that the diffing mechanism retains
|
||||
the specific *instance* of the component as long as the component which builds
|
||||
it continues to require its presence. The component which constructed it may
|
||||
have provided new configuration in form of different values for the constructor
|
||||
parameters, but these values (public fields) will be copied (using reflection)
|
||||
onto the retained instance whose privates fields are left unmodified.
|
||||
|
||||
Rendering
|
||||
---------
|
||||
At the end of each animation frame, all components (including the root `App`) which have `setState` on themselves will be rebuilt and the resulting changes will be minimally applied to the DOM. Note that components of lower "order" (those near the root of the tree) will build first because their building may require rebuilding of higher order (those near the leaves), thus avoiding the possibility that a component which is dirty build more than once during a single cycle.
|
||||
|
||||
At the end of each animation frame, all components (including the root `App`)
|
||||
which have `setState` on themselves will be rebuilt and the resulting changes
|
||||
will be minimally applied to the DOM. Note that components of lower "order"
|
||||
(those near the root of the tree) will build first because their building may
|
||||
require rebuilding of higher order (those near the leaves), thus avoiding the
|
||||
possibility that a component which is dirty build more than once during a single
|
||||
cycle.
|
||||
|
||||
Keys
|
||||
----
|
||||
In order to efficiently apply changes to the DOM and to ensure that stateful components are correctly identified, Effen requires that `no two nodes (except Text) or components of the same type may exist as children of another element without being distinguished by unique keys`. [`Text` is excused from this rule]. In many cases, nodes don't require a key because there is only one type amongst its siblings -- but if there is more one, you must assign each a key. This is why most nodes will take `({ Object key })` as an optional constructor parameter. In development mode (i.e. when sky is built `Debug`) Effen will throw an error if you forget to do this.
|
||||
|
||||
In order to efficiently apply changes to the DOM and to ensure that stateful
|
||||
components are correctly identified, Effen requires that `no two nodes (except
|
||||
Text) or components of the same type may exist as children of another element
|
||||
without being distinguished by unique keys`. [`Text` is excused from this rule].
|
||||
In many cases, nodes don't require a key because there is only one type amongst
|
||||
its siblings -- but if there is more one, you must assign each a key. This is
|
||||
why most nodes will take `({ Object key })` as an optional constructor
|
||||
parameter. In development mode (i.e. when sky is built `Debug`) Effen will throw
|
||||
an error if you forget to do this.
|
||||
|
||||
Event Handling
|
||||
--------------
|
||||
Events logically fire through the Effen node tree. If want to handle an event as it bubbles from the target to the root, create an `EventTarget`. `EventTarget` has named (typed) parameters for a small set of events that we've hit so far, as well as a 'custom' argument which is a `Map<String, sky.EventListener>`. If you'd like to add a type argument for an event, just post a patch.
|
||||
|
||||
```JavaScript
|
||||
Events logically fire through the Effen node tree. If want to handle an event as
|
||||
it bubbles from the target to the root, create an `EventTarget`. `EventTarget`
|
||||
has named (typed) parameters for a small set of events that we've hit so far, as
|
||||
well as a 'custom' argument which is a `Map<String, sky.EventListener>`. If
|
||||
you'd like to add a type argument for an event, just post a patch.
|
||||
|
||||
```dart
|
||||
class MyComp extends Component {
|
||||
MyComp({
|
||||
Object key
|
||||
}) : super(key: key);
|
||||
|
||||
void _handleClick(sky.GestureEvent e) {
|
||||
void _handleTap(sky.GestureEvent e) {
|
||||
// do stuff
|
||||
}
|
||||
|
||||
@ -100,7 +170,7 @@ class MyComp extends Component {
|
||||
new Container(
|
||||
children: // ...
|
||||
),
|
||||
onGestureTap: _handleClick,
|
||||
onGestureTap: _handleTap,
|
||||
custom: {
|
||||
'myCustomEvent': _customEventCallback
|
||||
}
|
||||
@ -115,22 +185,35 @@ class MyComp extends Component {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Styling
|
||||
-------
|
||||
Styling is the part of Effen which is least designed and is likely to change. There are two ways to specify styles:
|
||||
|
||||
* `Style` objects which are interned and can be applied to Elements via the `style` constructor parameter. Use `Style` objects for styles which are *not* animated.
|
||||
* An `inlineStyle` string which can be applied to Elements via the `inlineStyle` constructor parameter. Use `inlineStyle` for styles which *are* animated.
|
||||
Styling is the part of Effen which is least designed and is likely to change.
|
||||
There are two ways to specify styles:
|
||||
|
||||
* `Style` objects which are interned and can be applied to Elements via the
|
||||
``style` constructor parameter. Use `Style` objects for styles which are
|
||||
`*not* animated.
|
||||
|
||||
* An `inlineStyle` string which can be applied to Elements via the
|
||||
`inlineStyle` constructor parameter. Use `inlineStyle` for styles which
|
||||
*are* animated.
|
||||
|
||||
If you need to apply a Style to a Component or Node which you didn't construct (i.e. one that was handed into your constructor), you can wrap it in a `StyleNode` which also takes a `Style` constructor in it's `style` constructor parameter.
|
||||
If you need to apply a Style to a Component or Node which you didn't construct
|
||||
(i.e. one that was handed into your constructor), you can wrap it in a
|
||||
`StyleNode` which also takes a `Style` constructor in it's `style` constructor
|
||||
parameter.
|
||||
|
||||
Animation
|
||||
---------
|
||||
Animation is still an area of exploration. Have a look at [AnimatedComponent](components/animated_component.dart) and [Drawer](components/drawer.dart) for an example of this this currently works.
|
||||
|
||||
Animation is still an area of exploration. Have a look at
|
||||
[AnimatedComponent](components/animated_component.dart) and
|
||||
[Drawer](components/drawer.dart) for an example of this this currently works.
|
||||
|
||||
Performance
|
||||
-----------
|
||||
It is a design goal that it should be *possible* to arrange that all "build" cycles which happen during animations can complete in less than one milliesecond on a Nexus 5.
|
||||
|
||||
|
||||
It is a design goal that it should be *possible* to arrange that all "build"
|
||||
cycles which happen during animations can complete in less than one milliesecond
|
||||
on a Nexus 5.
|
||||
|
||||
@ -1,11 +1,76 @@
|
||||
Sky SDK
|
||||
=======
|
||||
Sky
|
||||
===
|
||||
|
||||
Sky is an experimental, high-performance UI framework for mobile apps. Sky helps
|
||||
you create apps with beautiful user interfaces and high-quality interactive
|
||||
design that run smoothly at 120 Hz.
|
||||
|
||||
Sky consists of two components:
|
||||
|
||||
1. *The Sky engine.* The engine is the core of the system system. Written in
|
||||
C++, the engine provides the muscle of the Sky system. The engine provides
|
||||
several primitives, including a soft real-time scheduler and a hierarchial,
|
||||
retained-mode graphics system, that let you build high-quality apps.
|
||||
|
||||
2. *The Sky framework.* The [framework](packages/sky/lib/framework) makes it
|
||||
easy to build apps using Sky by providing familiar user interface widgets,
|
||||
such as buttons, infinite lists, and animations, on top of the engine using
|
||||
Dart. These extensible components follow a functional programming style
|
||||
inspired by [React](http://facebook.github.io/react/).
|
||||
|
||||
We're still iterating on Sky heavily, which means the framework and underlying
|
||||
engine are both likely to change in incompatible ways several times, but if
|
||||
you're interested in trying out the system, this document can help you get
|
||||
started.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
The simplest Sky app is, appropriately, HelloWorldApp:
|
||||
|
||||
```dart
|
||||
import 'package:sky/framework/fn.dart';
|
||||
|
||||
class HelloWorldApp extends App {
|
||||
Node build() {
|
||||
return new Text('Hello, world!');
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
new HelloWorldApp();
|
||||
}
|
||||
```
|
||||
|
||||
Execution starts in `main`, which creates the `HelloWorldApp`. The framework
|
||||
then marks `HelloWorldApp` as dirty, which schedules it to build during the next
|
||||
animation frame. Each animation frame, the framework calls `build` on all the
|
||||
dirty components and diffs the virtual `Node` hierarchy returned this frame with
|
||||
the hierarchy returned last frame. Any differences are then applied as mutations
|
||||
to the physical heiarchy retained by the engine.
|
||||
|
||||
For more examples, please see the [examples directory](examples/).
|
||||
|
||||
Services
|
||||
--------
|
||||
|
||||
Sky apps can access services from the host operating system using Mojo. For
|
||||
example, you can access the network using the `network_service.mojom` interface.
|
||||
Although you can use these low-level interfaces directly, you might prefer to
|
||||
access these services via libraries in the framework. For example, the
|
||||
`fetch.dart` library wraps the underlying `network_service.mojom` in an
|
||||
ergonomic interface:
|
||||
|
||||
```dart
|
||||
import 'package:sky/framework/net/fetch.dart';
|
||||
|
||||
void main() {
|
||||
fetch('example.txt').then((Response response) {
|
||||
print(response.bodyAsString());
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Set up your computer
|
||||
--------------------
|
||||
|
||||
@ -18,8 +83,8 @@ Set up your computer
|
||||
3. Install the Sky SDK:
|
||||
- ``git clone https://github.com/domokit/sky_sdk.git``
|
||||
|
||||
4. Ensure sure $DART_SDK is set to the path of your Dart SDK and 'adb'
|
||||
(inside 'platform-tools' in the android sdk) is in your $PATH.
|
||||
4. Ensure sure $DART_SDK is set to the path of your Dart SDK and 'adb'
|
||||
(inside 'platform-tools' in the android sdk) is in your $PATH.
|
||||
|
||||
Set up your device
|
||||
------------------
|
||||
@ -38,7 +103,7 @@ of the Android operating system.
|
||||
Running a Sky application
|
||||
-------------------------
|
||||
|
||||
1. ``sky_sdk/bin/sky --install sky_sdk/examples/index.sky``
|
||||
1. ``packages/sky/lib/sky_tool --install examples/stocks/main.sky``
|
||||
The --install flag is only necessary the first time to install SkyDemo.apk.
|
||||
|
||||
2. Use ``adb logcat`` to view any errors or Dart print() output from the app.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user