You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Android应用无法连接本地Node.js API问题求助

Flutter Android应用无法连接本地Node.js API问题

错误信息

I/flutter ( 4159): Error: SocketException: Connection refused (OS Error: Connection refused, errno = 111), address = localhost, port = 39394

Android编译提示

Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

问题说明

  • iOS端可正常连接本地Node.js API,Android端无法连接,已授予应用网络权限
  • Android应用启动时出现上述编译警告,但可正常启动

相关代码

product.dart

import 'package:fiyatfind/constants/animation.dart';
import 'package:fiyatfind/constants/colors.dart';
import 'package:fiyatfind/constants/size.dart';
import 'package:fiyatfind/services/product_service.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class ProductScreen extends StatefulWidget {
  final String barcode;
  const ProductScreen({super.key, required this.barcode});

  @override
  State<ProductScreen> createState() => _ProductScreenState();
}

class _ProductScreenState extends State<ProductScreen> {
  late ProductService productService;
  late Future<void> productFuture;
  @override
  void initState() {
    super.initState();
    productService = Get.put(
        ProductService()); // initState içinde ProductService'yi başlatıyoruz
    productFuture = getProduct();
  }

  Future<void> getProduct() async {
    await productService.getProduct(widget.barcode);
    if (kDebugMode) {
      print("çalıştı");
    }
  }

