Android应用Fragment无法加载,伴APK资源加载I/O错误求助
Android应用Fragment无法加载,Logcat报APK资源加载I/O错误
问题概述
开发一款使用Fragments和Retrofit的Android应用,应用能正常启动,但Fragment无法加载,Logcat中出现APK资源加载I/O错误。已多次卸载重装应用,问题仍未解决。
相关代码
MainActivity 代码
class MainActivity : AppCompatActivity() { private lateinit var navController: NavController private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var binding: ActivityMainBinding lateinit var viewModel : CricketViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) val cricketRepo = (application as CricketApplication).repository val viewModelFactory = CricketViewModelFactory(cricketRepo) viewModel = ViewModelProvider(this , viewModelFactory).get(CricketViewModel::class.java) appBarConfiguration = AppBarConfiguration(setOf(R.id.iplFragment2 , R.id.otherMatchesFragment)) val navHostFragment = supportFragmentManager.findFragmentById(R.id.navContainer) as NavHostFragment navController = binding.navContainer.getFragment<NavHostFragment>().navController setupActionBarWithNavController(navController, appBarConfiguration) binding.bottomNavigationView.setupWithNavController(navController) } }
IplFragment 代码
class IplFragment : Fragment() { private lateinit var cricketViewModel: CricketViewModel private lateinit var binding: FragmentIplBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment binding = FragmentIplBinding.inflate(inflater , container , false) cricketViewModel = (activity as MainActivity).viewModel cricketViewModel.cRicket.observe(viewLifecycleOwner , Observer { // binding.tvData.text =it.data[0].series_id Toast.makeText(context , " $it.data" , Toast.LENGTH_SHORT).show() Log.d("iplfragment" , "$it.data") }) return binding.root } }
主Activity布局
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" tools:context=".ui.MainActivity"> <androidx.fragment.app.FragmentContainerView android:id="@+id/navContainer" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="650dp" app:defaultNavHost="true" app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph="@navigation/navgraph" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottomNavigationView" android:layout_width="match_parent" android:layout_height="70dp" android:layout_gravity="bottom" android:background="@color/black" android:backgroundTint="@color/black" app:itemIconTint="@color/white" app:itemTextColor="@color/white" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.997" app:menu="@menu/menu" /> </FrameLayout>
Fragment布局
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/purple_200" tools:context=".ui.IplFragment"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/white" android:id="@+id/tvData" android:text="IPL Match" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:textColor="@color/white" android:text="IPL" /> </FrameLayout>
错误日志
Failed to open APK '/data/app/~~1kceB6wqP_-41XWyDmGvog==/com.example.iplscore-XiE_yzRxa3HJApEmriciAQ==/base.apk': I/O error 01:44:18.943 E Failed to open APK '/data/app/~~1kceB6wqP_-41XWyDmGvog==/com.example.iplscore-XiE_yzRxa3HJApEmriciAQ==/base.apk': I/O error 01:44:18.945 E failed to add asset path '/data/app/~~1kceB6wqP_-41XWyDmGvog==/com.example.iplscore-XiE_yzRxa3HJApEmriciAQ==/base.apk' java.io.IOException: Failed to load asset path /data/app/~~1kceB6wqP_-41XWyDmGvog==/com.example.iplscore-XiE_yzRxa3HJApEmriciAQ==/base.apk at android.content.res.ApkAssets.nativeLoad(Native Method) at android.content.res.ApkAssets.<init>(ApkAssets.java:295) at android.content.res.ApkAssets.loadFromPath(ApkAssets.java:144) at android.app.ResourcesManager.loadApkAssets(ResourcesManager.java:454) at android.app.ResourcesManager.access$000(ResourcesManager.java:72) at android.app.ResourcesManager$ApkAssetsSupplier.load(ResourcesManager.java:168) at android.app.ResourcesManager.createAssetManager(ResourcesManager.java:530) at android.app.ResourcesManager.createResourcesImpl(ResourcesManager.java:612) at android.app.ResourcesManager.findOrCreateResourcesImplForKeyLocked(ResourcesManager.java:664) at android.app.ResourcesManager.createResources(ResourcesManager.java:1011) at android.app.ResourcesManager.getResources(ResourcesManager.java:1114) at android.app.ActivityThread.getTopLevelResources(ActivityThread.java:2372) at android.app.ApplicationPackageManager.getResourcesForApplication(ApplicationPackageManager.java:1751) at android.app.ApplicationPackageManager.getResourcesForApplication(ApplicationPackageManager.java:1737) at android.app.ApplicationPackageManager.getDrawable(ApplicationPackageManager.java:1506) at android.app.ApplicationPackageManager.loadUnbadgedItemIcon(ApplicationPackageManager.java:3029) at android.content.pm.PackageItemInfo.loadUnbadgedIcon(PackageItemInfo.java:290) at com.android.systemui.toast.SystemUIToast.getBadgedIcon(SystemUIToast.java:284) at com.android.systemui.toast.SystemUIToast.inflateToastView(SystemUIToast.java:198) at com.android.systemui.toast.SystemUIToast.<init>(SystemUIToast.java:90) at com.android.systemui.toast.SystemUIToast.<init>(SystemUIToast.java:77) at com.android.systemui.toast.ToastFactory.createToast(ToastFactory.java:78) at com.android.systemui.toast.ToastUI.lambda$showToast$0(ToastUI.java:113) at com.android.systemui.toast.ToastUI.$r8$lambda$w_gPCh3F8Xxn1jN4lkQZoUci71c(Unknown Source:0) at com.android.systemui.toast.ToastUI$$ExternalSyntheticLambda0.run(Unknown Source:16) at com.android.systemui.toast.ToastUI.showToast(ToastUI.java:140) at com.android.systemui.statusbar.CommandQueue$H.handleMessage(CommandQueue.java:1431) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
解决方案
1. 修复MainActivity布局加载重复问题
代码中连续调用两次setContentView会导致布局初始化混乱,Fragment容器无法正常工作,修改后代码如下:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) val cricketRepo = (application as CricketApplication).repository val viewModelFactory = CricketViewModelFactory(cricketRepo) viewModel = ViewModelProvider(this , viewModelFactory).get(CricketViewModel::class.java) appBarConfiguration = AppBarConfiguration(setOf(R.id.iplFragment2 , R.id.otherMatchesFragment)) val navHostFragment = supportFragmentManager.findFragmentById(R.id.navContainer) as NavHostFragment navController = navHostFragment.navController setupActionBarWithNavController(navController, appBarConfiguration) binding.bottomNavigationView.setupWithNavController(navController) }
2. 修复布局约束无效问题
主Activity根布局用FrameLayout却添加ConstraintLayout约束属性,完全无效,改为ConstraintLayout确保布局位置正确:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" tools:context=".ui.MainActivity"> <androidx.fragment.app.FragmentContainerView android:id="@+id/navContainer" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="0dp" app:defaultNavHost="true" app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph="@navigation/navgraph" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottomNavigationView" android:layout_width="match_parent" android:layout_height="70dp" android:background="@color/black" android:backgroundTint="@color/black" app:itemIconTint="@color/white" app:itemTextColor="@color/white" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:menu="@menu/menu" /> </androidx.constraintlayout.widget.ConstraintLayout>
3. 解决APK资源I/O错误
这类错误多和APK损坏、缓存或存储有关,尝试以下操作:
- 清理Android Studio缓存:
File > Invalidate Caches... > Invalidate and Restart - 清理设备应用缓存:设置 > 应用 > 你的应用 > 存储 > 清理缓存
- 检查设备存储是否充足,避免因空间不足导致APK读取失败
- 重新生成签名APK(若为正式包),确保文件无损坏
4. 优化Fragment中ViewModel获取方式
避免强转Activity获取ViewModel,改用更安全的方式:
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = FragmentIplBinding.inflate(inflater , container , false) cricketViewModel = ViewModelProvider(requireActivity(), CricketViewModelFactory((requireActivity().application as CricketApplication).repository)).get(CricketViewModel::class.java) cricketViewModel.cRicket.observe(viewLifecycleOwner) { data -> if (data?.data != null) { binding.tvData.text = data.data[0].series_id Log.d("iplfragment" , "${data.data}") } else { Toast.makeText(context , "数据为空" , Toast.LENGTH_SHORT).show() } } return binding.root }
内容的提问来源于stack exchange,提问作者Arpit Gupta
相关产品推荐
相关产品推荐

