提交 b273d1ad 编写于 作者: M Mikkel Nygaard Ravn 提交者: GitHub

Android plugin registry (#3641)

上级 33ee0a50
...@@ -90,6 +90,7 @@ java_library("flutter_shell_java") { ...@@ -90,6 +90,7 @@ java_library("flutter_shell_java") {
"io/flutter/plugin/common/MethodCall.java", "io/flutter/plugin/common/MethodCall.java",
"io/flutter/plugin/common/MethodChannel.java", "io/flutter/plugin/common/MethodChannel.java",
"io/flutter/plugin/common/MethodCodec.java", "io/flutter/plugin/common/MethodCodec.java",
"io/flutter/plugin/common/PluginRegistry.java",
"io/flutter/plugin/common/StandardMessageCodec.java", "io/flutter/plugin/common/StandardMessageCodec.java",
"io/flutter/plugin/common/StandardMethodCodec.java", "io/flutter/plugin/common/StandardMethodCodec.java",
"io/flutter/plugin/common/StringCodec.java", "io/flutter/plugin/common/StringCodec.java",
......
...@@ -10,16 +10,27 @@ import android.os.Build; ...@@ -10,16 +10,27 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import io.flutter.plugin.platform.PlatformPlugin; import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.view.FlutterMain; import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterView; import io.flutter.view.FlutterView;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/** /**
* Base class for activities that use Flutter. * Base class for activities that use Flutter.
*/ */
public class FlutterActivity extends Activity { public class FlutterActivity extends Activity implements PluginRegistry {
private final Map<String, Object> pluginMap = new LinkedHashMap<>(0);
private final List<RequestPermissionResultListener> requestPermissionResultListeners = new ArrayList<>(0);
private final List<ActivityResultListener> activityResultListeners = new ArrayList<>(0);
private final List<NewIntentListener> newIntentListeners = new ArrayList<>(0);
private final List<UserLeaveHintListener> userLeaveHintListeners = new ArrayList<>(0);
private FlutterView flutterView; private FlutterView flutterView;
private String[] getArgsFromIntent(Intent intent) { private String[] getArgsFromIntent(Intent intent) {
...@@ -68,6 +79,26 @@ public class FlutterActivity extends Activity { ...@@ -68,6 +79,26 @@ public class FlutterActivity extends Activity {
onFlutterReady(); onFlutterReady();
} }
@Override
public boolean hasPlugin(String key) {
return pluginMap.containsKey(key);
}
@Override
@SuppressWarnings("unchecked")
public <T> T valuePublishedByPlugin(String pluginKey) {
return (T) pluginMap.get(pluginKey);
}
@Override
public Registrar registrarFor(String pluginKey) {
if (pluginMap.containsKey(pluginKey)) {
throw new IllegalStateException("Plugin key " + pluginKey + " is already in use");
}
pluginMap.put(pluginKey, null);
return new FlutterRegistrar(pluginKey);
}
/** /**
* @see android.app.Activity#onDestroy() * @see android.app.Activity#onDestroy()
*/ */
...@@ -118,8 +149,39 @@ public class FlutterActivity extends Activity { ...@@ -118,8 +149,39 @@ public class FlutterActivity extends Activity {
} }
} }
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
for (RequestPermissionResultListener listener : requestPermissionResultListeners) {
if (listener.onRequestPermissionResult(requestCode, permissions, grantResults)) {
return;
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
for (ActivityResultListener listener : activityResultListeners) {
if (listener.onActivityResult(requestCode, resultCode, data)) {
return;
}
}
}
@Override
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
loadIntent(intent); if (!loadIntent(intent)) {
for (NewIntentListener listener : newIntentListeners) {
if (listener.onNewIntent(intent)) {
return;
}
}
}
}
@Override
public void onUserLeaveHint() {
for (UserLeaveHintListener listener : userLeaveHintListeners) {
listener.onUserLeaveHint();
}
} }
public boolean loadIntent(Intent intent) { public boolean loadIntent(Intent intent) {
...@@ -159,4 +221,58 @@ public class FlutterActivity extends Activity { ...@@ -159,4 +221,58 @@ public class FlutterActivity extends Activity {
if (level == TRIM_MEMORY_RUNNING_LOW) if (level == TRIM_MEMORY_RUNNING_LOW)
flutterView.onMemoryPressure(); flutterView.onMemoryPressure();
} }
private class FlutterRegistrar implements Registrar {
private final String pluginKey;
FlutterRegistrar(String pluginKey) {
this.pluginKey = pluginKey;
}
public Activity activity() {
return FlutterActivity.this;
}
public BinaryMessenger messenger() {
return getFlutterView();
}
/**
* Publishes a value associated with the plugin being registered.
*
* <p>The published value is available to interested clients via
* {@link PluginRegistry#valuePublishedByPlugin(String)}.</p>
*
* <p>Publication should be done only when there is an interesting value
* to be shared with other code. This would typically be an instance of
* the plugin's main class itself that must be wired up to receive
* notifications or events from an Android API.
*
* <p>Overwrites any previously published value.</p>
*/
public Registrar publish(Object value) {
pluginMap.put(pluginKey, value);
return this;
}
public Registrar addRequestPermissionResultListener(RequestPermissionResultListener listener) {
requestPermissionResultListeners.add(listener);
return this;
}
public Registrar addActivityResultListener(ActivityResultListener listener) {
activityResultListeners.add(listener);
return this;
}
public Registrar addNewIntentListener(NewIntentListener listener) {
newIntentListeners.add(listener);
return this;
}
public Registrar addUserLeaveHintListener(UserLeaveHintListener listener) {
userLeaveHintListeners.add(listener);
return this;
}
};
} }
// Copyright 2017 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.
package io.flutter.plugin.common;
import android.app.Activity;
import android.content.Intent;
/**
* Registry used by plugins to set up interaction with Android APIs.
*
* <p>Flutter applications by default include an auto-generated and auto-updated
* plugin registrant class (GeneratedPluginRegistrant) that makes use of a
* {@link PluginRegistry} to register contributions from each plugin mentioned
* in the application's pubspec file. The generated registrant class is, again
* by default, called from the application's main {@link Activity}, which
* defaults to an instance of {@link io.flutter.app.FlutterActivity}, itself a
* {@link PluginRegistry}.</p>
*/
public interface PluginRegistry {
/**
* Returns a {@link Registrar} for receiving the registrations pertaining
* to the specified plugin.
*
* @param pluginKey a unique String identifying the plugin; typically the
* fully qualified name of the plugin's main class.
*/
Registrar registrarFor(String pluginKey);
/**
* Returns whether the specified plugin is known to this registry.
*
* @param pluginKey a unique String identifying the plugin; typically the
* fully qualified name of the plugin's main class.
* @return true if this registry has handed out a registrar for the
* specified plugin.
*/
boolean hasPlugin(String pluginKey);
/**
* Returns the value published by the specified plugin, if any.
*
* <p>Plugins may publish a single value, such as an instance of the
* plugin's main class, for situations where external control or
* interaction is needed. Clients are expected to know the value's
* type.</p>
*
* @param pluginKey a unique String identifying the plugin; typically the
* fully qualified name of the plugin's main class.
* @return the published value, possibly null.
*/
<T> T valuePublishedByPlugin(String pluginKey);
/**
* Receiver of registrations from a single plugin.
*/
interface Registrar {
/**
* Returns the {@link Activity} that forms the plugin's operating context.
*/
Activity activity();
/**
* Returns a {@link BinaryMessenger} which the plugin can use for
* creating channels for communicating with the Dart side.
*/
BinaryMessenger messenger();
/**
* Publishes a value associated with the plugin being registered.
*
* <p>The published value is available to interested clients via
* {@link PluginRegistry#valuePublishedByPlugin(String)}.</p>
*
* <p>Publication should be done only when client code needs to interact
* with the plugin in a way that cannot be accomplished by the plugin
* registering callbacks with client APIs.</p>
*
* <p>Overwrites any previously published value.</p>
*
* @param value the value, possibly null.
* @return this {@link Registrar}.
*/
Registrar publish(Object value);
/**
* Adds a callback allowing the plugin to take part in handling incoming
* calls to {@Activity#onRequestPermissionsResult(int, String[], int[])}
* or {android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback#onRequestPermissionsResult(int, String[], int[])}.
*
* @param listener a {@link RequestPermissionResultListener} callback.
* @return this {@link Registrar}.
*/
Registrar addRequestPermissionResultListener(RequestPermissionResultListener listener);
/**
* Adds a callback allowing the plugin to take part in handling incoming
* calls to {@Activity#onActivityResult(int, int, Intent)}.
*
* @param listener an {@link ActivityResultListener} callback.
* @return this {@link Registrar}.
*/
Registrar addActivityResultListener(ActivityResultListener listener);
/**
* Adds a callback allowing the plugin to take part in handling incoming
* calls to {@Activity#onNewIntent(Intent)}.
*
* @param listener a {@link NewIntentListener} callback.
* @return this {@link Registrar}.
*/
Registrar addNewIntentListener(NewIntentListener listener);
/**
* Adds a callback allowing the plugin to take part in handling incoming
* calls to {@Activity#onUserLeaveHint()}.
*
* @param listener a {@link UserLeaveHintListener} callback.
* @return this {@link Registrar}.
*/
Registrar addUserLeaveHintListener(UserLeaveHintListener listener);
}
/**
* Delegate interface for handling results of permission requests on
* behalf of the main {@link Activity}.
*/
interface RequestPermissionResultListener {
/**
* @return true if the result has been handled.
*/
boolean onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults);
}
/**
* Delegate interface for handling activity results on behalf of the main
* {@link Activity}.
*/
interface ActivityResultListener {
/**
* @return true if the result has been handled.
*/
boolean onActivityResult(int requestCode, int resultCode, Intent data);
}
/**
* Delegate interface for handling new intents on behalf of the main
* {@link Activity}.
*/
interface NewIntentListener {
/**
* @return true if the new intent has been handled.
*/
boolean onNewIntent(Intent intent);
}
/**
* Delegate interface for handling user leave hints on behalf of the main
* {@link Activity}.
*/
interface UserLeaveHintListener {
void onUserLeaveHint();
}
}
...@@ -1427,6 +1427,7 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/MessageCo ...@@ -1427,6 +1427,7 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/MessageCo
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/MethodCall.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/MethodCall.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/MethodChannel.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/MethodChannel.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/MethodCodec.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/MethodCodec.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/PluginRegistry.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StandardMessageCodec.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StandardMessageCodec.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StandardMethodCodec.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StandardMethodCodec.java
FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StringCodec.java FILE: ../../../flutter/shell/platform/android/io/flutter/plugin/common/StringCodec.java
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册