Android Parcelable readStringArray()java.lang.RuntimeException:Nougat上的错误数组长度

时间:2017-04-12 08:02:19

标签: android parcelable android-7.0-nougat

所以我正在处理的应用遇到问题,该应用在Android 7及更高版本上崩溃 。来自logcat的错误似乎发生在我的parcelable类上。

这是发生崩溃的点(具有parcelable的类):

public class LookupCriteriaBean implements Parcelable, Serializable {
private String lookupCode;
private String lookupField;
private String lookupDisplayName;
private String lookupSearchValue;

public LookupCriteriaBean(){        
}

public LookupCriteriaBean(String s) {
    if (s == null || "".equals(s.trim()))
throw new IllegalArgumentException("Invalid lookup criteria setting from server!");

    int idx = 0;
    String[] arrS = Tool.split(s, Global.DELIMETER_DATA);
    lookupCode = arrS[idx++];
    lookupField = arrS[idx++];
    lookupDisplayName = arrS[idx++];
}

public LookupCriteriaBean(Parcel in) {
    String[] arrS = new String[LookupCriteriaBean.class.getFields().length];
    in.readStringArray(arrS);

    int idx = 0;
    lookupCode = arrS[idx++];
    lookupField = arrS[idx++];
    lookupDisplayName = arrS[idx++];
}

public String getLookupCode() {
    return lookupCode;
}

public void setLookupCode(String lookupCode) {
    this.lookupCode = lookupCode;
}

public String getLookupField() {
    return lookupField;
}

public void setLookupField(String lookupField) {
    this.lookupField = lookupField;
}

public String getLookupDisplayName() {
    return lookupDisplayName;
}

public void setLookupDisplayName(String lookupDisplayName) {
    this.lookupDisplayName = lookupDisplayName;
}

public String toString() {
    return lookupDisplayName;
}

public int describeContents() {
    return 0;
}

public void writeToParcel(Parcel dest, int flags) {
    dest.writeStringArray(new String[] { lookupCode, lookupField, lookupDisplayName });
}

public static final Parcelable.Creator<LookupCriteriaBean> CREATOR = new Parcelable.Creator<LookupCriteriaBean>() {

    public LookupCriteriaBean createFromParcel(Parcel source) {
        return new LookupCriteriaBean(source);
    }

    public LookupCriteriaBean[] newArray(int size) {
        return new LookupCriteriaBean[size];
    }
};

public String getLookupSearchValue() {
    return lookupSearchValue;
}

public void setLookupSearchValue(String lookupSearchValue) {
    this.lookupSearchValue = lookupSearchValue;
    }
}

触发崩溃的行是in.readStringArray(arrS);

问题是崩溃只发生在Android 7及更高版本上,它不会发生在我测试的任何其他设备上,我不知道是什么导致了这个,因为除了牛轧糖设备之外的其他一切应用运行正常。< / p>

这是logcat输出:

E/AndroidRuntime( 3868): FATAL EXCEPTION: main

E/AndroidRuntime( 3868): Process: com.adins.msmfif, PID: 3868

E/AndroidRuntime( 3868): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.adins.msmfif/com.adins.msm.LookupActivity}: java.lang.RuntimeException: bad array lengths

E/AndroidRuntime( 3868):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)

E/AndroidRuntime( 3868):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)

E/AndroidRuntime( 3868):    at android.app.ActivityThread.-wrap12(ActivityThread.java)

E/AndroidRuntime( 3868):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)

E/AndroidRuntime( 3868):    at android.os.Handler.dispatchMessage(Handler.java:102)

E/AndroidRuntime( 3868):    at android.os.Looper.loop(Looper.java:154)

E/AndroidRuntime( 3868):    at android.app.ActivityThread.main(ActivityThread.java:6077)

E/AndroidRuntime( 3868):    at java.lang.reflect.Method.invoke(Native Method)

E/AndroidRuntime( 3868):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)

E/AndroidRuntime( 3868):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

