Add tutorial section and Android part
Summary: JS is next. Screenshot on the intro page is really bad. I hope danielbuechele can replace this. :) Reviewed By: jknoxville Differential Revision: D15184371 fbshipit-source-id: 2faaf46450d192ae400675c13b8d71fa1b7dab14
This commit is contained in:
committed by
Facebook Github Bot
parent
f584eb05dd
commit
2b0e91aa69
BIN
docs/assets/android-tutorial-app.png
Normal file
BIN
docs/assets/android-tutorial-app.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 MiB |
BIN
docs/assets/android-tutorial.png
Normal file
BIN
docs/assets/android-tutorial.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 458 KiB |
105
docs/tutorial/android.md
Normal file
105
docs/tutorial/android.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
---
|
||||||
|
id: android
|
||||||
|
title: Building an Android Plugin
|
||||||
|
---
|
||||||
|
|
||||||
|
<img align="right" src="/docs/assets/android-tutorial-app.png" alt="Android Tutorial App" width="200">
|
||||||
|
|
||||||
|
For the purpose of the tutorial, we will assume you already have an existing
|
||||||
|
Android application in which you have a feed or list of items. As the Flipper
|
||||||
|
team, we obviously concern ourselves mostly with sea mammals, so this is what
|
||||||
|
our app displays. The actual display logic is not what's interesting here,
|
||||||
|
but how we can make this data available in our Flipper desktop app.
|
||||||
|
|
||||||
|
Part of what makes Flipper so useful is allowing users to inspect the
|
||||||
|
internals of their app. In this case, we'd like to see the specific
|
||||||
|
sea mammal data the app is handling, so let's write a plugin to make that
|
||||||
|
easy.
|
||||||
|
|
||||||
|
You can find the source code of the project [on GitHub](
|
||||||
|
https://github.com/facebook/flipper/tree/7dae5771d96ea76b75796d3b3a2c78746e581e3f/android/tutorial).
|
||||||
|
|
||||||
|
## Creating a Plugin
|
||||||
|
|
||||||
|
On Android, a Flipper plugin is a class that implements the
|
||||||
|
[`FlipperPlugin`](https://github.com/facebook/flipper/blob/master/android/src/main/java/com/facebook/flipper/core/FlipperPlugin.java)
|
||||||
|
interface.
|
||||||
|
|
||||||
|
The interface is rather small and only comprises four methods:
|
||||||
|
|
||||||
|
- `getId() -> String`: Specify a unique string so the JavaScript side knows where to talk to. This must match the name attribute in the `package.json` we will look into later in this tutorial.
|
||||||
|
- `onConnect(FlipperConnection)`: This method is called when the desktop app connects to the mobile client and is ready to receive or send data.
|
||||||
|
- `onDisconnect()`: We're sure you can figure this one out.
|
||||||
|
- `runInBackground() -> Boolean`: Unless this is true, only the currently selected plugin in the Flipper UI can communicate with the device.
|
||||||
|
|
||||||
|
Let's implement these methods for our sealife app:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
import com.facebook.flipper.core.FlipperConnection
|
||||||
|
import com.facebook.flipper.core.FlipperObject
|
||||||
|
import com.facebook.flipper.core.FlipperPlugin
|
||||||
|
import com.facebook.flipper.sample.tutorial.MarineMammals
|
||||||
|
|
||||||
|
class SeaMammalFlipperPlugin : FlipperPlugin {
|
||||||
|
private var connection: FlipperConnection? = null
|
||||||
|
|
||||||
|
override fun getId(): String = "sea-mammals"
|
||||||
|
|
||||||
|
override fun onConnect(connection: FlipperConnection?) {
|
||||||
|
this.connection = connection
|
||||||
|
|
||||||
|
MarineMammals.list.mapIndexed { index, (title, picture_url) ->
|
||||||
|
FlipperObject.Builder()
|
||||||
|
.put("id", index)
|
||||||
|
.put("title", title)
|
||||||
|
.put("url", picture_url).build()
|
||||||
|
}.forEach(this::newRow)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDisconnect() {
|
||||||
|
connection = null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun runInBackground(): Boolean = false
|
||||||
|
|
||||||
|
private fun newRow(row: FlipperObject) {
|
||||||
|
connection?.send("newRow", row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
*See [SeaMammalFlipperPlugin.kt](https://github.com/facebook/flipper/blob/5afb148ffa9e267e5b24e0dfae198d1cf46cc396/android/tutorial/src/main/java/com/facebook/flipper/sample/tutorial/plugin/SeaMammalFlipperPlugin.kt)*
|
||||||
|
|
||||||
|
The two interesting bits here are `onConnect` and `newRow`. `newRow` sends a message
|
||||||
|
to the desktop app and is identified with the same name "newRow".
|
||||||
|
|
||||||
|
For our sample app, we're dealing with a static data source. However, in real
|
||||||
|
life, you will likely dynamically receive new data as the user interacts with
|
||||||
|
the app. So while we just send all the data we have at once in `onConnect`,
|
||||||
|
you would normally set up a listener here to instead call `newRow` as new data
|
||||||
|
arrives.
|
||||||
|
|
||||||
|
You may have noticed that we don't just send random `Object`s over the wire but
|
||||||
|
use `FlipperObject`s instead. What are they? A `FlipperObject` works similar
|
||||||
|
to a JSON dictionary and has a limited set of supported types like strings,
|
||||||
|
integers and arrays. Before sending an object from your native app to the
|
||||||
|
desktop, you first need to break it down into `FlipperObject`-serializable parts.
|
||||||
|
|
||||||
|
## Registering your Plugin
|
||||||
|
|
||||||
|
Now all you need to do is let Flipper know about your new plugin. You do this
|
||||||
|
by calling `addPlugin` on your `FlipperClient`, which is normally created
|
||||||
|
at application startup.
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val flipperClient = AndroidFlipperClient.getInstance(this)
|
||||||
|
// Add all sorts of other amazing plugins here ...
|
||||||
|
flipperClient.addPlugin(SeaMammalFlipperPlugin())
|
||||||
|
flipperClient.start()
|
||||||
|
```
|
||||||
|
*See [`TutorialApplication.kt`](https://github.com/facebook/flipper/blob/5afb148ffa9e267e5b24e0dfae198d1cf46cc396/android/tutorial/src/main/java/com/facebook/flipper/sample/tutorial/TutorialApplication.kt)*
|
||||||
|
|
||||||
|
## What next
|
||||||
|
|
||||||
|
When starting your application now, Flipper will tell the desktop application
|
||||||
|
about the plugin it supports, including "sea-mammals" and will look for a
|
||||||
|
corresponding JavaScript plugin by that name. Let's build that next.
|
||||||
19
docs/tutorial/intro.md
Normal file
19
docs/tutorial/intro.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
id: intro
|
||||||
|
title: Intro
|
||||||
|
---
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
In this tutorial, we show you how how easy it is to build a Flipper plugin
|
||||||
|
for Android and iOS that extracts data from your native application and
|
||||||
|
displays it in the desktop app.
|
||||||
|
|
||||||
|
We then guide you through the process of converting a basic table plugin into
|
||||||
|
a full plugin with custom UI components.
|
||||||
|
|
||||||
|
Before we get started, let's define two terms we will use frequently throughout
|
||||||
|
this tutorial:
|
||||||
|
|
||||||
|
- **Desktop app**: This is the Electron-based application you run on your desktop.
|
||||||
|
- **Mobile client**: This is the mobile app running most likely on a phone or other mobile device. It connects to the desktop app.
|
||||||
@@ -121,6 +121,12 @@
|
|||||||
"troubleshooting": {
|
"troubleshooting": {
|
||||||
"title": "Troubleshooting Issues",
|
"title": "Troubleshooting Issues",
|
||||||
"sidebar_label": "Troubleshooting Issues"
|
"sidebar_label": "Troubleshooting Issues"
|
||||||
|
},
|
||||||
|
"tutorial/android": {
|
||||||
|
"title": "Building an Android Plugin"
|
||||||
|
},
|
||||||
|
"tutorial/intro": {
|
||||||
|
"title": "Intro"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"links": {
|
"links": {
|
||||||
@@ -136,6 +142,7 @@
|
|||||||
"Advanced Usage": "Advanced Usage",
|
"Advanced Usage": "Advanced Usage",
|
||||||
"Extending Flipper": "Extending Flipper",
|
"Extending Flipper": "Extending Flipper",
|
||||||
"Plugin Development": "Plugin Development",
|
"Plugin Development": "Plugin Development",
|
||||||
|
"Tutorial": "Tutorial",
|
||||||
"Other Platforms": "Other Platforms",
|
"Other Platforms": "Other Platforms",
|
||||||
"Internals": "Internals"
|
"Internals": "Internals"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,10 @@
|
|||||||
"extending/testing",
|
"extending/testing",
|
||||||
"extending/debugging"
|
"extending/debugging"
|
||||||
],
|
],
|
||||||
|
"Tutorial": [
|
||||||
|
"tutorial/intro",
|
||||||
|
"tutorial/android"
|
||||||
|
],
|
||||||
"Other Platforms": [
|
"Other Platforms": [
|
||||||
"extending/new-clients",
|
"extending/new-clients",
|
||||||
"extending/establishing-a-connection",
|
"extending/establishing-a-connection",
|
||||||
|
|||||||
Reference in New Issue
Block a user