我的规范很简单-我需要根据本地sqlite数据库中用户数量的值返回DeviceLoginPage()或RemoteLoginPage()。
这是我的app.dart ...
(app.dart)
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyApp',
initialRoute: '/login',
onGenerateRoute: _getRoute,
// Copy the platform from the main theme in order to support platform
// toggling from the Gallery options menu.
theme: _kShrineTheme.copyWith(platform: Theme.of(context).platform),
);
}
}
Route<dynamic> _getRoute(RouteSettings settings) {
debugPrint("Inside _getRoute()");
debugPrint("settings.name: " + settings.name);
if (settings.name == '/login') {
return MaterialPageRoute<void>(
settings: settings,
builder: (BuildContext context) => (AuthService().getLoginType() == LoginType.DEVICE.toString()) ?
DeviceLoginPage() : RemoteLoginPage(),
fullscreenDialog: true,
);
}
}
我检查我的用户表是否在我的authentication.dart AuthService.getLoginType()中包含任何用户
(authentication.dart)
abstract class BaseAuth {
Future<String> signIn(String email, String phone, String password);
Future<String> signUp(String email, String phone);
Future<void> signOut();
}
enum LoginType {
DEVICE,
REMOTE,
}
class AuthService implements BaseAuth {
DatabaseService _database = new DatabaseService();
...
Future<String> getLoginType() async {
print("Inside getLoginType()");
int usersCount = await _database.getUsersCount();
print("count in auth is:" + usersCount.toString());
print("Returning LoginType:" + (usersCount >=1 ? LoginType.DEVICE.toString() : LoginType.REMOTE.toString()));
return usersCount >=1 ? LoginType.DEVICE.toString() : LoginType.REMOTE.toString();
}
}
最后是我的database.dart文件
class DatabaseService {
static final DatabaseService _instance = DatabaseService.internal();
factory DatabaseService() => _instance;
Database _database;
Future<Database> get db async {
print("Inisde DatabaseService.get db");
if (_database != null) {
print("_database is not null");
return _database;
}
_database = await initDatabase();
return _database;
}
DatabaseService.internal();
initDatabase() async {
print("Inisde DatabaseService.initDatabase");
print("Here 1...");
Directory documentDirectory;
try {
print("About to run getApplicationDocumentsDirectory()...");
documentDirectory = await getApplicationDocumentsDirectory();
print("Got it: " + documentDirectory.toString());
} catch (ex) {
print("await getApplicationDocumentsDirectory() ERROR:" + ex.toString());
}
print("Here 2...");
String path = join(documentDirectory.path, "myapp.db");
print("Here 3...");
var ourDb = await openDatabase(path, version: 1, onCreate: _onCreate);
print("Here 4...");
print("ourDb is: " + ourDb.toString());
return ourDb;
}
void _onCreate(Database db, int version) async {
print("Running _onCreate()");
await db.execute(
"CREATE TABLE User(id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT, username TEXT, password TEXT)");
print("Table is created");
await db.rawInsert('INSERT INTO User(firstname,lastname,username,password) VALUES ("Anne","Suzanne","anne@gmail.com","anne")');
}
Future<int> getUsersCount() async {
final dbClient = await db;
var res = await dbClient.rawQuery('SELECT COUNT(*) FROM User');
int count = Sqflite.firstIntValue(res);
print("count is:" + count.toString());
return count;
}
}
问题是在应用程序启动时既未加载DeviceLoginPage()也未加载RemoteLoginPage()。相反,我得到了堆栈跟踪...
Syncing files to device TECNO P701...
I/flutter ( 9247): Inside _getRoute()
I/flutter ( 9247): settings.name: /
I/flutter ( 9247): Inside _getRoute()
I/flutter ( 9247): settings.name: /login
I/flutter ( 9247): ══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════
I/flutter ( 9247): The following message was thrown:
I/flutter ( 9247): Could not navigate to initial route.
I/flutter ( 9247): The requested route name was: "/login"
I/flutter ( 9247): The following routes were therefore attempted:
I/flutter ( 9247): * /
I/flutter ( 9247): * /login
I/flutter ( 9247): This resulted in the following objects:
I/flutter ( 9247): * null
I/flutter ( 9247): * MaterialPageRoute<Widget>(RouteSettings("/login", null), animation: null)
I/flutter ( 9247): One or more of those objects was null, and therefore the initial route specified will be ignored and
I/flutter ( 9247): "/" will be used instead.
I/flutter ( 9247): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter ( 9247): Inside _getRoute()
I/flutter ( 9247): settings.name: /
I/flutter ( 9247): Another exception was thrown: Could not find a generator for route RouteSettings("/", null) in the _WidgetsAppState.
D/OpenGLRenderer( 9247): ProgramCache.generateProgram: 34359738369
D/GraphicBuffer( 9247): register, handle(0xa42be7d0) (w:600 h:1024 s:608 f:0x1 u:0x000f02)
I/SurfaceView( 9247): updateWindow -- setFrame, this = io.flutter.view.FlutterView{5a56df6 VFED..... .F...... 0,0-600,960}
V/Activity( 9247): onPause com.techparadigms.mymandate.MainActivity@61099a0
V/Activity( 9247): onSaveInstanceState com.techparadigms.mymandate.MainActivity@61099a0: Bundle[{android:viewHierarchyState=Bundle[{android:views={16908290=android.view.AbsSavedState$1@1f17839}}]}]
D/SurfaceView( 9247): 94727670 windowPositionLostRT RT, frameNr = 0
V/Activity( 9247): onStop com.techparadigms.mymandate.MainActivity@61099a0
W/IInputConnectionWrapper( 9247): getExtractedText on inactive InputConnection
W/IInputConnectionWrapper( 9247): getTextBeforeCursor on inactive InputConnection
I/art ( 9247): Enter while loop.
I/art ( 9247): Enter while loop.
V/Activity( 9247): onStart com.techparadigms.mymandate.MainActivity@61099a0
V/Activity( 9247): onResume com.techparadigms.mymandate.MainActivity@61099a0
V/PhoneWindow( 9247): DecorView setVisiblity: visibility = 0, Parent = ViewRoot{fb27382 com.techparadigms.mymandate/com.techparadigms.mymandate.MainActivity,ident = 0}, this = DecorView@5a05959[MainActivity]
V/Activity( 9247): onPause com.techparadigms.mymandate.MainActivity@61099a0
V/Activity( 9247): onSaveInstanceState com.techparadigms.mymandate.MainActivity@61099a0: Bundle[{android:viewHierarchyState=Bundle[{android:views={16908290=android.view.AbsSavedState$1@1f17839}}]}]
V/Activity( 9247): onStop com.techparadigms.mymandate.MainActivity@61099a0
D/GraphicBuffer( 9247): register, handle(0x91551650) (w:600 h:960 s:608 f:0x1 u:0x000f02)
I/art ( 9247): Enter while loop.
仔细检查后,我发现一切正常,直到print("Here 1...");
中的诊断行initDatabase() async function (database.dart)
。似乎在这里暂停执行...不打印其他诊断行"Here 2...".
然后继续评估该行
builder: (BuildContext context) => (AuthService().getLoginType() == LoginType.DEVICE.toString()) ?
DeviceLoginPage() : LoginPage(),
找不到有效的路由,因为getLoginType()
返回空值。
我在Flutter中相对较新。到目前为止,我一直在使用在flutter_gallery_example中使用的onGenerateRoute()
示例……请问实现这一目标的最佳方法是什么?现在已经失去睡眠将近一个星期了...谢谢您的协助