E/AndroidRuntime( 3868): Caused by: java.lang.RuntimeException: bad array lengths

E/AndroidRuntime( 3868):    at android.os.Parcel.readStringArray(Parcel.java:1125)

E/AndroidRuntime( 3868):    at com.adins.msm.model.LookupCriteriaBean.<init>(LookupCriteriaBean.java:33)

E/AndroidRuntime( 3868):    at com.adins.msm.model.LookupCriteriaBean$1.createFromParcel(LookupCriteriaBean.java:80)

E/AndroidRuntime( 3868):    at com.adins.msm.model.LookupCriteriaBean$1.createFromParcel(LookupCriteriaBean.java:1)

E/AndroidRuntime( 3868):    at android.os.Parcel.readParcelable(Parcel.java:2470)

E/AndroidRuntime( 3868):    at android.os.Parcel.readValue(Parcel.java:2364)

E/AndroidRuntime( 3868):    at android.os.Parcel.readListInternal(Parcel.java:2778)

E/AndroidRuntime( 3868):    at android.os.Parcel.readArrayList(Parcel.java:2035)

E/AndroidRuntime( 3868):    at android.os.Parcel.readValue(Parcel.java:2385)

E/AndroidRuntime( 3868):    at android.os.Parcel.readArrayMapInternal(Parcel.java:2717)

E/AndroidRuntime( 3868):    at android.os.BaseBundle.unparcel(BaseBundle.java:269)

E/AndroidRuntime( 3868):    at android.os.Bundle.getParcelableArrayList(Bundle.java:886)

E/AndroidRuntime( 3868):    at com.adins.msm.LookupActivity.initialize(LookupActivity.java:59)

E/AndroidRuntime( 3868):    at com.adins.msm.LookupActivity.onCreate(LookupActivity.java:49)

E/AndroidRuntime( 3868):    at android.app.Activity.performCreate(Activity.java:6662)

E/AndroidRuntime( 3868):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)

E/AndroidRuntime( 3868):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)

感谢任何帮助

以下是我的活动中的代码,其中包含触发错误的按钮

public class LookupActivity extends Activity implements OnClickListener {
private ArrayAdapter<LookupCriteriaBean> listAdapter;
private String lovType;
public final LayoutParams defLayout = new LayoutParams(
        LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);

private QuestionBean bean = null;
private LinearLayout questionContainer;
private int totalCriteia = 1;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.lookup);
    initialize();

    //---change to portrait mode---
//        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

private void initialize() {
    setClickListener();

    Bundle extras = getIntent().getExtras();
    ArrayList<LookupCriteriaBean> list = extras.getParcelableArrayList(
            Global.BUND_KEY_LOV_CRITERIA);
    listAdapter = new ArrayAdapter<LookupCriteriaBean>(this,
            android.R.layout.simple_spinner_item, list);
    listAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);


     bean = DynamicSurveyActivity.getQuestionInFocus();
    lovType = bean.getAnswerType();

    if(bean.getTextMaxLength()!=0){
        totalCriteia = bean.getTextMaxLength();
    }
    questionContainer = (LinearLayout) findViewById(R.id.sub_search_bar);
    questionContainer.setOrientation(LinearLayout.VERTICAL);


    for (int i = 0; i < totalCriteia; i++) {
        ViewGroup view = generateDropdownDesc(this,listAdapter, i);
        questionContainer.addView(view, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);               
    }
}


private void setClickListener() {
    Button btnSearch = (Button) findViewById(R.id.search_button);
    btnSearch.setOnClickListener(this);
}

