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

Android Studio添加Assets文件夹后Navigation报R包不存在

问题现象

Android Studio项目新增Assets文件夹后编译失败,报错出自Navigation组件自动生成代码:

error: package R does not exist
"return new ActionOnlyNavDirections(R.id.action_newAlarmFragment_to_homeFragment);"

对应自动生成的Directions类代码如下:

import androidx.annotation.NonNull;
import androidx.navigation.ActionOnlyNavDirections;
import androidx.navigation.NavDirections;

public class SetNewAlarmFragmentDirections {
  private SetNewAlarmFragmentDirections() {
  }

  @NonNull
  public static NavDirections actionNewAlarmFragmentToHomeFragment() {
    return new ActionOnlyNavDirections(R.id.action_newAlarmFragment_to_homeFragment);
  }
}

已尝试的排查操作:

  • 执行Clean Project、Rebuild Project
  • 执行Invalidate caches and restart
  • 手动排查各文件R类导入语句,未发现异常
关联代码片段

SetNewAlarmFragment实现

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.Navigation
import com.pleavinseven.alarmclockproject.alarmmanager.AlarmManager
import com.pleavinseven.alarmclockproject.data.model.Alarm
import com.pleavinseven.alarmclockproject.data.viewmodel.AlarmViewModel
import com.pleavinseven.alarmclockproject.databinding.FragmentSetNewAlarmBinding
import com.pleavinseven.alarmclockproject.util.TimePickerUtil
import java.util.*


class SetNewAlarmFragment : Fragment() {

    private val timePickerUtil = TimePickerUtil()
    lateinit var binding: FragmentSetNewAlarmBinding
    private lateinit var alarmViewModel: AlarmViewModel


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        binding = FragmentSetNewAlarmBinding.inflate(inflater, container, false)

           binding.fragmentCreateAlarmRecurring.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener { _, isChecked ->
        if (isChecked) {
            binding.fragmentCreateAlarmRecurring.visibility = View.VISIBLE
        } else {
            binding.fragmentCreateAlarmRecurring.visibility = View.GONE
        }
    })

    alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]


    binding.fragmentBtnSetAlarm.setOnClickListener(View.OnClickListener { _ ->
        scheduleAlarm()
        Navigation.findNavController(requireView())
            .navigate(com.pleavinseven.alarmclockproject.R.id.action_newAlarmFragment_to_homeFragment)
    })
    return binding.root


}

导航配置nav_graph.xml

?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/alarm_nav"
app:startDestination="@id/homeFragment">

<fragment
    android:id="@+id/homeFragment"
     android:name="com.pleavinseven.alarmclockproject.fragments.HomeFragment"
    android:label="fragment_home"
    tools:layout="@layout/fragment_home" >
    <action
        android:id="@+id/action_homeFragment_to_newAlarmFragment"
        app:destination="@id/newAlarmFragment" />
    <action
        android:id="@+id/action_homeFragment_to_updateFragment"
        app:destination="@id/updateFragment" />
</fragment>
<fragment
    android:id="@+id/newAlarmFragment"
    android:name="com.pleavinseven.alarmclockproject.fragments.SetNewAlarmFragment"
    android:label="NewAlarmFragment" >
    <action
        android:id="@+id/action_newAlarmFragment_to_homeFragment"
        app:destination="@id/homeFragment" />
</fragment>
<fragment
    android:id="@+id/updateFragment"
    android:name="com.pleavinseven.alarmclockproject.fragments.UpdateFragment"
    android:label="UpdateFragment" >
    <action
        android:id="@+id/action_updateFragment_to_homeFragment"
        app:destination="@id/homeFragment" />
    <argument
        android:name="currentAlarm"
        app:argType="com.pleavinseven.alarmclockproject.data.model.Alarm" />
</fragment>
排查解决步骤

按优先级从高到低逐一排查:

  1. 修正导航XML语法错误
    贴出的nav xml第一行缺失左尖括号,正确开头应为<?xml version="1.0" encoding="utf-8"?>,当前写法会直接导致AAPT2资源编译失败,R类无法正常生成,所有依赖R类的代码(包括Safe Args自动生成的Directions类)都会报找不到R的错误。先补全这个尖括号,再重新编译。
  2. 确认Assets文件夹路径正确
    新增Assets文件夹时如果放错位置,会打断资源编译流程:标准Assets路径必须是对应模块的src/main/assets,不能放在模块根目录、res目录下,也不能和java/kotlin代码目录混放。如果路径放错,移动到正确位置后重新编译即可。
  3. 修复非传递R类兼容问题
    如果项目gradle.properties中开启了android.nonTransitiveRClass=true,且Navigation组件版本低于2.4.0,会触发Safe Args插件的已知bug:自动生成的Directions类不会自动导入项目包名的R类,直接调用R就会报不存在。解决方法二选一:
    • 把Navigation相关依赖(包括safe-args插件)升级到2.4.0及以上稳定版
    • 临时关闭非传递R类配置验证,即把android.nonTransitiveRClass改为false
  4. 排查资源编译前置错误
    执行命令行编译./gradlew clean assembleDebug,查看编译日志最开头的错误,不要看最后抛出的R不存在错误——R不存在永远是连锁结果,前面一定有更早的资源编译失败原因,比如资源命名不合法(含大写、特殊字符)、资源冲突、XML布局语法错误等,修好最前置的资源错误,R类就会正常生成。
  5. 核对Safe Args插件配置
    确认项目级和模块级的Safe Args插件配置匹配:
    • 项目级build.gradle中要添加对应版本的safe-args依赖
    • Kotlin项目模块级要应用androidx.navigation.safeargs.kotlin插件,Java项目应用androidx.navigation.safeargs插件,插件版本要和引入的navigation-fragment、navigation-ui依赖版本完全一致,版本不匹配也会导致自动生成代码异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 21:24:20