Android 7 & 8 Only - ClassCastException: LayoutParams cannot be cast to AbsListView$LayoutParams

戏子无情 提交于 2021-01-27 22:46:48

问题


I have a very odd problem that I'm looking into. I didn't write the original code, but I am investigate why its crashing now, all of a sudden. After looking at it, I don't see any reason for the crash. Also, it works perfectly in lower OS levels (e.g., Android 6); however, its consistently crashing when run in Android 7 and 8. It was also very difficult to reproduce at first, because the crash only manifests after the 6th indices... Was originally thinking that it might be some corrupted data, because the issue only manifested for certain users. But then I was able to reproduce, consistently, once I bumped up the number of items in the list. The Class cast exception is happening in our List Adapter, when we iterate through a List of Medication Objects and construct a List of them for quick reference to the user. Indices 0 thru 5 have no issue; however, after processing indices 6, the app crashes when it returns the View (the convertView that was originally passed in). I've stepped through the code with up to 6 medications and never see a problem. Upon stepping through with the 6th indices (the 7th medication), it crashes, consistently, when the getView(...) method returns. And like I said before, this only happens when the code is running in Android 7 and 8. When the code runs on Android 6 (for example), it can process 10+ medications and more. Even tested with a user that had 20. Wondering if anyone has come across this and/or has suggestions/thoughts. Is it possible that something changed in Android 7 and 8 with the adapter's view recycler? It makes no sense that it only happens when the medication list is larger than the screen can display. Its almost as if the recycler has a bug in Android 7 and 8...

Here is getView(...) implementation:

public View getView(int position, View convertView, ViewGroup parent) {

    Log.i(TAG, position + " | " + convertView);

    ViewHolder holder;

    LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

    // MedicationItem
    MedicationItem medItem_pos = rowItems.get(position);

    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.med_adjustment_reconciliation_item, parent, false);
        holder = new ViewHolder();
        holder.drugInfo = (TextView) convertView.findViewById(R.id.med_adj_recon_list_item_drug_info_textview);
        holder.drugDosageInfo = (TextView) convertView.findViewById(R.id.med_adj_recon_list_item_drug_dosage_info_textview);

        if (medItem_pos.isTaking()) {
            ((ListView)parent).setItemChecked(position, true);

        } else {
            ((ListView)parent).setItemChecked(position, false);
        }

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    // Build Drug Info
    StringBuilder sbDrugInfo = new StringBuilder(medItem_pos.getDrug());
    if (StringUtils.isNotEmpty(medItem_pos.getTradeName()))
        sbDrugInfo.append(String.format(" (%s) ", Html.fromHtml(medItem_pos.getTradeName())));
    if (null != medItem_pos.getDose() && medItem_pos.getDose() > 0 && StringUtils.isNotEmpty(medItem_pos.getMedUnit())) {
        MedUnit medUnit = EnumUtils.lookup(MedUnit.class, medItem_pos.getMedUnit());
        sbDrugInfo.append(String.format("%s %s", medItem_pos.getDose(), (null==medUnit?medItem_pos.getMedUnit():medUnit.getLocaleString())));
    }

    // Build Drug Dosage Info
    StringBuilder sbDrugDosageInfo = new StringBuilder();
    sbDrugDosageInfo.append(defineQuantity(medItem_pos.getQuantity(), medItem_pos.getDosageFormUnit()));

    if (StringUtils.isNotBlank(medItem_pos.getFrequency())){
        MedFrequency medFrequency = EnumUtils.lookup(MedFrequency.class, medItem_pos.getFrequency());
        if (null != medFrequency){
            if (sbDrugDosageInfo.length() > 0)
                sbDrugDosageInfo.append(" | ").append(medFrequency.getLocaleString());
            else
                sbDrugDosageInfo.append(medFrequency.getLocaleString());
        }else{
            sbDrugDosageInfo.append(MedFrequency.OTHER.getLocaleString());
        }
    }

    // display drug information
    holder.drugInfo.setText(sbDrugInfo.toString());
    holder.drugDosageInfo.setText(sbDrugDosageInfo.toString());

    return convertView;
}

...
...

private class ViewHolder {
    TextView drugInfo;
    TextView drugDosageInfo;
}

Here is the error:

02-20 21:22:11.923 909-7727/? I/ActivityManager: START u0 {cmp=com.some.co/.modules.medadjustment.MedAdjustmentActivity (has extras)} from uid 10246
02-20 21:22:11.926 689-689/? D/QCOM PowerHAL: LAUNCH HINT: ON
02-20 21:22:11.928 689-689/? D/QCOM PowerHAL: Activity launch hint handled
02-20 21:22:11.936 675-2136/? D/audio_hw_primary: out_write: retry previous failed cal level set
02-20 21:22:11.951 21906-21911/? I/zygote: Do partial code cache collection, code=126KB, data=89KB
02-20 21:22:11.952 21906-21911/? I/zygote: After code cache collection, code=124KB, data=88KB
02-20 21:22:11.952 21906-21911/? I/zygote: Increasing code cache capacity to 512KB
02-20 21:22:12.074 21906-21906/? D/AndroidRuntime: Shutting down VM
02-20 21:22:12.074 21906-21906/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.some.co, PID: 21906
    java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
        at android.widget.ListView.removeUnusedFixedViews(ListView.java:1990)
        at android.widget.ListView.layoutChildren(ListView.java:1851)
        at android.widget.AbsListView.onLayout(AbsListView.java:2164)
        at android.view.View.layout(View.java:19659)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
        at android.view.View.layout(View.java:19659)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19659)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
        at android.view.View.layout(View.java:19659)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
        at android.view.View.layout(View.java:19659)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19659)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(Unknown Source:68)
        at android.view.View.layout(View.java:19659)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:19659)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
        at android.view.View.layout(View.java:19659)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:761)
        at android.view.View.layout(View.java:19659)
        at android.view.ViewGroup.layout(ViewGroup.java:6075)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2496)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2212)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1392)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6752)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