  @override
  Widget build(BuildContext context) {
    final width = MediaQuery.of(context).size.width;
    return Scaffold(
        appBar: AppBar(
          automaticallyImplyLeading: false,
          elevation: 0,
          backgroundColor: Colors.transparent,
          title: Padding(
            padding: const EdgeInsets.only(left: 10),
            child: Row(
              children: [
                CircleAvatar(
                  radius: 25,
                  backgroundColor: MyColor.fadeTuruncu,
                  child: IconButton(
                    splashColor: Colors.transparent,
                    highlightColor: Colors.transparent,
                    onPressed: () {
                      Get.back();
                    },
                    icon: const Icon(
                      Icons.arrow_back_ios_new,
                      color: MyColor.turuncu,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
        body: FutureBuilder(
            future: productFuture,
            builder: (context, snapshot) {
              if (snapshot.hasError) {
                return const Center(child: Text("Beklenmeyen bir hata oluştu"));
              } else if (snapshot.connectionState == ConnectionState.waiting) {
                return Center(child: AnimationProvider.animation());
              } else {
                return productService.products.isEmpty
                    ? Center(
                        child: Text(
                        "Ürün bulunamadı",
                        style: TextStyle(
                            fontSize: FontSize.setBigSize(width),
                            color: MyColor.turuncu),
                      ))
                    : ListView.builder(
                        itemCount: productService.products.length,
                        itemBuilder: (context, index) {
                          return Column(
                            children: [
                              Padding(
                                  padding: EdgeInsets.symmetric(
                                      vertical: PaddingSize.setBigSize(width),
                                      horizontal:
                                          PaddingSize.setNormalSize(width)),
                                  child: productService.products[index].resim ==
                                          null
                                      ? Image.asset(
                                          "assets/images/noimage.png",
                                          width: width * 0.5,
                                        )
                                      : Image.network(
                                          productService.products[index].resim,
                                          width: width * 0.75)),
                              Stack(
                                children: [
                                  Container(
                                    padding: EdgeInsets.only(
                                        bottom:
                                            PaddingSize.setNormalSize(width)),
                                    width: width * 0.8,
                                    decoration: BoxDecoration(
                                        color: MyColor.koyuGri,
                                        borderRadius:
                                            BorderRadius.circular(20)),
                                    child: Padding(
                                      padding: EdgeInsets.symmetric(
                                          horizontal:
                                              PaddingSize.setNormalSize(width)),
                                      child: Column(
                                        children: [
                                          const SizedBox(
                                            height: 30,
                                          ),
                                          Text(
                                            productService
                                                .products[index].brandName,
                                            style: TextStyle(
                                                fontSize:
                                                    FontSize.setBigSize(width),
                                                color: Colors.white,
                                                fontWeight: FontWeight.bold),
                                          ),
                                          Padding(
                                            padding: EdgeInsets.only(
                                                top: PaddingSize.setNormalSize(
                                                    width)),
                                            child: Row(
                                              mainAxisAlignment:
                                                  MainAxisAlignment
                                                      .spaceBetween,
                                              children: [
                                                Text(
                                                  "Fiyat 1:",
                                                  style: TextStyle(
                                                      fontSize: FontSize
                                                          .setNotNormalNotBig(
                                                              width),
                                                      color: MyColor.turuncu,
                                                      fontWeight:
                                                          FontWeight.bold),
                                                ),
                                                Text(
                                                  productService.products[index]
                                                              .satisFiyati ==
                                                          null
                                                      ? "Fiyat Bilinmiyor"
                                                      : "${productService.products[index].satisFiyati} TL",
                                                  style: TextStyle(
                                                      fontSize: FontSize
                                                          .setNotNormalNotBig(
                                                              width),
                                                      color: Colors.white,
                                                      fontWeight:
                                                          FontWeight.bold),
                                                ),
                                              ],
                                            ),
                                          ),
                                          Padding(
                                            padding: EdgeInsets.only(
                                                top: PaddingSize.setSmallSize(
                                                    width)),
                                            child: Row(
                                              mainAxisAlignment:
                                                  MainAxisAlignment
                                                      .spaceBetween,
                                              children: [
                                                Text(
                                                  "Fiyat 2:",
                                                  style: TextStyle(
                                                      fontSize: FontSize
                                                          .setNotNormalNotBig(
                                                              width),
                                                      color: MyColor.turuncu,
                                                      fontWeight:
                                                          FontWeight.bold),
                                                ),
                                                Text(
                                                  productService.products[index]
                                                              .satisFiyati2 ==
                                                          null
                                                      ? "Fiyat Bilinmiyor"
                                                      : "${productService.products[index].satisFiyati2} TL",
                                                  style: TextStyle(
                                                      fontSize: FontSize
                                                          .setNotNormalNotBig(
                                                              width),
                                                      color: Colors.white,
                                                      fontWeight:
                                                          FontWeight.bold),
                                                ),
                                              ],
                                            ),
                                          ),
                                          Padding(
                                            padding: EdgeInsets.only(
                                                top: PaddingSize.setSmallSize(
                                                    width)),
                                            child: Row(
                                              mainAxisAlignment:
                                                  MainAxisAlignment
                                                      .spaceBetween,
                                              children: [
                                                Text(
                                                  "Fiyat 3:",
                                                  style: TextStyle(
                                                      fontSize: FontSize
                                                          .setNotNormalNotBig(
                                                              width),
                                                      color: MyColor.turuncu,
                                                      fontWeight:
                                                          FontWeight.bold),
                                                ),
                                                Text(
                                                  productService.products[index]
                                                              .satisFiyati3 ==
                                                          null
                                                      ? "Fiyat Bilinmiyor"
                                                      : "${productService.products[index].satisFiyati3} TL",
                                                  style: TextStyle(
                                                      fontSize: FontSize
                                                          .setNotNormalNotBig(
                                                              width),
                                                      color: Colors.white,
                                                      fontWeight:
                                                          FontWeight.bold),
                                                ),
                                              ],
                                            ),
                                          ),
                                          Padding(
                                            padding: EdgeInsets.only(
                                                top: PaddingSize.setSmallSize(
                                                    width)),
                                            child: Row(
                                              mainAxisAlignment:
                                                  MainAxisAlignment
                                                      .spaceBetween,
                                              children: [
                                                Text(
                                                  "Taksitli Fiyat:",
                                                  style: TextStyle(
                                                      fontSize: FontSize
                                                          .setNotNormalNotBig(
                                                              width),
                                                      color: MyColor.turuncu,
                                                      fontWeight:
                                                          FontWeight.bold),
                                                ),
                                                Text(
                                                  productService.products[index]
                                                              .taksitliFiyat ==
                                                          null
                                                      ? "Fiyat Bilinmiyor"
                                                      : "${productService.products[index].taksitliFiyat} TL",
                                                  style: TextStyle(
                                                      fontSize: FontSize
                                                          .setNotNormalNotBig(
                                                              width),
                                                      color: Colors.white,
                                                      fontWeight:
                                                          FontWeight.bold),
                                                ),
                                              ],
                                            ),
                                          ),
                                          Padding(
                                            padding: EdgeInsets.only(
                                                top: PaddingSize.setSmallSize(
                                                    width)),
                                            child: Row(
                                              mainAxisAlignment:
                                                  MainAxisAlignment
                                                      .spaceBetween,
                                              children: [
                                                Text(
                                                  "Stok Miktarı",
                                                  style: TextStyle(
                                                      fontSize: FontSize
                                                          .setNotNormalNotBig(
                                                              width),
                                                      color: MyColor.turuncu,
                                                      fontWeight:
                                                          FontWeight.bold),
                                                ),
                                                Text(
                                                  productService.products[index]
                                                              .onHand ==
                                                          null
                                                      ? "Stok Bilinmiyor"
                                                      : "${productService.products[index].onHand} ${productService.products[index].unit}",
                                                  style: TextStyle(
                                                      fontSize: FontSize
                                                          .setNotNormalNotBig(
                                                              width),
                                                      color: Colors.white,
                                                      fontWeight:
                                                          FontWeight.bold),
                                                ),
                                              ],
                                            ),
                                          ),
                                          Padding(
                                            padding: EdgeInsets.only(
                                                top: PaddingSize.setNormalSize(
                                                    width)),
                                            child: SizedBox(
                                              width: width,
                                              child: Column(
                                                crossAxisAlignment:
                                                    CrossAxisAlignment.start,
                                                children: [
                                                  Text("Tedarikçi Firma",
                                                      textAlign: TextAlign.left,
                                                      style: TextStyle(
                                                          fontSize: FontSize
                                                              .setNotNormalNotBig(
                                                                  width),
                                                          color:
                                                              MyColor.turuncu,
                                                          fontWeight:
                                                              FontWeight.bold)),
                                                  Padding(
                                                    padding: EdgeInsets.only(
                                                        top: PaddingSize
                                                            .setSmallSize(
                                                                width)),
                                                    child: Text(
                                                      productService
                                                              .products[index]
                                                              .saticiFirma ??
                                                          "Tedarikçi Bilinmiyor",
                                                      style: TextStyle(
                                                          fontSize: FontSize
                                                              .setBigSize(
                                                                  width),
                                                          color: Colors.white,
                                                          fontWeight:
                                                              FontWeight.bold),
                                                    ),
                                                  ),
                                                ],
                                              ),
                                            ),
                                          )
                                        ],
                                      ),
                                    ),
                                  )
                                ],
                              )
                            ],
                          );
                        });
              }
            }));
  }
}

product_service.dart

import 'package:dio/dio.dart';
import 'package:fiyatfind/models/product_model.dart';
import 'package:fiyatfind/providers/database_providers.dart';

import 'package:flutter/foundation.dart';
import 'package:get/get.dart';

class ProductService {
  Dio dio = Dio();
  final accessToken =
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2ODkzNjAzOTd9._RDmnzGWFNE02R4i_3IlrHyNW_UX6bnJB_lTT3__QtY";
  final url = "http://localhost:3000/product";
  List<ProductModel> products = [];
  DatabaseConfig dbconfig = Get.find();

  Future<List<ProductModel>> getProduct(String productCode) async {
    if (kDebugMode) {
      print(dbconfig.host.value);
    }
    if (kDebugMode) {
      print(dbconfig.username.value);
    }
    if (kDebugMode) {
      print(dbconfig.password.value);
    }
    if (kDebugMode) {
      print(dbconfig.databaseName.value);
    }

    if (kDebugMode) {
      print(productCode);
    }
    try {
      var response = await dio.post(url,
          data: {
            "host": dbconfig.host.value,
            "username": dbconfig.username.value,
            "password": dbconfig.password.value,
            "database": dbconfig.databaseName.value,
            "productCode": productCode
          },
          options: Options(
            headers: {'Authorization': 'Bearer $accessToken'},
          ));
      if (response.statusCode == 200) {
        products.clear();
        products = (response.data as List)
            .map((e) => ProductModel.fromJson(e))
            .toList();
        return products;
      } else {
        return [];
      }
    } catch (e) {
      if (kDebugMode) {
        print(e);
      }
      return [];
    }
  }
}

解决方案

核心问题:Android模拟器的localhost指向自身而非主机

Android模拟器内的localhost(127.0.0.1)指代模拟器系统本身,而非运行Node.js的主机电脑,因此会触发连接拒绝错误。

1. 修改API访问地址

  • 使用主机局域网IP:在product_service.dart中,将localhost替换为主机电脑的局域网IP(如192.168.1.100):
    final url = "http://192.168.1.100:3000/product";
    
  • 使用模拟器特殊映射地址:Android模拟器提供10.0.2.2作为主机localhost的映射地址,直接替换即可:
    final url = "http://10.0.2.2:3000/product";
    

2. 确保Node.js API允许外部访问

启动Node.js服务时,监听地址设置为0.0.0.0(而非默认的localhost),让局域网内设备(包括模拟器)能正常访问:

app.listen(3000, '0.0.0.0', () => {
  console.log('Server running on port 3000');
});

3. 检查防火墙设置

确认主机电脑的防火墙允许3000端口的入站连接,避免拦截模拟器的请求。

关于编译警告

这些警告是依赖库使用了已废弃API或未检查的操作,不影响应用核心功能。若要消除警告:

  • 在Android项目的build.gradle中添加lint参数:
    android {
      lintOptions {
        deprecation true
        unchecked true
      }
    }
    
  • 或更新相关依赖库到最新版本,避免使用废弃API。

内容的提问来源于stack exchange,提问作者MertYavuz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:15:58