當(dāng)前Flutter內(nèi)的請求數(shù)據(jù)都無法直接利用抓包工具直接抓取反惕,對測試造成了十分嚴(yán)重的困擾。下面說說如何解決Flutter模塊無法抓包這個問題演侯。
解決思路是這樣的:基于Flutter自帶的網(wǎng)絡(luò)框架與原生的網(wǎng)絡(luò)框架不通姿染,設(shè)置網(wǎng)絡(luò)代理時只能檢測到原生的網(wǎng)絡(luò),那么我們可以主動為Flutter網(wǎng)絡(luò)框架設(shè)置對應(yīng)的代理地址以獲取網(wǎng)絡(luò)請求數(shù)據(jù)秒际。
那么我們需要Native主動為Flutter端提供代理的地址悬赏。為此我們采用EventChannel的方式來傳遞兩端數(shù)據(jù)狡汉。
Native端
以iOS端為例:我們構(gòu)建一個UIAlertController用以輸入代理地址:
在Appdelegate里設(shè)置延遲2s執(zhí)行,保證flutter引擎已經(jīng)初始化闽颇。
#ifdef DEBUG
//延時處理盾戴,立即處理的話,引擎還沒有初始化完成
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC),dispatch_get_main_queue(), ^{
[self showFlutterDelegateAlertController];
});
#else
#endif
彈框代碼:
//設(shè)置Flutter代理彈框
- (void)showFlutterDelegateAlertController {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:@"輸入代理" preferredStyle:UIAlertControllerStyleAlert];
//增加取消按鈕兵多;
[alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}]];
//增加確定按鈕尖啡;
[alertController addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//獲取第1個輸入框;
UITextField *delegateField = alertController.textFields.firstObject;
if (delegateField.text.length>0){
//一下代碼為調(diào)取flutter端代碼
[PlatformRouterImp sharedRouter].nativeCallFlutterEventSink(delegateField.text);
}
}]];
//定義第一個輸入框中鼠;
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = @"(測試抓包專用可婶,不用輸端口)";
}];
[self.window.rootViewController presentViewController:alertController animated:true completion:nil];
}
PlatformRouterImp為自己封裝的一個兩端通信的類。只需設(shè)置FlutterViewController時先為其設(shè)置Eventchannel通道
- (void)setupNativeCallFlutter {
if (!self.flutterViewController) return;
// 用于Native調(diào)用Flutter
FlutterEventChannel *nativeCallFlutterChannel = [FlutterEventChannel eventChannelWithName:NativeCallFlutter binaryMessenger:self.flutterViewController];
[nativeCallFlutterChannel setStreamHandler:self];
}
設(shè)置完通道后設(shè)置數(shù)據(jù)監(jiān)聽函數(shù)
- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events
{
self.nativeCallFlutterEventSink = events;
return nil;
}
- (FlutterError*)onCancelWithArguments:(id)arguments {
//[[NSNotificationCenter defaultCenter] removeObserver:self];
NSLog(@"停止發(fā)送數(shù)據(jù)");
return nil;
}
Flutter端
在main函數(shù)里監(jiān)聽EventChannel數(shù)據(jù)流
static const EventChannel eventChannel =
EventChannel('samples.flutter.dev/nativeCallFlutter');
@override
void initState() {
super.initState();
eventChannel.receiveBroadcastStream().listen(_onEnvent, onError: _onError);
}
為網(wǎng)絡(luò)框架設(shè)置代理地址援雇,這里以dio為例
void _onEnvent(Object obj) {
setState(() {
print('接收到eventChannel:$obj');
//TODO:設(shè)置dio代理
Http2Client _client = Http2Client.getInstance();
(_client.getDio().httpClientAdapter as DefaultHttpClientAdapter)
.onHttpClientCreate = (HttpClient client) {
client.findProxy = (uri) {
//proxy all request to localhost:8888
print('設(shè)置了代理:PROXY $obj:8888');
return "PROXY $obj:8888";
};
client.badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
};
});
}
void _onError(Object obj) {
print('失斆省:$obj');
}
至此,可在原生界面為Flutter端設(shè)置網(wǎng)絡(luò)代理里惫搏。