如何使用Expo Config Plugins在原生目录创建文件及文件夹?
在Expo托管工作流中创建Android自定义Activity及目录结构的方案
核心实现思路
在托管工作流中,所有原生修改必须通过Expo Config Plugin完成,确保每次prebuild或eas build时修改能被持久化应用。以下是具体步骤:
1. 编写Config Plugin生成目录与Activity文件
利用Node.js文件系统API和Expo提供的项目路径工具,在插件中动态创建目标目录并写入Activity代码。
示例插件代码(保存为plugins/withCustomAndroidActivities.js):
const path = require('path'); const fs = require('fs/promises'); const { withAndroidManifest, withProjectRoot } = require('@expo/config-plugins'); module.exports = async function withCustomAndroidActivities(config) { // 动态获取Android包名,避免硬编码 const packageName = config.android?.package || 'com.my.app'; const packagePathSegments = packageName.split('.'); config = await withProjectRoot(config, async (config) => { // 计算Java代码根目录路径 const javaRootDir = path.join( config.modRequest.projectRoot, 'android', 'app', 'src', 'main', 'java', ...packagePathSegments ); // 创建自定义Activity存放目录 const customActivityDir = path.join(javaRootDir, 'customActivities'); await fs.mkdir(customActivityDir, { recursive: true }); // 写入示例Activity代码 const activityContent = ` package ${packageName}.customActivities; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; public class CustomActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 此处添加你的业务逻辑 finish(); } } `.trim(); await fs.writeFile( path.join(customActivityDir, 'CustomActivity.java'), activityContent ); return config; }); // 注册新Activity到AndroidManifest.xml config = withAndroidManifest(config, (config) => { const manifest = config.modResults.manifest; manifest.application[0].activity.push({ $: { 'android:name': `.customActivities.CustomActivity`, 'android:exported': 'true', 'android:theme': '@style/Theme.App.SplashScreen' // 可按需修改主题 } }); return config; }); return config; };
2. 在Expo配置文件中启用插件
将编写好的插件添加到app.json或app.config.js的plugins数组:
{ "expo": { "plugins": [ "./plugins/withCustomAndroidActivities.js" ] } }
3. 验证与测试
- 执行
expo prebuild --platform android生成原生目录,检查android/app/src/main/java/com/my/app/customActivities是否存在目标文件。 - 查看
AndroidManifest.xml,确认新Activity已完成注册。 - 运行
eas build --platform android,验证构建流程无报错,新Activity可正常运行。
替代方案:复制预编写的Activity文件
若不想动态生成代码,可预先写好Activity文件,在插件中直接复制到目标目录:
// 替换插件中写入文件的逻辑 const sourceActivityPath = path.join(config.modRequest.projectRoot, 'assets', 'CustomActivity.java'); await fs.copyFile(sourceActivityPath, path.join(customActivityDir, 'CustomActivity.java'));
关键注意事项
- 托管工作流中禁止手动修改原生目录,所有修改必须通过Config Plugin实现,否则会被
prebuild覆盖。 - 若需Activity与React Native交互,可继承
com.facebook.react.ReactActivity而非普通AppCompatActivity。 - 确保插件中的路径、包名与项目实际情况一致,避免硬编码。
内容的提问来源于stack exchange,提问作者KaraX_X
相关产品推荐
相关产品推荐

