Android类型转换异常:Application无法转为InventoryApplication排查求助
问题排查:ClassCastException: android.app.Application cannot be cast to InventoryApplication
异常日志
2022-12-11 02:50:28.862 24393-24393/com.example.skillit E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.skillit, PID: 24393 java.lang.ClassCastException: android.app.Application cannot be cast to com.example.skillit.data.InventoryApplication at com.example.skillit.ProfileActivity$viewModel$2.invoke(ProfileActivity.kt:22) at com.example.skillit.ProfileActivity$viewModel$2.invoke(ProfileActivity.kt:21) at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:47) at androidx.lifecycle.ViewModelLazy.getValue(ViewModelLazy.kt:35) at com.example.skillit.ProfileActivity.getViewModel(ProfileActivity.kt:21) at com.example.skillit.ProfileActivity.onCreate$lambda$3(ProfileActivity.kt:51) at com.example.skillit.ProfileActivity.$r8$lambda$733-BBVTFBdHTXlcl6xFIzJMP3c(Unknown Source:0) at com.example.skillit.ProfileActivity$$ExternalSyntheticLambda3.onClick(Unknown Source:2) at android.view.View.performClick(View.java:7881) at android.widget.TextView.performClick(TextView.java:16201) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1219) at android.view.View.performClickInternal(View.java:7858) at android.view.View.-$$Nest$mperformClickInternal(Unknown Source:0) at android.view.View$PerformClick.run(View.java:30863) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at android.app.ActivityThread.main(ActivityThread.java:8741) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
相关代码
ProfileActivity.kt
package com.example.skillit import android.content.Intent import android.os.Bundle import android.view.LayoutInflater import android.widget.Button import android.widget.ImageView import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.cardview.widget.CardView import androidx.fragment.app.activityViewModels import com.example.skillit.data.InventoryApplication import com.example.skillit.databinding.FragmentItemDetailBinding import com.example.skillit.databinding.ProfileActivityBinding class ProfileActivity : AppCompatActivity() { //private var _binding: ProfileActivityBinding? = null //private val binding get() = _binding!! private val viewModel: InventoryViewModel by viewModels { InventoryViewModelFactory((application as InventoryApplication).database.itemDao()) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) this.supportActionBar?.hide() //_binding = ProfileActivityBinding.inflate(LayoutInflater.from(this)) //setContentView(binding.root) setContentView(R.layout.profile_activity) val explore_button = findViewById(R.id.explore_button) as CardView val profile_button = findViewById(R.id.profile_button) as CardView val home_button = findViewById(R.id.home_button) as CardView val upload_button = findViewById<Button>(R.id.upload) home_button.setOnClickListener{ intent = Intent(this, HomeActivity::class.java) startActivity(intent) overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right) } explore_button.setOnClickListener{ intent = Intent(this, ExploreActivity::class.java) startActivity(intent) overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right) } profile_button.setOnClickListener{ intent = Intent(this, ProfileActivity::class.java) startActivity(intent) } upload_button.setOnClickListener{ viewModel.addNewItem("name", "link") } } }
InventoryApplication.kt
package com.example.skillit.data import android.app.Application class InventoryApplication : Application() { val database: ItemRoomDatabase by lazy { ItemRoomDatabase.getDatabase(this) } }
ItemRoomDatabase.kt
package com.example.skillit.data import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase @Database(entities = [Item::class], version = 1, exportSchema = false) abstract class ItemRoomDatabase : RoomDatabase() { abstract fun itemDao(): ItemDao companion object { @Volatile private var INSTANCE: ItemRoomDatabase? = null fun getDatabase(context: Context): ItemRoomDatabase { // if the INSTANCE is not null, then return it, // if it is, then create the database return INSTANCE ?: synchronized(this) { val instance = Room.databaseBuilder( context.applicationContext, ItemRoomDatabase::class.java, "item_database" ) // Wipes and rebuilds instead of migrating if no Migration object. // Migration is not part of this codelab. .fallbackToDestructiveMigration() .build() INSTANCE = instance // return instance instance } } } }
问题原因
核心原因是未在AndroidManifest.xml中声明自定义的InventoryApplication作为应用的Application子类,系统默认创建的是android.app.Application实例,而非你自定义的子类,导致强制类型转换失败。
解决方案
- 打开项目中的
AndroidManifest.xml文件 - 在
<application>标签中添加android:name属性,指定自定义Application类的全路径:
<application android:name="com.example.skillit.data.InventoryApplication" <!-- 保留原有属性,如icon、theme等 --> ...> <!-- 活动、服务等其他声明 --> </application>
- 清理项目缓存,重新构建并运行应用,即可解决该类型转换异常。
内容的提问来源于stack exchange,提问作者Fortnite
相关产品推荐
相关产品推荐

