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

使用react-native-gifted-chat发送消息时Expo应用崩溃问题

Expo Android APK发送消息崩溃问题(模拟器运行正常)

问题现象

应用在Android模拟器上完全正常,但打包为预览版APK安装到实体Android设备后,执行以下步骤会立即崩溃:

  • 将Expo应用构建为预览版APK
  • 在实体Android设备上安装该APK
  • 打开应用并导航至聊天界面
  • 输入消息并按下发送按钮
  • 应用立即崩溃

相关代码

import React, { useState, useCallback, useEffect } from "react";
import { Bubble, GiftedChat, Send } from "react-native-gifted-chat";
import { SafeAreaView, View, Text } from "react-native";
import { Colors } from "../../constants/Colors";
import { Ionicons } from "@expo/vector-icons";
import { useSafeAreaInsets } from "react-native-safe-area-context";

const ChatScreen = () => {
  const insets = useSafeAreaInsets();
  const [messages, setMessages] = useState([]);
  const [isTyping, setIsTyping] = useState(false);
  const [text, setText] = useState("");

  useEffect(() => {
    test();
  }, []);

  const test = async (userMessage) => {
    setIsTyping(true);
    try {
      const newMessage = {
        _id: Date.now(),
        text: "api response text",
        createdAt: new Date(),
        user: { _id: 2, name: "AI Assistant" },
        isStarred: false,
      };
      setMessages((prev) => GiftedChat.append(prev, [newMessage]));
    } catch (error) {
      console.error("API Error:", error);
    } finally {
      setIsTyping(false);
    }
  };

  const onSend = useCallback(async (messages = []) => {
    setMessages((prev) => GiftedChat.append(prev, messages));
    await test(messages[0].text);
  }, []);

  const onLongPress = (context, message) => {
    setMessages((prev) =>
      prev.map((msg) =>
        msg._id === message._id ? { ...msg, isStarred: !msg.isStarred } : msg
      )
    );
  };

  const renderSend = (props) => (
    <View style={{ flexDirection: "row", alignItems: "center", padding: 14 }}>
      <Send {...props} containerStyle={styles.sendButton}>
        <Ionicons name="paper-plane" size={20} color="white" />
      </Send>
    </View>
  );

  const renderBubble = (props) => (
    <Bubble
      {...props}
      wrapperStyle={{
        left: { backgroundColor: Colors.card },
        right: { backgroundColor: Colors.primary },
      }}
      renderTime={() => (
        <View style={styles.timeContainer}>
          <Text style={styles.timeText}>
            {new Date(props.currentMessage.createdAt).toLocaleTimeString([], {
              hour: "2-digit",
              minute: "2-digit",
            })}
          </Text>
          {props.currentMessage.isStarred && (
            <Ionicons name="star" size={15} color="#FFD700" />
          )}
        </View>
      )}
    />
  );

  return (
    <SafeAreaView
      style={{
        flex: 1,
        backgroundColor: "white",
        paddingBottom: insets.bottom,
      }}
    >
      <GiftedChat
        messages={messages}
        onSend={onSend}
        user={{ _id: 1 }}
        isTyping={isTyping}
        renderBubble={renderBubble}
        renderSend={renderSend}
        onLongPress={onLongPress}
        text={text}
        onInputTextChanged={setText}
        maxComposerHeight={100}
        textInputProps={styles.inputMsg}
      />
    </SafeAreaView>
  );
};

const styles = {
  timeContainer: { flexDirection: "row", alignItems: "center" },
  timeText: { fontSize: 12, color: "#666", marginRight: 5 },
  sendButton: {
    backgroundColor: Colors.primary,
    padding: 10,
    borderRadius: 10,
    justifyContent: "center",
    alignItems: "center",
  },
  inputMsg: {
    backgroundColor: Colors.card,
    borderWidth: 1,
    borderRadius: 10,
    borderColor: "#666",
    paddingHorizontal: 10,
    fontSize: 16,
    marginVertical: 4,
    paddingTop: 8,
  },
};

export default ChatScreen;

环境版本信息

  • Node.js版本: v20.12.1
  • React版本: 18.2.0
  • React Native版本: 0.74.5
  • react-native-gifted-chat版本: 2.6.4
  • 平台: Android
  • TypeScript版本: 5.3.3

排查与解决建议

1. 修正textInputProps传递错误

代码中直接将样式对象传给textInputProps,这是错误用法——textInputProps需要接收属性对象,而非纯样式。模拟器可能容错,但生产环境会引发崩溃:

// 错误写法
textInputProps={styles.inputMsg}
// 修正写法
textInputProps={{ style: styles.inputMsg }}

2. 检查图标资源打包问题

实体设备可能缺失模拟器默认包含的字体/图标资源,尝试:

  • 确保expo-font已安装并在app.json中声明所需字体
  • 临时替换@expo/vector-icons为React Native内置组件测试

3. 排查安全区域计算冲突

实体设备的安全区域逻辑可能与模拟器不同,尝试:

  • 暂时移除SafeAreaView的paddingBottom: insets.bottom配置,测试是否还崩溃
  • 确认react-native-safe-area-context在生产环境的配置正确

4. 合并状态更新避免冲突

onSend和test中连续调用setMessages可能导致状态更新冲突,尝试合并操作:

const onSend = useCallback(async (messages = []) => {
  const userMessages = GiftedChat.append([], messages);
  setIsTyping(true);
  try {
    const aiMessage = {
      _id: Date.now(),
      text: "api response text",
      createdAt: new Date(),
      user: { _id: 2, name: "AI Assistant" },
      isStarred: false,
    };
    setMessages(GiftedChat.append(userMessages, [aiMessage]));
  } catch (error) {
    console.error("API Error:", error);
  } finally {
    setIsTyping(false);
  }
}, []);

5. 查看实体设备崩溃日志

连接设备到电脑,执行以下命令获取崩溃堆栈信息,精准定位问题:

adb logcat *:E

内容的提问来源于stack exchange,提问作者Fırat Altun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:44:52