diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1b9a2ec
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+.DS_Store
+.dart_tool/
+.idea
+
+.packages
+.pub/
+
+build/
+.flutter-plugins
diff --git a/.metadata b/.metadata
new file mode 100644
index 0000000..cae5295
--- /dev/null
+++ b/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: bbfbf1770cca2da7c82e887e4e4af910034800b6
+ channel: stable
+
+project_type: plugin
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..dfe237f
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,20 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Flutter: Attach to Device",
+ "type": "dart",
+ "request": "attach",
+ "program": "example/lib/main.dart"
+ },
+ {
+ "name": "Flutter",
+ "program": "example/lib/main.dart",
+ "request": "launch",
+ "type": "dart"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..41cc7d8
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.0.1
+
+* TODO: Describe initial release.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ba75c69
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+TODO: Add your license here.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..623ce94
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+# g_faraday
+
+## 快速集成
+
+### 创建一个 flutter module 项目
+
+```
+flutter create -t module #{your_project_name}
+
+```
+
+### 在module目录下创建一个 flutter plugin 项目
+
+```
+cd #{your_project_name}
+
+flutter create -t plugin --platforms ios,android faraday_helper
+
+```
+
+### 在flutter module项目中依赖g_faraday
+```
+```
diff --git a/android/.gitignore b/android/.gitignore
new file mode 100644
index 0000000..c6cbe56
--- /dev/null
+++ b/android/.gitignore
@@ -0,0 +1,8 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
diff --git a/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
new file mode 100644
index 0000000..5ae5d55
--- /dev/null
+++ b/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
@@ -0,0 +1,25 @@
+package io.flutter.plugins;
+
+import io.flutter.plugin.common.PluginRegistry;
+import com.yuxiaor.flutter.g_faraday.GFaradayPlugin;
+
+/**
+ * Generated file. Do not edit.
+ */
+public final class GeneratedPluginRegistrant {
+ public static void registerWith(PluginRegistry registry) {
+ if (alreadyRegisteredWith(registry)) {
+ return;
+ }
+ GFaradayPlugin.registerWith(registry.registrarFor("com.yuxiaor.flutter.g_faraday.GFaradayPlugin"));
+ }
+
+ private static boolean alreadyRegisteredWith(PluginRegistry registry) {
+ final String key = GeneratedPluginRegistrant.class.getCanonicalName();
+ if (registry.hasPlugin(key)) {
+ return true;
+ }
+ registry.registrarFor(key);
+ return false;
+ }
+}
diff --git a/android/build.gradle b/android/build.gradle
new file mode 100644
index 0000000..768358c
--- /dev/null
+++ b/android/build.gradle
@@ -0,0 +1,43 @@
+group 'com.yuxiaor.flutter.g_faraday'
+version '1.0-SNAPSHOT'
+
+buildscript {
+ ext.kotlin_version = '1.3.72'
+ repositories {
+ google()
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:4.0.1'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ }
+}
+
+rootProject.allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+
+android {
+ compileSdkVersion 28
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+ defaultConfig {
+ minSdkVersion 16
+ }
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
diff --git a/android/gradle.properties b/android/gradle.properties
new file mode 100644
index 0000000..38c8d45
--- /dev/null
+++ b/android/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx1536M
+android.enableR8=true
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..01a286e
--- /dev/null
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
diff --git a/android/settings.gradle b/android/settings.gradle
new file mode 100644
index 0000000..a877076
--- /dev/null
+++ b/android/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'g_faraday'
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..9340104
--- /dev/null
+++ b/android/src/main/AndroidManifest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/Faraday.kt b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/Faraday.kt
new file mode 100644
index 0000000..05c3618
--- /dev/null
+++ b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/Faraday.kt
@@ -0,0 +1,158 @@
+package com.yuxiaor.flutter.g_faraday
+
+import android.app.Activity
+import android.content.Intent
+import androidx.fragment.app.FragmentActivity
+import com.yuxiaor.flutter.g_faraday.delegates.DefaultNavigatorDelegate
+import com.yuxiaor.flutter.g_faraday.delegates.FaradayNavigator
+import com.yuxiaor.flutter.g_faraday.plugins.ActivityAwarePlugin
+import com.yuxiaor.flutter.g_faraday.plugins.ResultListener
+import com.yuxiaor.flutter.g_faraday.utils.NativeContextProvider
+import com.yuxiaor.flutter.g_faraday.utils.getArgs
+import com.yuxiaor.flutter.g_faraday.utils.getFlutterArgs
+import com.yuxiaor.flutter.g_faraday.utils.startForResult
+import io.flutter.embedding.engine.FlutterEngine
+import io.flutter.embedding.engine.dart.DartExecutor
+import io.flutter.embedding.engine.plugins.FlutterPlugin
+import java.io.Serializable
+import java.util.concurrent.atomic.AtomicInteger
+
+/**
+ * Author: Edward
+ * Date: 2020-08-31
+ * Description:
+ */
+object Faraday {
+
+ //native -> flutter intent args key
+ internal const val FLUTTER_ARGS_KEY = "_flutter_args_key"
+ const val ARGS_KEY = "_args_key_"
+ private val nextCode = AtomicInteger()
+ var navigator: FaradayNavigator? = null
+
+ private val activityAwarePlugin = ActivityAwarePlugin()
+ private val faradayPlugin = GFaradayPlugin()
+
+ @JvmStatic
+ val engine by lazy { FlutterEngine(NativeContextProvider.context) }
+
+ @JvmStatic
+ fun startFlutterEngine(navigatorDelegate: FaradayNavigator? = null) {
+ this.navigator = navigatorDelegate ?: DefaultNavigatorDelegate()
+ //注册插件
+ registerPlugin(faradayPlugin)
+ registerPlugin(activityAwarePlugin)
+ //开始执行dart代码,启动引擎
+ engine.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())
+ }
+
+ @JvmStatic
+ fun registerPlugin(plugin: FlutterPlugin) {
+ engine.plugins.add(plugin)
+ }
+
+ @JvmStatic
+ fun getCurrentActivity(): Activity? {
+ return activityAwarePlugin.binding?.activity
+ }
+
+ /**
+ * When jumped to native page form a flutter page with args,this method is provided to get the args.
+ * Or you can also call [Intent.getFlutterArgs()] to get args if you are using kotlin.
+ */
+ @JvmStatic
+ fun getFlutterArgs(intent: Intent): Serializable? {
+ return intent.getFlutterArgs()
+ }
+
+
+ @JvmStatic
+ fun openFlutter(activity: FragmentActivity, url: String, vararg params: Pair, onActivityResult: ((data: HashMap?) -> Unit)? = null) {
+ activity.openFlutter(url, *params) {
+ onActivityResult?.invoke(it)
+ }
+ }
+
+ @JvmStatic
+ fun openFlutter(activity: Activity, url: String, vararg params: Pair) {
+ activity.openFlutter(url, *params)
+ }
+
+ @JvmStatic
+ fun openFlutter(activity: Activity, url: String, requestCode: Int, vararg params: Pair) {
+ activity.openFlutter(url, requestCode, *params)
+ }
+
+ internal fun openActivityForResult(intent: Intent, callback: (result: HashMap?) -> Unit) {
+ val nextRequestCode = nextCode.getAndIncrement()
+ getCurrentActivity()?.startActivityForResult(intent, nextRequestCode)
+ ResultListener(activityAwarePlugin) { requestCode, resultCode, data ->
+ if (requestCode == nextRequestCode && resultCode == Activity.RESULT_OK) {
+ callback.invoke(data?.getArgs())
+ }
+ }
+ }
+
+
+ internal fun onPageCreate(args: Any?, callback: (seqId: Int) -> Unit) {
+ faradayPlugin.onPageCreate(args, callback)
+ }
+
+ internal fun onPageShow(seqId: Int) {
+ faradayPlugin.onPageShow(seqId)
+ }
+
+ internal fun onPageHidden(seqId: Int) {
+ faradayPlugin.onPageHidden(seqId)
+ }
+
+ internal fun onPageDealloc(seqId: Int) {
+ faradayPlugin.onPageDealloc(seqId)
+ }
+}
+
+
+/**
+ * Native to flutter
+ * @param url flutter router
+ * @param params params from native to flutter
+ * @param onActivityResult callback for Activity Result
+ */
+fun FragmentActivity.openFlutter(url: String, vararg params: Pair, onActivityResult: ((data: HashMap?) -> Unit)? = null) {
+ val args = hashMapOf(*params).apply { this["name"] = url }
+ val intent = Intent(this, FaradayActivity::class.java).putExtra(Faraday.FLUTTER_ARGS_KEY, args)
+ startForResult(intent) { resultCode, data ->
+ if (resultCode == Activity.RESULT_OK) {
+ onActivityResult?.invoke(data?.getArgs())
+ }
+ }
+}
+
+
+/**
+ * Native to flutter
+ * @param url flutter router
+ * @param params params from native to flutter
+ *
+ * no Activity result
+ */
+fun Activity.openFlutter(url: String, vararg params: Pair) {
+ val args = hashMapOf(*params).apply { this["name"] = url }
+ val intent = Intent(this, FaradayActivity::class.java).putExtra(Faraday.FLUTTER_ARGS_KEY, args)
+ startActivity(intent)
+}
+
+
+/**
+ * Native to flutter
+ * @param url flutter router
+ * @param params params from native to flutter
+ *
+ * you need to override [onActivityResult] in your Activity to get the result
+ */
+fun Activity.openFlutter(url: String, requestCode: Int, vararg params: Pair) {
+ val args = hashMapOf(*params).apply { this["name"] = url }
+ val intent = Intent(this, FaradayActivity::class.java).putExtra(Faraday.FLUTTER_ARGS_KEY, args)
+ startActivityForResult(intent, requestCode)
+}
+
diff --git a/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/FaradayActivity.kt b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/FaradayActivity.kt
new file mode 100644
index 0000000..fee3911
--- /dev/null
+++ b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/FaradayActivity.kt
@@ -0,0 +1,48 @@
+package com.yuxiaor.flutter.g_faraday
+
+import android.content.Context
+import android.os.Bundle
+import io.flutter.embedding.android.FlutterActivity
+import io.flutter.embedding.engine.FlutterEngine
+
+/**
+ * Author: Edward
+ * Date: 2020-09-01
+ * Description:
+ */
+class FaradayActivity : FlutterActivity() {
+
+ private var seqId = 0
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ //native -> flutter args
+ val args = intent.getSerializableExtra(Faraday.FLUTTER_ARGS_KEY)
+ Faraday.onPageCreate(args) {
+ seqId = it
+ }
+ }
+
+ override fun provideFlutterEngine(context: Context): FlutterEngine? {
+ return Faraday.engine
+ }
+
+ override fun onResume() {
+ super.onResume()
+ Faraday.onPageShow(seqId)
+ }
+
+
+ override fun onPause() {
+ super.onPause()
+ Faraday.onPageHidden(seqId)
+
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ Faraday.onPageDealloc(seqId)
+ }
+
+
+}
\ No newline at end of file
diff --git a/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/FaradayFragment.kt b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/FaradayFragment.kt
new file mode 100644
index 0000000..79ae33b
--- /dev/null
+++ b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/FaradayFragment.kt
@@ -0,0 +1,66 @@
+package com.yuxiaor.flutter.g_faraday
+
+import android.content.Context
+import android.os.Bundle
+import io.flutter.embedding.android.FlutterFragment
+import io.flutter.embedding.engine.FlutterEngine
+
+/**
+ * Author: Edward
+ * Date: 2020-09-07
+ * Description:
+ */
+class FaradayFragment private constructor() : FlutterFragment() {
+
+ private var seqId = 0
+
+
+ companion object {
+
+ @JvmStatic
+ fun newInstance(route: String, vararg params: Pair): FaradayFragment {
+ val args = hashMapOf(*params).apply { this["name"] = route }
+ val bundle = Bundle().apply { putSerializable(Faraday.FLUTTER_ARGS_KEY, args) }
+ return FaradayFragment().apply { arguments = bundle }
+ }
+ }
+
+
+ override fun provideFlutterEngine(context: Context): FlutterEngine? {
+ return Faraday.engine
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val args = arguments?.getSerializable(Faraday.FLUTTER_ARGS_KEY)
+ Faraday.onPageCreate(args) {
+ seqId = it
+ }
+ }
+
+
+ override fun onHiddenChanged(hidden: Boolean) {
+ super.onHiddenChanged(hidden)
+ if (!hidden) {
+ Faraday.onPageShow(seqId)
+ } else {
+ Faraday.onPageHidden(seqId)
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ Faraday.onPageShow(seqId)
+ }
+
+ override fun onPause() {
+ super.onPause()
+ Faraday.onPageHidden(seqId)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ Faraday.onPageDealloc(seqId)
+ }
+
+}
\ No newline at end of file
diff --git a/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/GFaradayPlugin.kt b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/GFaradayPlugin.kt
new file mode 100644
index 0000000..d22e4fc
--- /dev/null
+++ b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/GFaradayPlugin.kt
@@ -0,0 +1,95 @@
+package com.yuxiaor.flutter.g_faraday
+
+import androidx.annotation.NonNull
+import io.flutter.embedding.engine.plugins.FlutterPlugin
+import io.flutter.plugin.common.MethodCall
+import io.flutter.plugin.common.MethodChannel
+import io.flutter.plugin.common.MethodChannel.MethodCallHandler
+import io.flutter.plugin.common.MethodChannel.Result
+import io.flutter.plugin.common.PluginRegistry.Registrar
+import java.io.Serializable
+
+/** GFaradayPlugin */
+class GFaradayPlugin : FlutterPlugin, MethodCallHandler {
+ private var channel: MethodChannel? = null
+
+ companion object {
+ @JvmStatic
+ fun registerWith(registrar: Registrar) {
+ val channel = MethodChannel(registrar.messenger(), "g_faraday")
+ channel.setMethodCallHandler(GFaradayPlugin())
+
+ }
+ }
+
+ override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
+ channel = MethodChannel(flutterPluginBinding.flutterEngine.dartExecutor, "g_faraday")
+ channel?.setMethodCallHandler(this)
+ }
+
+
+ override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
+ when (call.method) {
+ "getPlatformVersion" -> result.success("Android ${android.os.Build.VERSION.RELEASE}")
+ "pushNativePage" -> {
+ val name = call.argument("name")
+ require(name != null) { "page route name should not be null" }
+ Faraday.navigator?.push(name, call.argument("arguments")) { result.success(it) }
+ }
+ "popContainer" -> {
+ val arg = call.arguments
+ Faraday.navigator?.pop(arg as? Serializable)
+ if (arg != null && arg !is Serializable) {
+ print("=========返回值丢失,返回值类型 $arg")
+ }
+ result.success(null)
+ }
+ "disableHorizontalSwipePopGesture" -> {
+ val disable = call.arguments as? Boolean ?: false
+ print(if (!disable) "enable" else "disable" + " Horizontal Swipe PopGesture")
+ result.success(null)
+ }
+ else -> result.notImplemented()
+ }
+ }
+
+ fun onPageCreate(args: Any?, callback: (seqId: Int) -> Unit) {
+ channel?.invoke("pageCreate", args) {
+ val seqId = it as Int
+ callback.invoke(seqId)
+ }
+ }
+
+ fun onPageShow(seqId: Int) {
+ channel?.invokeMethod("pageShow", seqId)
+ }
+
+ fun onPageHidden(seqId: Int) {
+ channel?.invokeMethod("pageHidden", seqId)
+ }
+
+ fun onPageDealloc(seqId: Int) {
+ channel?.invokeMethod("pageDealloc", seqId)
+ }
+
+
+ override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
+ channel?.setMethodCallHandler(null)
+ }
+
+
+ private fun MethodChannel.invoke(method: String, arguments: Any?, callback: ((result: Any?) -> Unit)? = null) {
+ invokeMethod(method, arguments, object : Result {
+
+ override fun notImplemented() {
+ }
+
+ override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?) {
+ }
+
+ override fun success(result: Any?) {
+ callback?.invoke(result)
+ }
+ })
+ }
+}
diff --git a/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/delegates/DefaultNavigatorDelegate.kt b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/delegates/DefaultNavigatorDelegate.kt
new file mode 100644
index 0000000..4c0ca25
--- /dev/null
+++ b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/delegates/DefaultNavigatorDelegate.kt
@@ -0,0 +1,46 @@
+package com.yuxiaor.flutter.g_faraday.delegates
+
+import android.app.Activity
+import android.content.Intent
+import android.net.Uri
+import com.yuxiaor.flutter.g_faraday.Faraday
+import java.io.Serializable
+
+/**
+ * Author: Edward
+ * Date: 2020-09-02
+ * Description:
+ */
+
+/**
+ * Default Navigator Delegate
+ */
+class DefaultNavigatorDelegate : FaradayNavigator {
+
+ /**
+ * Open native page
+ * @param name route name
+ * @param arguments data from flutter page to native page
+ * @param callback onActivityResult callback
+ */
+ override fun push(name: String, arguments: Serializable?, callback: (result: HashMap?) -> Unit) {
+ val intent = Intent(Intent.ACTION_VIEW)
+ intent.data = Uri.parse(name)
+ intent.putExtra(Faraday.ARGS_KEY, arguments)
+ Faraday.openActivityForResult(intent, callback)
+ }
+
+ /**
+ * Close container Activity when flutter pops the last page
+ * @param result data from flutter to native
+ */
+ override fun pop(result: Serializable?) {
+ val activity = Faraday.getCurrentActivity() ?: return
+ if (result != null) {
+ activity.setResult(Activity.RESULT_OK, Intent().apply { putExtra(Faraday.ARGS_KEY, result) })
+ }
+ activity.finish()
+ }
+
+}
+
diff --git a/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/delegates/FaradayNavigator.kt b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/delegates/FaradayNavigator.kt
new file mode 100644
index 0000000..f87a782
--- /dev/null
+++ b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/delegates/FaradayNavigator.kt
@@ -0,0 +1,16 @@
+package com.yuxiaor.flutter.g_faraday.delegates
+
+import java.io.Serializable
+
+/**
+ * Author: Edward
+ * Date: 2020-09-02
+ * Description:
+ */
+
+interface FaradayNavigator {
+
+ fun push(name: String, arguments: Serializable?, callback: (result: HashMap?) -> Unit)
+
+ fun pop(result: Serializable?)
+}
diff --git a/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/plugins/ActivityAwarePlugin.kt b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/plugins/ActivityAwarePlugin.kt
new file mode 100644
index 0000000..8356468
--- /dev/null
+++ b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/plugins/ActivityAwarePlugin.kt
@@ -0,0 +1,58 @@
+package com.yuxiaor.flutter.g_faraday.plugins
+
+import android.content.Intent
+import io.flutter.embedding.engine.plugins.FlutterPlugin
+import io.flutter.embedding.engine.plugins.activity.ActivityAware
+import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
+import io.flutter.plugin.common.PluginRegistry
+
+/**
+ * Author: Edward
+ * Date: 2020-08-31
+ * Description:
+ */
+class ActivityAwarePlugin : FlutterPlugin, ActivityAware {
+
+ var binding: ActivityPluginBinding? = null
+
+ override fun onAttachedToActivity(binding: ActivityPluginBinding) {
+ this.binding = binding
+ }
+
+ override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
+ }
+
+ override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
+ }
+
+ override fun onDetachedFromActivity() {
+ }
+
+ override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
+ }
+
+ override fun onDetachedFromActivityForConfigChanges() {
+ }
+
+ fun addActivityResultListener(listener: PluginRegistry.ActivityResultListener) {
+ binding?.addActivityResultListener(listener)
+ }
+
+ fun removeActivityResultListener(listener: PluginRegistry.ActivityResultListener) {
+ binding?.removeActivityResultListener(listener)
+ }
+}
+
+
+class ResultListener(private val activityAwarePlugin: ActivityAwarePlugin, private val callback: (requestCode: Int, resultCode: Int, data: Intent?) -> Unit) : PluginRegistry.ActivityResultListener {
+
+ init {
+ activityAwarePlugin.addActivityResultListener(this)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
+ callback.invoke(requestCode, resultCode, data)
+ activityAwarePlugin.removeActivityResultListener(this)
+ return false
+ }
+}
\ No newline at end of file
diff --git a/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/utils/IntentExt.kt b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/utils/IntentExt.kt
new file mode 100644
index 0000000..a3eda04
--- /dev/null
+++ b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/utils/IntentExt.kt
@@ -0,0 +1,66 @@
+package com.yuxiaor.flutter.g_faraday.utils
+
+import android.content.Intent
+import android.os.Bundle
+import android.os.Parcelable
+import com.yuxiaor.flutter.g_faraday.Faraday
+import java.io.Serializable
+
+/**
+ * Author: Edward
+ * Date: 2020-09-02
+ * Description:
+ */
+fun Intent.fillArgs(params: Array>): Intent {
+ params.forEach {
+ when (val value = it.second) {
+ null -> putExtra(it.first, null as? Serializable?)
+ is Int -> putExtra(it.first, value)
+ is Long -> putExtra(it.first, value)
+ is CharSequence -> putExtra(it.first, value)
+ is String -> putExtra(it.first, value)
+ is Float -> putExtra(it.first, value)
+ is Double -> putExtra(it.first, value)
+ is Char -> putExtra(it.first, value)
+ is Short -> putExtra(it.first, value)
+ is Boolean -> putExtra(it.first, value)
+ is Serializable -> putExtra(it.first, value)
+ is Bundle -> putExtra(it.first, value)
+ is Parcelable -> putExtra(it.first, value)
+ is Array<*> -> when {
+ value.isArrayOf() -> putExtra(it.first, value)
+ value.isArrayOf() -> putExtra(it.first, value)
+ value.isArrayOf() -> putExtra(it.first, value)
+ else -> throw Exception("Intent extra ${it.first} has wrong type ${value.javaClass.name}")
+ }
+ is IntArray -> putExtra(it.first, value)
+ is LongArray -> putExtra(it.first, value)
+ is FloatArray -> putExtra(it.first, value)
+ is DoubleArray -> putExtra(it.first, value)
+ is CharArray -> putExtra(it.first, value)
+ is ShortArray -> putExtra(it.first, value)
+ is BooleanArray -> putExtra(it.first, value)
+ else -> throw Exception("Intent extra ${it.first} has wrong type ${value.javaClass.name}")
+ }
+ }
+ return this
+}
+
+/**
+ * 获取Intent携带的所有数据
+ */
+fun Intent.getArgs(): HashMap {
+ val map = hashMapOf()
+ extras?.keySet()?.forEach {
+ map[it] = extras?.get(it)
+ }
+ return map
+}
+
+
+/**
+ * 从flutter页面传给原生页面的数据
+ */
+fun Intent.getFlutterArgs(): Serializable? {
+ return getSerializableExtra(Faraday.ARGS_KEY)
+}
\ No newline at end of file
diff --git a/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/utils/NativeContextProvider.kt b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/utils/NativeContextProvider.kt
new file mode 100644
index 0000000..241bdc0
--- /dev/null
+++ b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/utils/NativeContextProvider.kt
@@ -0,0 +1,45 @@
+package com.yuxiaor.flutter.g_faraday.utils
+
+import android.app.Application
+import android.content.ContentProvider
+import android.content.ContentValues
+import android.database.Cursor
+import android.net.Uri
+
+/**
+ * Author: Edward
+ * Date: 2019-08-13
+ * Description:
+ */
+class NativeContextProvider : ContentProvider() {
+
+ companion object {
+ lateinit var context: Application
+ }
+
+ override fun onCreate(): Boolean {
+ val app = context as Application
+ NativeContextProvider.context = app
+ return true
+ }
+
+ override fun insert(uri: Uri, values: ContentValues?): Uri? {
+ return null
+ }
+
+ override fun query(uri: Uri, projection: Array?, selection: String?, selectionArgs: Array?, sortOrder: String?): Cursor? {
+ return null
+ }
+
+ override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array?): Int {
+ return 0
+ }
+
+ override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int {
+ return 0
+ }
+
+ override fun getType(uri: Uri): String? {
+ return null
+ }
+}
\ No newline at end of file
diff --git a/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/utils/ResultHelper.kt b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/utils/ResultHelper.kt
new file mode 100644
index 0000000..c3ad716
--- /dev/null
+++ b/android/src/main/kotlin/com/yuxiaor/flutter/g_faraday/utils/ResultHelper.kt
@@ -0,0 +1,64 @@
+package com.yuxiaor.flutter.g_faraday.utils
+
+import android.content.Intent
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentActivity
+import java.util.concurrent.atomic.AtomicInteger
+
+/**
+ * Author: Edward
+ * Date: 2020-09-02
+ * Description:
+ */
+
+/**
+ * Start Activity for result with args.
+ */
+inline fun FragmentActivity.startForResult(vararg param: Pair, noinline callback: (resultCode: Int, data: Intent?) -> Unit) {
+ startForResult(Intent(this, T::class.java).fillArgs(param), callback)
+}
+
+/**
+ * Start Activity for result with Intent
+ */
+fun FragmentActivity.startForResult(intent: Intent, callback: (resultCode: Int, data: Intent?) -> Unit) {
+ ResultFragment.get(this).startForResult(intent, callback)
+}
+
+
+internal class ResultFragment private constructor() : Fragment() {
+
+ companion object {
+ private const val TAG = "ResultFragment"
+ fun get(activity: FragmentActivity): ResultFragment {
+ val manager = activity.supportFragmentManager
+ var fragment = manager.findFragmentByTag(TAG)
+ if (fragment == null) {
+ fragment = ResultFragment()
+ manager.beginTransaction().add(fragment, TAG).commitAllowingStateLoss()
+ manager.executePendingTransactions()
+ }
+ return fragment as ResultFragment
+ }
+ }
+
+ private val nextLocalRequestCode = AtomicInteger()
+ private val resultMap = mutableMapOf Unit>()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ retainInstance = true
+ }
+
+ fun startForResult(intent: Intent, listener: (Int, Intent?) -> Unit) {
+ val requestCode = nextLocalRequestCode.getAndIncrement()
+ resultMap[requestCode] = listener
+ startActivityForResult(intent, requestCode)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ val listener = resultMap.remove(requestCode)
+ listener?.invoke(resultCode, data)
+ }
+}
\ No newline at end of file
diff --git a/example/.gitignore b/example/.gitignore
new file mode 100644
index 0000000..f3c2053
--- /dev/null
+++ b/example/.gitignore
@@ -0,0 +1,44 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Web related
+lib/generated_plugin_registrant.dart
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Exceptions to above rules.
+!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
diff --git a/example/.metadata b/example/.metadata
new file mode 100644
index 0000000..bcef94e
--- /dev/null
+++ b/example/.metadata
@@ -0,0 +1,10 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: bbfbf1770cca2da7c82e887e4e4af910034800b6
+ channel: stable
+
+project_type: app
diff --git a/example/README.md b/example/README.md
new file mode 100644
index 0000000..2b91535
--- /dev/null
+++ b/example/README.md
@@ -0,0 +1,16 @@
+# g_faraday_example
+
+Demonstrates how to use the g_faraday plugin.
+
+## Getting Started
+
+This project is a starting point for a Flutter application.
+
+A few resources to get you started if this is your first Flutter project:
+
+- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
+- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
+
+For help getting started with Flutter, view our
+[online documentation](https://flutter.dev/docs), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
diff --git a/example/android/.gitignore b/example/android/.gitignore
new file mode 100644
index 0000000..0a741cb
--- /dev/null
+++ b/example/android/.gitignore
@@ -0,0 +1,11 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+key.properties
diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle
new file mode 100644
index 0000000..3dc5a4f
--- /dev/null
+++ b/example/android/app/build.gradle
@@ -0,0 +1,51 @@
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterRoot = localProperties.getProperty('flutter.sdk')
+if (flutterRoot == null) {
+ throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
+}
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
+
+android {
+ compileSdkVersion 28
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+
+ lintOptions {
+ disable 'InvalidPackage'
+ }
+
+ defaultConfig {
+ applicationId "com.yuxiaor.flutter.g_faraday_example"
+ minSdkVersion 23
+ targetSdkVersion 28
+ versionCode 1
+ versionName "1.0"
+ }
+
+ buildTypes {
+ release {
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+}
diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000..346d3af
--- /dev/null
+++ b/example/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a029935
--- /dev/null
+++ b/example/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/example/android/app/src/main/kotlin/com/yuxiaor/flutter/g_faraday_example/App.kt b/example/android/app/src/main/kotlin/com/yuxiaor/flutter/g_faraday_example/App.kt
new file mode 100644
index 0000000..173bcc7
--- /dev/null
+++ b/example/android/app/src/main/kotlin/com/yuxiaor/flutter/g_faraday_example/App.kt
@@ -0,0 +1,18 @@
+package com.yuxiaor.flutter.g_faraday_example
+
+import android.app.Application
+import com.yuxiaor.flutter.g_faraday.Faraday
+
+/**
+ * Author: Edward
+ * Date: 2020-09-02
+ * Description:
+ */
+class App : Application() {
+
+
+ override fun onCreate() {
+ super.onCreate()
+ Faraday.startFlutterEngine()
+ }
+}
\ No newline at end of file
diff --git a/example/android/app/src/main/kotlin/com/yuxiaor/flutter/g_faraday_example/FirstActivity.kt b/example/android/app/src/main/kotlin/com/yuxiaor/flutter/g_faraday_example/FirstActivity.kt
new file mode 100644
index 0000000..76604eb
--- /dev/null
+++ b/example/android/app/src/main/kotlin/com/yuxiaor/flutter/g_faraday_example/FirstActivity.kt
@@ -0,0 +1,44 @@
+package com.yuxiaor.flutter.g_faraday_example
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.widget.Button
+import android.widget.TextView
+import androidx.appcompat.app.AppCompatActivity
+import com.yuxiaor.flutter.g_faraday.openFlutter
+import com.yuxiaor.flutter.g_faraday.utils.getFlutterArgs
+
+/**
+ * Author: Edward
+ * Date: 2020-09-03
+ * Description:
+ */
+class FirstActivity : AppCompatActivity() {
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+ val infoTxt = findViewById(R.id.infoTxt)
+ val btn1 = findViewById