- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在使用 Flutter 构建一个简单的维基百科浏览器。由于没有原生的 Flutter Webview,我必须手动解析 HTML 片段并将其转换为等效的 Flutter 小部件。我设法做到了,但是在深入浏览了几页之后(通过单击蓝色链接),页面转换动画变得极其缓慢。
重现步骤:
添加如下依赖
dependencies:
flutter:
sdk: flutter
fluro: "^1.1.0"
html: "^0.13.2"
粘贴并运行以下代码(在 Release模式下以便更清楚地观察)。
import 'dart:async';
import 'dart:convert';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:fluro/fluro.dart';
import 'package:html/dom.dart' as DOM;
import 'package:html/parser.dart' show parse;
void main() {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
final router = new Router(); // Fluro router
@override
void initState() {
super.initState();
router.define(
'/wiki',
handler: new Handler(
handlerFunc: (_, params) => new WikiPage(title: params['q'])
)
);
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
onGenerateRoute: router.generator, // delegate to Fluro
routes: {
'/': (BuildContext context) => new WikiPage(title: 'Firefox')
},
);
}
}
class WikiPage extends StatefulWidget {
WikiPage({Key key, this.title}) : super(key: key);
final String title;
@override
_WikiPageState createState() => new _WikiPageState();
}
class _WikiPageState extends State<WikiPage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text(widget.title)),
body: new FutureBuilder<String>(
future: getPage(widget.title),
builder: (context, snapshot) {
if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
if (snapshot.hasData) {
if (snapshot.data.isEmpty) return new Container(); // empty result
// parse HTML
DOM.Document document = parse(snapshot.data);
document.querySelector('.infobox')?.remove(); // remove the infobox table
List<DOM.Element> paragraphs = document.getElementsByTagName('p');
// convert HTML tree to Flutter widgets
return new ListView(
padding: const EdgeInsets.all(16.0),
children: paragraphs.map((paragraph) =>
new RichText(
text: new TextSpan(
text: '',
style: DefaultTextStyle.of(context).style,
children: paragraph.nodes.map((node) {
if (node.toString() == '<html a>') { // HTML <a> tag
String href = node.attributes['href'];
return new TextSpan( // as blue link
text: node.text,
style: Theme.of(context).textTheme.body1.copyWith(
color: Colors.blue
),
recognizer: new TapGestureRecognizer()
..onTap = () => Navigator.of(context).pushNamed(
'/wiki?q=${href.split('/')[2]}'
)
);
} else {
return new TextSpan(text: node.text);
}
}).toList()
)
)
).toList()
);
} else { // waiting for data
return new Center(child: new CircularProgressIndicator());
}
},
)
);
}
Future<String> getPage(String title) async {
final String url = 'https://en.wikipedia.org/w/api.php?' +
'action=mobileview&format=json§ions=0&noimages=1&noheadings=1' +
'&formatversion=2&page=${Uri.encodeComponent(title)}';
final response = await http.get(url);
final json = JSON.decode(response.body);
return json['mobileview']['sections'][0]['text']; // retrieve HTML string
}
}
可能是什么问题?垃圾收集器问题?感谢您的帮助。
[√] Flutter (on Microsoft Windows [Version 10.0.15063], locale en-US, channel master)
• Flutter at C:\Users\tzm\Downloads\flutter_sdk
• Framework revision 6655074b37 (2 days ago), 2017-07-28 15:44:38 -0700
• Engine revision 232f4636e5
• Tools Dart version 1.25.0-dev.7.0
最佳答案
我找到了解决方案。诀窍是
maintainState
设置为 false
,以便始终从内存中丢弃之前的计算。缺点是我们需要在从当前页面弹出时重新生成以前访问过的页面。关于dart - 几页深后,页面转换变得非常缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45399495/
拿这个: var lists:{ item1:{} ,item2:{} ,item3:{} ,item4:{} } 由于它基本上是空的,我想要一个函数(可能但不一定是 _lodash
我想更改 ng bootstrap 分页组件的样式并在 Angular 6 应用程序中使用 /deep/ 链接。以下代码工作正常,但控制台显示警告,指出该代码已被弃用。 那么,我应该如何更改它以消除警
使用 webcomponents,您可以使用 /deep/ 定位 shadowdom 的内部元素,在我尝试使用事件委托(delegate)之前它工作正常。 一个常规的点击功能将起作用: $('html
在 Swift 中,我试图实现一个单词 Trie,使用文字表示作为一系列嵌套的 NSObject。这是 Trie。 let GEENITRIE:NSObject = [ "i":[
运行 npm update 更新 package.json 中列出的项目;但是,这些项目的依赖关系仍然过时。 明显的解决方法是再次运行 npm update。有时我需要运行它 3 次以上才能使 npm
我创建了 2 级嵌套 linq 查询: var data = (from p in Departments join e in Employees on p.Id equals
首先是代码 #include typedef wchar_t* BSTR; wchar_t hello[] = L"Hello"; class _bstr_t { public: opera
我要编写一个 lisp 程序来生成十六进制数的实际值。我已经编写了一个函数,但似乎出现了 stackoverflow(深度)错误。我想知道是否有人可以指出我的错误或指导我朝着正确的方向前进。 如果没有
我想将每种类型都转换为boolean 或object type CastDeep = { [P in keyof T]: K extends K[] ? K[] : T[P] ex
我刚刚发现自己在写这个: fn init_timestamps(dir: &PathBuf, file_timestamps: &'static HashMap) { match fs::re
我有一个现有的 pybind11::array_t,需要进行复制构造。 pybind11 中是否有一个函数允许我对 array_t 进行深度复制? 我知道我可以创建一个新的 array_t,适当调整大
引用http://www.devx.com/tips/Tip/13291 ,它说我可以使用 memcpy 来复制由 sizeof() 确定的大小,但是,数组不是指向指针吗? 除了遍历数组,如何使用 m
我有多个成员(member),每个成员(member)都有一条记录,其中包含几个备注字段: Member ID Entry A Entry B 1 [memo t
$watchCollection 是否能够忽略对以 $ 开头的属性的更改?使用深度 $watch 时已经存在此行为,因为它依赖于 angular.equals 进行比较。 理想情况下,$watchCo
我有一个带有复杂键的 map - 例如,二维数组: m := make(map[[2][3]int]int) 当我在映射中插入一个新键时,Go 是否会对该键进行深度复制? a := [2][3]int
我需要查询如下所述的三个表。我了解简单的 JOIN,但是这个有点超出我的水平。 courses 有两列 id (PK) 和 courseTitle(示例 id 1,courseTitle 物理) cl
我有一个对象,它是 Realm 的 Object 子类,并且符合 Codable 以便在与 API 对话时与 JSON 相互转换。 如何利用 Codable 协议(protocol)进行深度复制(包括
我是一名优秀的程序员,十分优秀!