【发布时间】:2017-09-07 21:21:13
【问题描述】:
所以我正在开发的应用程序遇到了问题,该应用程序仅在 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 及更高版本上,它不会发生在我测试过的任何其他设备上,我不知道是什么原因造成的,因为该应用程序在除牛轧糖设备之外的所有其他设备上运行良好。
这里是 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 及更高版本上按下时崩溃
嗯...所以我尝试了各种方法,甚至重写了代码,但这个问题仍然存在,可能是牛轧糖中的其他东西导致了这个,有什么想法吗?
【问题讨论】:
-
在打包阵列之前添加日志标签。在包裹之前检查它的长度,然后在包裹之后检查它的长度
-
查看this - 这是同一个问题,但如果您的问题仅在 7.0+ 上触发,则背后可能还有其他问题。但请查看订单并添加调试标签!
-
@LunarWatcher 我在问这个问题之前已经阅读了你提供的链接,我尝试按照描述重新格式化我的代码,但问题仍然存在,我的应用程序在 android 7 及更高版本上崩溃,但在以下任何情况下都可以正常工作.
-
@LunarWatcher 似乎毕竟是同一个问题,尽管为什么我的代码在旧版本的 android 上运行良好仍然是个谜,这让我想太多并寻找错误的地方,感谢大家的帮助!
标签: android parcelable android-7.0-nougat