public void onClick(View v) {       
    Button btn = (Button) v;
    int id = btn.getId();
    if (R.id.search_button == id) {
        String lookupSearchValue = this.getSearchValue().trim();
    //  if (this.validateSearchValue(lookupSearchValue)) {

            LookupCriteriaBean lookupCriteriaBean[] =  new LookupCriteriaBean[totalCriteia];

            for (int i = 0; i < totalCriteia; i++) {

                LinearLayout qContainer = (LinearLayout) questionContainer.getChildAt(i);
                Spinner spinnerCriteria = (Spinner) qContainer.getChildAt(0);
                int posSpinner = spinnerCriteria.getSelectedItemPosition();

                EditText editText = (EditText) qContainer.getChildAt(1);

                LookupCriteriaBean beanCriteria = listAdapter.getItem(posSpinner);
                beanCriteria.setLookupSearchValue(editText.getText().toString().trim());

                lookupCriteriaBean[i] = beanCriteria;
            }

            Map<String, Object> paramMap = new HashMap<String, Object>();
            paramMap.put(Global.MAP_KEY_LOOKUP_CRITERIA, mergeLookupCriteriaBean(lookupCriteriaBean));

            if (Global.AT_LOV.equals(lovType)) {
                new LookupResultTask(this, getString(R.string.progressWait))
                    .execute(paramMap);
            }
            else if (Global.AT_LOV_W_FILTER.equals(lovType)) {
                LookupManager lookupManager = new LookupManager();
                QuestionBean qBean = DynamicSurveyActivity.getQuestionInFocus();
                List<QuestionBean> listOfQuestion = DynamicSurveyActivity.getListOfQuestion();

                lookupManager.setFilterValue(listOfQuestion, qBean);

                paramMap.put(Global.MAP_KEY_LOOKUP_FILTER, qBean.getLovFilters());
                new LookupResultTask(this, getString(R.string.progressWait))
                    .execute();
            }
    //  }
    }
}


private String getSearchValue() {
            String value = "";

    for (int i = 0; i < totalCriteia; i++) {        
        LinearLayout qContainer = (LinearLayout) questionContainer.getChildAt(i);               
        EditText editText = (EditText) qContainer.getChildAt(1);
        value = value+editText.getText().toString().trim(); 
    }

    return value;
}

private boolean validateSearchValue(String searchValue) {
    boolean valid = true;

    List<String> errMessage = new ArrayList<String>();

    if ("".equals(searchValue)) {
        errMessage.add(getString(R.string.lovHint) + " " + getString(R.string.msgRequired));
    }

    if (errMessage.size() > 0) {
        valid = false;

        String[] msg = (String[]) errMessage.toArray(new String[errMessage.size()]);
        String alert = Tool.implode(msg, "\n");
        Toast.makeText(this, alert, Toast.LENGTH_LONG).show();
    }       

    return valid;
}

public LinearLayout generateDropdownDesc(Activity activity,
        ArrayAdapter<LookupCriteriaBean> listAdapter, int pos) {
    LinearLayout container = new LinearLayout(activity);
    container.setOrientation(LinearLayout.VERTICAL);

    int totalOption = listAdapter.getCount();


        final String prompt = getString(R.string.lovCriteria);
        Spinner spinner = new Spinner(activity);
        EditText desc = new EditText(activity);     
        desc.setHint(string.lovHint);
        spinner.setAdapter(listAdapter);
        spinner.setPrompt(prompt);

    if (pos < totalOption) {
        spinner.setSelection(pos);
    } else {
        int tempPos = (pos%totalOption);

        spinner.setSelection(tempPos);
    }


        container.addView(spinner, defLayout);
        container.addView(desc, defLayout);

    return container;
}