02-20 21:22:12.078 21906-21906/? I/zygote: System.exit called, status: 2
02-20 21:22:12.078 21906-21906/? I/AndroidRuntime: VM exiting with result code 2, cleanup skipped.
02-20 21:22:12.097 909-1399/? W/InputDispatcher: channel '643fc74 com.some.co/com.some.co.modules.welcome.MyActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
02-20 21:22:12.097 909-1399/? E/InputDispatcher: channel '643fc74 com.some.co/com.some.co.modules.welcome.MyActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
02-20 21:22:12.098 909-949/? W/zygote64: kill(-21906, 9) failed: No such process
02-20 21:22:12.098 909-1664/? I/ActivityManager: Process com.some.co (pid 21906) has died: fore TOP 

Finally, here is the layout xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/med_adj_recon_list_item_background_frame"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/button_white_with_gray_border"
    android:layout_margin="@dimen/spacing_tiny">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:padding="@dimen/spacing_small"
        android:layout_gravity="center_vertical"
        android:layout_margin="@dimen/spacing_small">
        <TextView
            android:id="@+id/med_adj_recon_list_item_drug_info_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="@dimen/font_normal"
            android:textColor="@drawable/button_custom_med_adjustment_text_color"/>
        <TextView
            android:id="@+id/med_adj_recon_list_item_drug_dosage_info_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="@dimen/font_small"
            android:textColor="@drawable/button_custom_med_adjustment_text_color"/>
    </LinearLayout>
    <View
        android:id="@+id/med_adj_recon_list_item_divider"
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:background="@drawable/color_selector"/>
    <ImageView
        android:id="@+id/med_adj_recon_list_item_image_view"
        android:layout_width="@dimen/icon_width"
        android:layout_height="@dimen/icon_height"
        style="@style/IconImageViewBase"
        android:src="@drawable/tick_selector"/>
</LinearLayout>

Sometimes another pair of eyes helps. Greatly appreciate the help!

Here are the imports from the fragment Class, that load the ListView:

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.some.co.R;
import com.some.co.fragment.CommonFragment;
import com.some.co.modules.home.cards.CardFragment;
import com.some.co.modules.medadjustment.model.DeclineMedicationReason;
import com.some.co.modules.medadjustment.model.MedicationItem;
import com.some.co.modules.medadjustment.model.TextDrawable;

import java.lang.reflect.Type;
import java.util.List;

Here are the dependencies in the build.gradle:

final ANDROID_SDK_VERSION = '22.2.1'

dependencies {
    compile "com.android.support:design:$ANDROID_SDK_VERSION"
    compile "com.android.support:appcompat-v7:$ANDROID_SDK_VERSION"
    compile "com.android.support:support-v4:$ANDROID_SDK_VERSION"
    compile "com.android.support:cardview-v7:$ANDROID_SDK_VERSION"
    compile "com.android.support:recyclerview-v7:$ANDROID_SDK_VERSION"
    compile 'com.android.support:multidex:1.0.1'
    // only include the needed dependencies from play-services, 8.4 version above require SDK23.
    compile 'com.google.android.gms:play-services-auth:8.3.0'
    compile 'com.google.android.gms:play-services-base:8.3.0'
    compile 'com.google.android.gms:play-services-gcm:8.3.0'
    compile 'com.google.android.gms:play-services-analytics:8.3.0'
    compile 'com.google.android.gms:play-services-location:8.3.0'
    compile 'org.apache.commons:commons-lang3:3.3.2'
    compile 'org.greenrobot:eventbus:3.0.0'
    compile 'org.greenrobot:greendao-encryption:2.2.2'
    compile 'com.google.code.gson:gson:2.3.1'
    compile 'joda-time:joda-time:2.8.2'
    compile 'org.joda:joda-convert:1.4' // for proguard, b/c we're using joda-time (above)
    // for UI testing
    androidTestCompile 'com.jayway.android.robotium:robotium-solo:4.3.1'
    androidTestCompile 'com.squareup.spoon:spoon-client:1.7.0'
}

Also, the 'compileSdkVersion' and 'targetSdkVersion' are both set to 22

来源:https://stackoverflow.com/questions/49137138/android-7-8-only-classcastexception-layoutparams-cannot-be-cast-to-abslistv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!