1

我的firebase控制台上的android底部导航视图经常出现膨胀异常。我已经仔细检查了我的代码。我做了一些更改,但应用程序仍然因膨胀异常而崩溃。它没有特定的模式,并且出现在每个品牌和型号以及从 4 到 10 的所有版本的 android 上。最初我虽然这是由于我使用的向量。然后我用PNG替换了所有矢量,但错误仍然存​​在。根据 firebase 控制台的错误原因是找不到资源异常。 由 android.content.res.Resources$NotFoundException 资源 ID #0x7f0800ac 引起 此异常影响 1% 的用户会话。 我正在使用带有 android navcontroller 的底部导航。 我无法在 firebase 报告的任何设备上重现它。我也尝试使用 AS 模拟器,但问题没有被重现。

这是完整的堆栈跟踪。

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{myapp.com/myapp.com.HomeActivity}: android.view.InflateException: Binary XML file line #97: Binary XML file line #97: Error inflating class com.google.android.material.bottomnavigation.BottomNavigationView
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2956)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3091)
       at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
       at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1843)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:193)
       at android.app.ActivityThread.main(ActivityThread.java:6758)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:497)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:912)

这是在 xml 文件的第 97 行

 <com.google.android.material.bottomnavigation.BottomNavigationView
                android:id="@+id/bottomNav"
                style="@style/BottomNavigationView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:itemTextColor="@drawable/bottom_navigation_text_tint"
                app:labelVisibilityMode="labeled"
                app:layout_constraintBottom_toBottomOf="parent"
                app:menu="@menu/bottommenu" />

这是布局文件的其余部分。这是底部菜单 xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/fragHome"
        android:icon="@drawable/home"
        android:title="@string/home" />

    <item
        android:id="@+id/fragUsage"
        android:icon="@drawable/usage"
        android:title="@string/usage" />

    <item
        android:id="@+id/fragWishList"
        android:icon="@drawable/withList"
        android:title="@string/withList" />

    <item
        android:id="@+id/fragShop"
        android:icon="@drawable/cart"
        android:title="@string/shop" />
    <item
        android:id="@+id/fragMore"
        android:icon="@drawable/more"
        android:title="@string/more" />
</menu>

这是 Bottom_navigation_text_tint

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorPrimary" android:state_checked="true" />
    <item android:color="@color/lightGrey" />
</selector>

这是底部导航中使用的样式。

<style name="BottomNavigationView">
        <item name="itemTextAppearanceActive">
            @style/TextAppearance.BottomNavigationView.Active
        </item>
        <item name="itemTextAppearanceInactive">
            @style/TextAppearance.BottomNavigationView.Inactive
        </item>
    </style>

    <style name="TextAppearance.BottomNavigationView.Inactive">
        <item name="android:textSize">@dimen/_8sdp</item>
        <item name="fontFamily">@font/roboto_regular</item>
    </style>

    <!-- active tab icon style -->
    <style name="TextAppearance.BottomNavigationView.Active">
        <item name="fontFamily">@font/roboto_regular</item>
        <item name="android:textSize">@dimen/_8sdp</item>
    </style>

更新 1 这是我的家庭活动课