private LookupCriteriaBean mergeLookupCriteriaBean(LookupCriteriaBean[] lookupCriteriaBeanArray) {
    LookupCriteriaBean lookupCriteriaBean = new LookupCriteriaBean();

    lookupCriteriaBean.setLookupCode(lookupCriteriaBeanArray[0].getLookupCode());
    lookupCriteriaBean.setLookupDisplayName(lookupCriteriaBeanArray[0].getLookupDisplayName());
    lookupCriteriaBean.setLookupField(lookupCriteriaBeanArray[0].getLookupField());
    lookupCriteriaBean.setLookupSearchValue(lookupCriteriaBeanArray[0].getLookupSearchValue());


    if (lookupCriteriaBeanArray.length > 1) {
        for (int i = 1; i < lookupCriteriaBeanArray.length; i++) {
            String code = lookupCriteriaBean.getLookupCode();
            String field = lookupCriteriaBean.getLookupField();
            String searchValue = lookupCriteriaBean.getLookupSearchValue();

            lookupCriteriaBean.setLookupCode(code
                    + Global.DELIMETER_SUBSUBDATA
                    + lookupCriteriaBeanArray[i].getLookupCode());
            lookupCriteriaBean.setLookupField(field
                    + Global.DELIMETER_SUBSUBDATA
                    + lookupCriteriaBeanArray[i].getLookupField());
            lookupCriteriaBean.setLookupSearchValue(searchValue
                    + Global.DELIMETER_SUBSUBDATA
                    + lookupCriteriaBeanArray[i].getLookupSearchValue());

        }
    }

    return lookupCriteriaBean;

}

按下R.id.search_button按钮时,在Android 7及更高版本上按下崩溃

嗯...所以我尝试了各种各样的事情,甚至重写了代码,但这个问题仍然存在,它可能是牛轧糖中的其他东西导致了这个,任何想法?

2 个答案:

答案 0 :(得分:0)

重写我的代码几次后引用其他答案同样的问题,拆分我用来分隔字符串的字符串数组修复了这个问题,但是我仍然不知道为什么getStringArray(arrS)只会在android上崩溃7及以上。

我确实想知道为什么我的代码仍然可以在较低版本上运行。

因此,所有字段都按照正确的顺序分别访问它们,然后就可以了。

这是我的固定代码:

---------------snip---------------------------------

public LookupCriteriaBean(Parcel in) {
    lookupCode = in.readString();
    lookupField = in.readString();
    lookupDisplayName = in.readString();
    }

public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(lookupCode);
    dest.writeString(lookupField);
    dest.writeString(lookupDisplayName);
}

-----------------snip--------------------------------

答案 1 :(得分:-1)

小提示!

您可以使用以下库来简化parcelable的使用。

https://github.com/codepath/android_guides/wiki/Using-Parceler

如果您查看www.parcelabler.com,这可能是一个解决方案

public class LookupCriteriaBean implements Parcelable, Serializable {
private String lookupCode;
private String lookupField;
private String lookupDisplayName;
private String lookupSearchValue;

public String getLookupSearchValue() {
    return lookupSearchValue;
}

public void setLookupSearchValue(String lookupSearchValue) {
    this.lookupSearchValue = lookupSearchValue;
    }

public String getLookupCode() {
    return lookupCode;
}

public void setLookupCode(String lookupCode) {
    this.lookupCode = lookupCode;
}

public String getLookupField() {
    return lookupField;
}

public void setLookupField(String lookupField) {
    this.lookupField = lookupField;
}

public String getLookupDisplayName() {
    return lookupDisplayName;
}

public void setLookupDisplayName(String lookupDisplayName) {
    this.lookupDisplayName = lookupDisplayName;
}

public String toString() {
    return lookupDisplayName;
}

//
//  Here is the implementation of parcelable
//
    protected LookupCriteriaBean(Parcel in) {
        lookupCode = in.readString();
        lookupField = in.readString();
        lookupDisplayName = in.readString();
        lookupSearchValue = in.readString();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(lookupCode);
        dest.writeString(lookupField);
        dest.writeString(lookupDisplayName);
        dest.writeString(lookupSearchValue);
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<LookupCriteriaBean> CREATOR = new Parcelable.Creator<LookupCriteriaBean>() {
        @Override
        public LookupCriteriaBean createFromParcel(Parcel in) {
            return new LookupCriteriaBean(in);
        }

        @Override
        public LookupCriteriaBean[] newArray(int size) {
            return new LookupCriteriaBean[size];
        }
    };
}