Pea*_*Gen 8 android http ios dart flutter
我正在开发一个具有网络活动的颤振应用程序。为了获取数据,我连接到一个REST API,这个 API 的速度很快。
有关更多信息,此 API 正在使用AWS API Gateway并AWS Lambda与其他 AWS 技术一起使用。
下面是我的代码,连接到网络。
class RoleService with ChangeNotifier {
NavLinks _navLinks = NavLinks();
late List<Role> _roles;
/// Get all Roles
Future<void> getAllRoles(String authToken) async {
try {
var data = await http.get(
Uri.parse("https://api2.example.com/userrel/roles/getall"),
headers: {HttpHeaders.authorizationHeader: "Bearer $authToken"},
);
var jsonData =
convert.json.decode(data.body).cast<Map<String, dynamic>>();
_roles = jsonData.map<Role>((json) => new Role.fromJson(json)).toList();
print(_roles);
} catch (error) {
print(error);
throw error;
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在下面看到postman上述API调用的性能。对于颤振测试,我使用华为 p30 Lite Android 手机。
然后,当我API在 flutter 中执行相同的调用时,这就是我得到的。
观察输出,postman我可以看到它缓存了 DNS 查找、TCP 握手和 SSL 握手。postman 在第一次调用 API 基本 URI 后执行此操作。然后从第二次开始,DNS 查找等会被缓存,从而在将来对同一基本 URI 的 API 调用中节省大量时间。
但在颤振中,“连接建立”时间很长,即使检索数据的时间只有几毫秒。
如何避免连接延迟并获得最大性能?如果缓存 SSL、DNS 查找等是解决方案,我该如何在 flutter 中做到这一点?
Pea*_*Gen 12
看来这个问题很多人都有。那么,让我回答我自己的问题。
flutter 能记住网络连接吗?是的,它可以。
Flutter 只需要对同一 API 进行一次网络调用即可记住连接。从第二次调用相同的 API 开始,它将使用其“缓存”内存,为您带来巨大的性能提升。
所以首先请记住,这只在您多次调用同一个 API 时才有效。如果您调用不同的 API,这将不起作用。然而,在许多应用程序中,您拥有由 API 团队构建的 API,并且您将调用应用程序的相同吞吐量。
解决方案是使用 flutter http.Client。然后分享同样的http.Client然后在您对同一 API 进行的调用中您将看到只有第一个呼叫需要时间进行“连接”,其余呼叫不需要该时间。
flutter http pub page中有一个示例。它说 ,
如果您向同一服务器发出多个请求,则可以使用客户端保持打开的持久连接,而不是发出一次性请求。如果您这样做,请确保完成后关闭客户端:
检查下面的例子。仅供参考,并非最佳使用方法。
主程序.dart
import 'package:flutter/material.dart';
import 'package:network_test/role_service.dart';
import 'package:network_test/user_role_service.dart';
import 'package:network_test/user_service.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var startTime = "";
var endTime = "";
void _network() async {
var client = http.Client();
RoleService _roleService = RoleService();
UserService _userService = UserService();
UserRoleService _userRoleService = UserRoleService();
String authToken = "****";
String uid = "555555";
try {
await _roleService.getAllRoles(authToken, client);
//await _roleService.getAllRoles(authToken, client);
await _userService.getUserByUID(authToken, uid, client);
await _userService.getUserByID(authToken, 27, client);
await _userRoleService.getUserRoleByUser(authToken, 27, client);
} finally {
client.close();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
"Start Time: " + startTime,
style: Theme.of(context).textTheme.headline4,
),
Text(
"End Time: " + endTime,
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _network,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
角色服务.dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http/http.dart';
import 'package:network_test/role.dart';
import 'dart:convert' as convert;
import 'dart:io';
class RoleService with ChangeNotifier {
late List<Role> _roles;
String link2 = "https://api2.somewhere.com/userrel";
/// Return roles
List<Role> returnRoles() {
return _roles;
}
/// Get all Roles
Future<void> getAllRoles(String authToken, Client client) async {
try {
var data = await client.get(Uri.parse(link2 + "/role/getall"),
headers: {HttpHeaders.authorizationHeader: "Bearer $authToken"});
var jsonData =
convert.json.decode(data.body).cast<Map<String, dynamic>>();
_roles = jsonData.map<Role>((json) => Role.fromJson(json)).toList();
print(_roles[0].roleName);
} catch (error) {
print(error);
throw error;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我告诉你上面不是最佳实践。为什么?因为你将http.Client在许多不同的地方创造和摧毁。让我们关注更好的实践。
几乎在每个应用程序中,我们都使用状态管理。我是 的粉丝Provider,它可以是你选择的任何东西。我想出最好的办法就是让状态管理记住.的创建http.Client。由于我正在使用Provider,我创建了以下类。
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
class ConnectionService with ChangeNotifier {
http.Client _client = http.Client();
http.Client returnConnection() {
return _client;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的主课
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => ConnectionService()),
],
child: MyApp(),
));
}
Run Code Online (Sandbox Code Playgroud)
现在,当应用程序打开时,我调用该类ConnectionService来建立连接并执行 API 调用,例如检查用户身份验证、用户访问权限等。只有第一个调用需要时间来建立连接,其他调用则不会。