Flutter平台接口代理插件platform_proxy的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter平台接口代理插件platform_proxy的使用

Flutter本身只支持有限的代理配置。我们可以通过设置系统环境变量如http_proxyhttps_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

1 回复

更多关于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上实现这些功能。

回到顶部