Contents
事象:Chromeでは起動できるのにAndroidエミュレーターでは起動できない
バックエンドとしてDjango Rest APIを実装し、DBのデータを取得できるようにしました。
起動するデバイスとしてWeb-serverやChromeを選択すればDBデータを取得できるのですが、アンドロイドエミュレーターで実行しようとすると、アプリの枠は表示されるのにDBデータが取得できていません。
エラー内容
1 2 3 4 5 6 7 8 |
Launching lib\main.dart on Android SDK built for x86 in debug mode... lib\main.dart:1 √ Built build\app\outputs\flutter-apk\app-debug.apk. Connecting to VM Service at ws://127.0.0.1:52541/0xSvxXwueFQ=/ws I/flutter ( 5749): Connection refused E/flutter ( 5749): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: NoSuchMethodError: The getter 'length' was called on null. E/flutter ( 5749): Receiver: null E/flutter ( 5749): Tried calling: length |
接続拒否されてレスポンスのlengthがnullだからエラーになっています。
本来は、ボタンだけでなくDBデータが表示されるはずです。
原因:web-serverとandroidでlocalhostの値が違う
URLの127.0.0.1:8000の部分を10.0.2.2:8000に変更すると、起動できます。
バックエンド側のallowed hostの値も変更する必要があります。
以下がDjangoのsettings.pyの設定
1 2 3 4 5 6 |
CORS_ORIGIN_WHITELIST = [ "http://localhost:8000", "http://127.0.0.1:8000", "http://10.0.2.2:8000", ] ALLOWED_HOSTS = ['localhost','127.0.0.1', '10.0.2.2'] |
恒久対応:ローカルホストを自分のIPアドレスにする
Djangoをrunserverするときに、0.0.0.0を指定します。これで現在の自分のIPアドレスで起動されます。
1 |
python manage.py runserver 0.0.0.0:8000 |
ブラウザからAPIの結果を確認したい場合は、ipconfigで自分のIPアドレスを確認してから、http://自分のIPアドレス:8000にアクセスします。
Flutter上のURLも、自分のIPアドレスに変更します。Terminalに表示しているのは「ipconfig」の結果です。
これで、Android、Chrome(web-server)どちらで実行しても結果が表示されるようになりました。
おまけ:ポート番号の指定
なお、Flutterをポートを指定せずに実行すると、毎回ポート番号が自動採番されてそのたびにDjangoのCORS_ORIGIN_WHITELISTを直さなければならなくなるので、launch.jsonを以下のように変更しています
1 2 3 4 5 6 7 8 9 10 |
"configurations": [ { "name": "flutter_frontend", "request": "launch", "type": "dart", "args": ["-d", "emulator-5554","--web-port", "8000"], //追加 }, ・ ・ ・ |
emulator-5554はデバイスIDで、「flutter devices」というコマンドで調べることができます。
このように設定しておくことで、Ctrl+F5する度にアンドロイド端末、ポート8000で起動されます。