Flutter插件flutter_alice的安装与使用指南
Flutter插件flutter_alice的安装与使用指南
Alice 是一个用于 Flutter 的 HTTP 检查工具,帮助调试 HTTP 请求。它捕获并存储 HTTP 请求和响应,可以通过简单的 UI 查看。
安装
1. 添加依赖到 pubspec.yaml
dependencies:
flutter_alice: ^1.0.1
2. 安装依赖
$ flutter pub get
3. 导入包
import 'package:flutter_alice/alice.dart';
使用方法
Alice 配置
创建 Alice 实例
Alice alice = Alice();
添加导航键到应用
MaterialApp(
navigatorKey: alice.getNavigatorKey(),
home: ...
)
你也可以使用自己的导航键:
Alice alice = Alice(navigatorKey: yourNavigatorKeyHere);
如果需要延迟传递导航键,可以使用:
alice.setNavigatorKey(yourNavigatorKeyHere);
其他设置
如果你想使用深色模式,只需添加 darkTheme
标志:
Alice alice = Alice(..., darkTheme: true);
HTTP 客户端配置
根据使用的 HTTP 客户端类型进行配置:
使用 Dio
Dio dio = Dio();
dio.interceptors.add(alice.getDioInterceptor());
使用 HttpClient (来自 dart:io 包)
httpClient
.getUrl(Uri.parse("https://jsonplaceholder.typicode.com/posts"))
.then((request) async {
alice.onHttpClientRequest(request);
var httpResponse = await request.close();
var responseBody = await httpResponse.transform(utf8.decoder).join();
alice.onHttpClientResponse(httpResponse, request, body: responseBody);
});
使用 http/http 包
http.get('https://jsonplaceholder.typicode.com/posts').then((response) {
alice.onHttpResponse(response);
});
使用 Chopper
chopper = ChopperClient(
interceptors: alice.getChopperInterceptor(),
);
使用其他 HTTP 客户端
你可以使用通用的 HTTP 调用接口:
AliceHttpCall aliceHttpCall = AliceHttpCall(id);
alice.addHttpCall(aliceHttpCall);
扩展
你可以使用扩展来缩短你的 HTTP 和 HTTP 客户端代码,这将使代码更加简洁。
导入扩展
import 'package:flutter_alice/core/alice_http_client_extensions.dart';
import 'package:flutter_alice/core/alice_http_extensions.dart';
使用扩展
http
.post('https://jsonplaceholder.typicode.com/posts', body: body)
.interceptWithAlice(alice, body: body);
httpClient
.postUrl(Uri.parse("https://jsonplaceholder.typicode.com/posts"))
.interceptWithAlice(alice, body: body, headers: Map());
示例 Demo
以下是一个完整的示例项目,展示了如何在 Flutter 应用中集成 flutter_alice
插件。
lib/main.dart
import 'dart:convert';
import 'dart:io';
import 'package:alice_example/posts_service.dart';
import 'package:chopper/chopper.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_alice/alice.dart';
import 'package:flutter_alice/core/alice_http_client_extensions.dart';
import 'package:flutter_alice/core/alice_http_extensions.dart';
import 'package:http/http.dart' as http;
import 'package:overlay_support/overlay_support.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late Alice _alice;
late Dio _dio;
late HttpClient _httpClient;
ChopperClient? _chopper;
late PostsService _postsService;
[@override](/user/override)
void initState() {
_alice = Alice(
showNotification: true,
showInspectorOnShake: true,
darkTheme: false,
);
_dio = Dio(BaseOptions(followRedirects: false));
_dio.interceptors.add(_alice.getDioInterceptor());
_httpClient = HttpClient();
_chopper = ChopperClient(
interceptors: _alice.getChopperInterceptor(),
);
_postsService = PostsService.create(_chopper);
super.initState();
}
[@override](/user/override)
Widget build(BuildContext context) {
return OverlaySupport(
child: MaterialApp(
theme: ThemeData(primarySwatch: Colors.blue),
navigatorKey: _alice.getNavigatorKey(),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: const Text('Alice HTTP Inspector - Example'),
),
body: Container(
padding: EdgeInsets.all(16),
child: ListView(
children: [
const SizedBox(height: 8),
_getTextWidget(
"Welcome to example of Alice Http Inspector. Click buttons below to generate sample data."),
ElevatedButton(
child: Text("Run Dio HTTP Requests"),
onPressed: _runDioRequests,
),
ElevatedButton(
child: Text("Run http/http HTTP Requests"),
onPressed: _runHttpHttpRequests,
),
ElevatedButton(
child: Text("Run HttpClient Requests"),
onPressed: _runHttpHttpClientRequests,
),
ElevatedButton(
child: Text("Run Chopper HTTP Requests"),
onPressed: _runChopperHttpRequests,
),
const SizedBox(height: 24),
_getTextWidget(
"After clicking on buttons above, you should receive notification."
" Click on it to show inspector. You can also shake your device or click button below."),
ElevatedButton(
child: Text("Run HTTP Insepctor"),
onPressed: _runHttpInspector,
),
ElevatedButton(
child: Text("test"),
onPressed: () {
_dio.interceptors.add(_alice.getDioInterceptor());
},
)
],
),
),
),
),
);
}
Widget _getTextWidget(String text) {
return Text(
text,
style: TextStyle(fontSize: 14),
textAlign: TextAlign.center,
);
}
void _runChopperHttpRequests() async {
Map<String, dynamic> body = {"title": "foo", "body": "bar", "userId": "1"};
_postsService.getPost("1");
_postsService.postPost(body);
_postsService.putPost("1", body);
_postsService.putPost("1231923", body);
_postsService.putPost("1", null);
_postsService.postPost(null);
_postsService.getPost("123456");
}
void _runDioRequests() async {
Map<String, dynamic> body = {"title": "foo", "body": "bar", "userId": "1"};
_dio.get("https://httpbin.org/redirect-to?url=https%3A%2F%2Fhttpbin.org");
_dio.delete("https://httpbin.org/status/500");
_dio.delete("https://httpbin.org/status/400");
_dio.delete("https://httpbin.org/status/300");
_dio.delete("https://httpbin.org/status/200");
_dio.delete("https://httpbin.org/status/100");
_dio.post("https://jsonplaceholder.typicode.com/posts", data: body);
_dio.get("https://jsonplaceholder.typicode.com/posts",
queryParameters: {"test": 1});
_dio.put("https://jsonplaceholder.typicode.com/posts/1", data: body);
_dio.put("https://jsonplaceholder.typicode.com/posts/1", data: body);
_dio.delete("https://jsonplaceholder.typicode.com/posts/1");
_dio.get("http://jsonplaceholder.typicode.com/test/test");
_dio.get("https://jsonplaceholder.typicode.com/photos");
_dio.get(
"https://icons.iconarchive.com/icons/paomedia/small-n-flat/256/sign-info-icon.png");
_dio.get(
"https://images.unsplash.com/photo-1542736705-53f0131d1e98?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&w=1000&q=80");
_dio.get(
"https://findicons.com/files/icons/1322/world_of_aqua_5/128/bluetooth.png");
_dio.get(
"https://upload.wikimedia.org/wikipedia/commons/4/4e/Pleiades_large.jpg");
_dio.get("http://techslides.com/demos/sample-videos/small.mp4");
_dio.get("https://www.cse.wustl.edu/~jain/cis677-97/ftp/e_3dlc2.pdf");
_dio.get("http://dummy.restapiexample.com/api/v1/employees");
}
void _runHttpHttpRequests() async {
Map<String, dynamic> body = {"title": "foo", "body": "bar", "userId": "1"};
http
.post(Uri.parse('https://jsonplaceholder.typicode.com/posts'),
body: body)
.interceptWithAlice(_alice, body: body);
http
.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'))
.interceptWithAlice(_alice);
http
.put(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'),
body: body)
.interceptWithAlice(_alice, body: body);
http
.patch(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'),
body: body)
.interceptWithAlice(_alice, body: body);
http
.delete(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'))
.interceptWithAlice(_alice, body: body);
http
.get(Uri.parse('https://jsonplaceholder.typicode.com/test/test'))
.interceptWithAlice(_alice);
http
.post(Uri.parse('https://jsonplaceholder.typicode.com/posts'),
body: body)
.then((response) {
_alice.onHttpResponse(response, body: body);
});
http
.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'))
.then((response) {
_alice.onHttpResponse(response);
});
http
.put(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'),
body: body)
.then((response) {
_alice.onHttpResponse(response, body: body);
});
http
.patch(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'),
body: body)
.then((response) {
_alice.onHttpResponse(response, body: body);
});
http
.delete(Uri.parse('https://jsonplaceholder.typicode.com/posts/1'))
.then((response) {
_alice.onHttpResponse(response);
});
http
.get(Uri.parse('https://jsonplaceholder.typicode.com/test/test'))
.then((response) {
_alice.onHttpResponse(response);
});
}
void _runHttpHttpClientRequests() {
Map<String, dynamic> body = {"title": "foo", "body": "bar", "userId": "1"};
_httpClient
.getUrl(Uri.parse("https://jsonplaceholder.typicode.com/posts"))
.interceptWithAlice(_alice);
_httpClient
.postUrl(Uri.parse("https://jsonplaceholder.typicode.com/posts"))
.interceptWithAlice(_alice, body: body, headers: Map());
_httpClient
.putUrl(Uri.parse("https://jsonplaceholder.typicode.com/posts/1"))
.interceptWithAlice(_alice, body: body);
_httpClient
.getUrl(Uri.parse("https://jsonplaceholder.typicode.com/test/test/"))
.interceptWithAlice(_alice);
_httpClient
.postUrl(Uri.parse("https://jsonplaceholder.typicode.com/posts"))
.then((request) async {
_alice.onHttpClientRequest(request, body: body);
request.write(body);
var httpResponse = await request.close();
var responseBody = await utf8.decoder.bind(httpResponse).join();
_alice.onHttpClientResponse(httpResponse, request, body: responseBody);
});
_httpClient
.putUrl(Uri.parse("https://jsonplaceholder.typicode.com/posts/1"))
.then((request) async {
_alice.onHttpClientRequest(request, body: body);
request.write(body);
var httpResponse = await request.close();
var responseBody = await utf8.decoder.bind(httpResponse).join();
_alice.onHttpClientResponse(httpResponse, request, body: responseBody);
});
_httpClient
.patchUrl(Uri.parse("https://jsonplaceholder.typicode.com/posts/1"))
.then((request) async {
_alice.onHttpClientRequest(request, body: body);
request.write(body);
var httpResponse = await request.close();
var responseBody = await utf8.decoder.bind(httpResponse).join();
_alice.onHttpClientResponse(httpResponse, request, body: responseBody);
});
_httpClient
.deleteUrl(Uri.parse("https://jsonplaceholder.typicode.com/posts/1"))
.then((request) async {
_alice.onHttpClientRequest(request);
var httpResponse = await request.close();
var responseBody = await utf8.decoder.bind(httpResponse).join();
_alice.onHttpClientResponse(httpResponse, request, body: responseBody);
});
_httpClient
.getUrl(Uri.parse("https://jsonplaceholder.typicode.com/test/test/"))
.then((request) async {
_alice.onHttpClientRequest(request);
var httpResponse = await request.close();
var responseBody = await utf8.decoder.bind(httpResponse).join();
_alice.onHttpClientResponse(httpResponse, request, body: responseBody);
});
}
void _runHttpInspector() {
_alice.showInspector();
}
}
更多关于Flutter插件flutter_alice的安装与使用指南的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter插件flutter_alice的安装与使用指南的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,针对您提到的Flutter功能未定义插件 flutter_alice
的问题,我们可以提供一个基本的集成和使用示例。假设 flutter_alice
是一个用于日志记录或调试的插件(请注意,这个假设基于插件名称的猜测,实际功能可能有所不同),以下是如何在Flutter项目中集成和使用该插件的示例代码。
首先,确保您已经在 pubspec.yaml
文件中添加了 flutter_alice
依赖项(请注意,您需要替换为实际的插件版本号和描述):
dependencies:
flutter:
sdk: flutter
flutter_alice: ^x.y.z # 替换为实际版本号
然后,运行 flutter pub get
来获取依赖项。
接下来,在您的 Flutter 应用中初始化并使用 flutter_alice
。以下是一个简单的示例,展示了如何配置和使用该插件进行日志记录:
import 'package:flutter/material.dart';
import 'package:flutter_alice/flutter_alice.dart';
void main() {
// 初始化 AliceClient,配置日志级别和其他选项
AliceClient.init(
enable: true, // 是否启用日志记录
level: AliceLevel.verbose, // 设置日志级别
output: AliceOutput.console, // 设置输出目标,例如控制台
// 可以添加更多配置,如文件输出、远程服务器等
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Alice Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
// 记录一个日志
Alice.log('App started');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Alice Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'0',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// 在按钮点击时记录一个日志
Alice.verbose('Button pressed');
// 这里可以添加其他逻辑,比如计数器增加
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
在这个示例中,我们做了以下几件事:
- 在
main
函数中初始化AliceClient
,并配置了日志级别和输出目标。 - 在
MyHomePage
的initState
方法中记录了一个启动日志。 - 在浮动按钮的
onPressed
回调中记录了一个按钮点击日志。
请注意,flutter_alice
是一个假设的插件名称,实际使用时您需要替换为真实存在的插件,并根据其文档进行配置和使用。如果 flutter_alice
插件不存在或功能不同,请参考该插件的实际文档进行调整。