Flutter平台接口代理插件platform_proxy的使用
Flutter平台接口代理插件platform_proxy的使用
Flutter本身只支持有限的代理配置。我们可以通过设置系统环境变量如http_proxy
、https_proxy
等来实现。如果没有定义这些变量,HTTP请求将绕过系统的代理配置。
这个插件platform_proxy
旨在解决这个问题。
代理配置矩阵
不同的操作系统提供不同的代理配置选项。下表尝试代表这些选项。如果有遗漏,请指出。
OS | 手动 | 手动 +凭据 | 手动 +绕行 | 自动代理配置 (PAC) |
---|---|---|---|---|
Android | ✓ | ✗ | ✓ | ✓ |
iOS | ✓ | ✓ | ✓ | ✓ |
Windows | ✓ | ✗ | ✓ | ✓ |
Mac OS | ✓ | ✓ | ✓ | ✓ |
Linux | in_progress | in_progress | in_progress | in_progress |
platform_proxy插件支持的内容
下表表示从“代理配置矩阵”中支持的配置选项。
OS | 手动 | 手动 +凭据 | 手动 +绕行 | 自动代理配置 (Pac) |
---|---|---|---|---|
Android | ✓ | ✗ | ✓ | ✓ |
iOS | ✓ | ✓ | ✓ | ✓ |
Windows | ✓ | ✗ | ✓ | ✓ |
Mac OS | ✓ | ✓ | ✓ | ✓ |
Linux | in_progress | in_progress | in_progress | in_progress |
开始使用
目前工作仍在进行中。Dart SDK本身存在一个问题,这阻碍了对系统代理配置的简单集成。
PlatformProxy
类实例提供了针对给定URL启用的Proxy
列表。
是的,我们需要为每个请求的URL获取正确的代理配置,即使系统已经配置了代理也不意味着该代理已启用(例如,绕行选项和PAC)。
然后,需要通过findProxy
方法提供代理配置。此方法支持扩展的PAC
字符串(原生版本不支持凭据)。为了简化这一点,插件有一个扩展功能,可以将Iterable<Proxy>
转换为带有或不带凭据的PAC字符串:
var platformProxy = PlatformProxy();
var proxies = await _platformProxy.getPlatformProxies(url: "your url");
var pacString = proxies.getProxiesAsPac();
or
var pacString = proxies.pacStringWithCredentials();
不幸的是,findProxy
方法是同步的,我们不允许在那里使用await
。在该问题得到解决之前,您可以尝试使用ProxyAwareHttpClient
来预取代理配置,然后再发出实际请求。
final client = ProxyAwareHttpClient(client: HttpClient(), platformProxy: PlatformProxy());
client.getUrl(Uri.parse('https://flutter.dev')).then((value) => value.close()).then((value) {};
示例代码
import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:platform_proxy/platform_proxy.dart';
import 'package:platform_proxy/proxy_httpclient.dart';
void main() {
// WidgetsFlutterBinding.ensureInitialized();
// HttpOverrides.global = PlatformProxyHttpOverrides(PlatformProxy());
runApp(MyApp());
}
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
final client = ProxyAwareHttpClient(client: HttpClient(), platformProxy: PlatformProxy());
[@override](/user/override)
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
String platformVersion;
try {
platformVersion = (await PlatformProxy().getPlatformProxies(url: "https://google.com")).getProxiesAsPac();
client.getUrl(Uri.parse('http://platform.proxy.io')).then((value) => value.close()).then((value) {});
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const SelectableText('Plugin example app'),
),
body: Center(
child: Column(children:[TextButton(child: Text("Send"), onPressed: () {
client.getUrl(Uri.parse('https://google.com')).then((value) => value.close());
}), SelectableText('Running on: $_platformVersion\n')]),
),
),
);
}
}
更多关于Flutter平台接口代理插件platform_proxy的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter平台接口代理插件platform_proxy的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,platform_proxy
插件允许开发者在不同平台上(如iOS和Android)代理平台特定的接口调用。虽然Flutter本身提供了强大的跨平台能力,但有时候你可能需要访问特定平台的API,这时候platform_proxy
就显得非常有用。
以下是一个简单的示例,展示如何使用platform_proxy
插件在Flutter中调用平台特定的代码。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加platform_proxy
依赖:
dependencies:
flutter:
sdk: flutter
platform_proxy: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来获取依赖。
2. 创建平台通道
接下来,你需要为iOS和Android分别创建平台通道。
iOS部分
在ios/Runner/AppDelegate.swift
中,添加以下代码来处理平台通道:
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: "com.example.platform_proxy_channel", binaryMessenger: controller)
channel.setMethodCallHandler {
(call: FlutterMethodCall, result: @escaping FlutterResult) in
if call.method == "platformSpecificFunction" {
// 在这里实现你的平台特定功能
result("Hello from iOS")
} else {
result(FlutterMethodNotImplemented)
}
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Android部分
在android/app/src/main/kotlin/com/yourapp/MainActivity.kt
(如果你使用的是Kotlin)中添加以下代码:
package com.yourapp
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
private val CHANNEL = "com.example.platform_proxy_channel"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "platformSpecificFunction") {
// 在这里实现你的平台特定功能
result.success("Hello from Android")
} else {
result.notImplemented()
}
}
}
}
3. 在Dart代码中调用平台特定功能
现在,你可以在你的Flutter Dart代码中通过platform_proxy
(或更常见的MethodChannel
)来调用这些平台特定的功能。不过,由于platform_proxy
本质上是对MethodChannel
的一个封装,我们直接展示如何使用MethodChannel
来调用:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
static const platform = MethodChannel('com.example.platform_proxy_channel');
String _platformVersion = 'Unknown';
@override
void initState() {
super.initState();
_getPlatformVersion();
}
Future<void> _getPlatformVersion() async {
String version;
try {
version = await platform.invokeMethod('platformSpecificFunction');
} on PlatformException catch (e) {
version = 'Failed to get platform version: '${e.message}..';
}
setState(() {
_platformVersion = version;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Platform Proxy Example'),
),
body: Center(
child: Text('Platform version: $_platformVersion\n'),
),
),
);
}
}
在这个示例中,我们创建了一个MethodChannel
,并在Flutter的initState
方法中调用invokeMethod
来获取平台特定的消息。
总结
虽然platform_proxy
插件可能提供了更高层次的抽象,但直接使用MethodChannel
同样可以实现平台特定功能的调用。上述代码展示了如何在Flutter应用中通过MethodChannel
与原生代码进行通信,并展示了如何在iOS和Android上实现这些功能。