class HomeActivity : AppCompatActivity(), HasSupportFragmentInjector,
    NavigationView.OnNavigationItemSelectedListener,
    ConfirmationDialogue.OnActivateClicked, Injectable,
    DrawerLocker, DialogAccounts.OnActivateClicked, DialogAccounts.OnDismissClicked {

    private var isMaintenance: Boolean = false

    @Inject
    lateinit var notificationRepo: NotificationRepo

    private lateinit var drawerToggle: ActionBarDrawerToggle

    @Inject
    lateinit var tokenRepository: TokenRepository

    @Inject
    lateinit var hyperLinksRepository: HyperlinkRepository

    @Inject
    lateinit var remoteDataSource: RemoteDataSource

    @Inject
    lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>

    override fun supportFragmentInjector() = dispatchingAndroidInjector


    private lateinit var navController: NavController
    private lateinit var bottomNav: BottomNavigationView
    private lateinit var mActionBar: View
    private lateinit var btnHamBurger: ImageButton
    private lateinit var sideNavView: NavigationView
    private lateinit var btnBell: ImageButton
    private lateinit var drawerLayout: DrawerLayout
    private lateinit var userDetails: RegistrationDetails
    private lateinit var dialogAccounts: DialogAccounts

    companion object {
        var selected = RegistrationUtility.getUserDetails()

    }

    override fun onStart() {
        super.onStart()
     }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home)
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

        initViews()
        initEvents()

    }

    override fun onSupportNavigateUp() = navController.navigateUp()

    private fun initViews() {
        bottomNav = findViewById(R.id.bottomNav)
        mActionBar = findViewById(R.id.myActionBar)
        btnHamBurger = findViewById(R.id.btnHamBurger)
        navController = findNavController(R.id.navigationHostFragment)
        sideNavView = findViewById(R.id.nav_view)
        btnBell = findViewById(R.id.btnBell)
        drawerLayout = findViewById(R.id.drawer_layout)

        Glide.with(BaseClass.appContext).asGif().load(R.drawable.loader_png).diskCacheStrategy(
            DiskCacheStrategy.ALL
        ).into(loader_gif)
     }


    @SuppressLint("IntentReset")
    private fun initEvents() {
        onDestinationChanged()
        sideNavView.setupWithNavController(navController)
        bottomNav.setupWithNavController(navController)
        sideNavView.setNavigationItemSelectedListener(this)

        btnHamBurger.setOnClickListener {
            if (!sideNavView.isShown) {
                drawerLayout.openDrawer(GravityCompat.END)
            }
        }
        btnBell.setOnClickListener {
            navController.navigate(R.id.frag_Notif)
        }
        drawerToggle = object : ActionBarDrawerToggle(
            this,
            drawerLayout,
            null,
            R.string.empty,
            R.string.empty
        ) {

            override fun onDrawerOpened(drawerView: View) {
                super.onDrawerOpened(drawerView)
                setNavHeader()
            }
        }
        drawerToggle.isDrawerIndicatorEnabled = true
        drawerLayout.addDrawerListener(drawerToggle)
        drawerToggle.syncState()


        tvTitle.setOnClickListener {
        }
    }



    private fun onDestinationChanged() {
        navController.addOnDestinationChangedListener { _, destination, _ ->

            btnBell.visibility = View.VISIBLE
            Lingver.getInstance().setLocale(this, getLocale())
            when (destination.id) {
                R.id.fragBundles -> tvTitle.text = getString(R.string.bundles)
                //other code
            }

        }
    }



    private fun setNavHeader() {
        userDetails = RegistrationUtility.getUserDetails()
        val headerView = sideNavView.getHeaderView(0)
        val view = sideNavView.menu.findItem(R.id.nav_log_version).actionView
        val tvVersion = view.findViewById<TextView>(R.id.lblVersion)
        var currentVersion = getString(R.string.version) + " " + BuildConfig.VERSION_NAME
        if (BuildConfig.DEBUG) {
            currentVersion = currentVersion + " " + BuildConfig.FLAVOR
        }
        tvVersion.text = currentVersion
        val navUsername = headerView.findViewById(R.id.tvUserName) as TextView
        navUsername.text = userDetails.userName
        val nvMobile = headerView.findViewById(R.id.tvUserNumber) as TextView
        nvMobile.text = userDetails.mobileNumber
        val imgProfile = headerView.findViewById(R.id.ivUserImage) as ImageView
        imgProfile.setImageResource(userDetails.userAvatar ?: R.drawable.ic_av1)

    }

    override fun onBackPressed() {
        if (sideNavView.isShown) {
            drawerLayout.closeDrawer(GravityCompat.END)
        }
        if (loader_loader.isVisible) {
            loader_loader.visibility = View.GONE
        } else {
            super.onBackPressed()
        }
    }


    override fun onNavigationItemSelected(menuItem: MenuItem): Boolean {
        var screenName = ""
        when (menuItem.itemId) {
            R.id.fragProfile -> {
                navController.popBackStack(R.id.fragHome, false)
                navController.navigate(R.id.fragProfile)
                screenName = LoggingScreens.MyProfile.screenName
            }
            // other code.
        }
        drawerLayout.closeDrawer(GravityCompat.END)
        return true
    }




    override fun setDrawerEnabled(enabled: Boolean) {
        val lockMode: Int = if (enabled) {
            DrawerLayout.LOCK_MODE_UNLOCKED
        } else {
            DrawerLayout.LOCK_MODE_LOCKED_CLOSED
        }
        drawerLayout.setDrawerLockMode(lockMode)
        drawerToggle.isDrawerIndicatorEnabled = enabled
    }




    override fun onDestroy() {
        super.onDestroy()
        Glide.get(applicationContext).clearMemory();
        thread(start = true) {
            Glide.get(this).clearDiskCache()
        }
    }



    private fun showUpdateDialog(
        title: String,
        message: String,
        cancelable: Boolean,
        buttonText: Int
    ) {
        dialogAccounts = DialogAccounts(
            this@HomeActivity,
            message,
            title,
            R.drawable.ic_av1_happy,
            this@HomeActivity,
            this@HomeActivity,
            cancelable,
            buttonText
        )
        dialogAccounts.showDialog()


    }

    override fun onActivateClicked() {
        if (!isMaintenance) {
            val intent =
                Intent(
                    Intent.ACTION_VIEW,
                    Uri.parse("market://details?id=" + applicationContext.packageName)
                )
            if (intent.resolveActivity(packageManager) != null) {
                startActivity(intent)
            }
        }
    }

    override fun onDismissClicked() {
    }




}


interface DrawerLocker {
    fun setDrawerEnabled(enabled: Boolean)
}

这是我的proguard配置

# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class screenName to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file screenName.
#-renamesourcefileattribute SourceFile
# Application classes that will be serialized/deserialized over moshi

#project related
-keep class app.com.pk.constants
-keep class app.com.pk.service.model.** { *; }
-keep class  app.com.pk.service.database.models.** { *; }
-keep class app.com.pk.languageutility.** { *; }
-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*
-keepattributes EnclosingMethod
-keepattributes InnerClasses
-dontwarn org.xmlpull.v1.**
-dontwarn android-support-v4.**
-dontwarn  com.crashlytics.**
-keep class com.google.android.gms.** { *; }
-dontwarn com.google.android.gms.**
-keep public class com.google.** {*;}
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod

# Retrofit does reflection on method and parameter annotations.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations

# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}

# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**

# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit

# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*

# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>

# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8


# For OkHttp 3.x
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }

# crashlytics
-keep class com.crashlytics.** { *; }
-dontwarn com.crashlytics.**
4

0 回答 0