概要

例えば以下のようなコードを準備して、画面に表示させようとすると、Connection refused, errno = 111になった。ホストOSのlocalhostに接続して欲しいのだが、Emulatorのlocalhostにコンテンツを取得しようとしている模様。

import 'dart:convert';

import 'package:myapp/entity/user.dart';
import 'package:http/http.dart' as http;

class APIClient {
  final baseUrl = 'http://localhost:3000';

  Future<User> fetchUser(String id) async {
    final response = await http.get(Uri.parse("$baseURL/users/$id"));

    if (response.statusCode == 200) {
      return User.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
    } else {
      throw Exception('Failed to load user');
    }
  }
}

解決方法

Android Emulatorのドキュメントを確認したところ、10.0.2.2 がホストOSのループバック インターフェース(127.0.0.1)へのエイリアスになっている。つまり、10.0.2.2 -> 10.0.2.1 -> 127.0.0.1 のように通信してくれるらしい(10.0.2.1はEmulatorのゲートウェイアドレス)。

baseUrlを以下のように修正して解決した。

final baseUrl = 'http://10.0.2.2:3000';