我正在开发一个Android应用程序,我正在使用Fabric / Crashlytics推送给测试人员。
我自己在2台物理设备上彻底测试了我的应用程序:
我最近将一个版本的应用程序推送给了一个测试人员。她的设备是:
我正在尝试使用登录/注册Activity
/ Fragment
系列。我通过Crashlytics收到崩溃报告,其中包含以下信息:
以下是日志的摘录:
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.company.app/com.company.app.LoginActivity}: android.view.InflateException: Binary XML file line #70: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2693)
... other lines
Caused by android.view.InflateException: Binary XML file line #70: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:770)
... other lines
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
at com.company.app.LoginActivity.onCreate(LoginActivity.java:25)
at android.app.Activity.performCreate(Activity.java:6289)
... other lines
Caused by java.lang.IllegalStateException: Fragment com.company.app.LoginFragment did not create a view.
at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2160)
at android.app.Activity.onCreateView(Activity.java:5610)
at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:34)
at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:79)
... other lines
at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:256)
at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:109)
at com.company.app.LoginActivity.onCreate(LoginActivity.java:25)
at android.app.Activity.performCreate(Activity.java:6289)
... other lines
以下是我的LoginActivity和LoginFragment文件的精简版本:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout>
<LinearLayout>
<android.support.v7.widget.Toolbar>
<LinearLayout>
<TextView />
<ImageButton />
</LinearLayout>
</android.support.v7.widget.Toolbar>
<FrameLayout>
<fragment
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.company.app.LoginFragment"
tools:layout="@layout/fragment_login" />
<View />
</FrameLayout>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// This next line causes the error
setContentView(R.layout.activity_login);
ImageButton infoButton = (ImageButton)findViewById(R.id.info_button);
infoButton.setColorFilter(ContextCompat.getColor(this, R.color.colorPrimary), PorterDuff.Mode.SRC_ATOP);
infoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mUserCreationFragment != null) {
mUserCreationFragment.showInfo();
} else if (mEnterCodesFragment != null) {
mEnterCodesFragment.showInfo();
} else if (mLoginFragment != null) {
mLoginFragment.showInfo();
}
}
});
mToolbar = (Toolbar)findViewById(R.id.toolbar);
mTitleLabel = (TextView)findViewById(R.id.title_label);
mTitleLabel.setText(getString(R.string.login_string));
setSupportActionBar(mToolbar);
}
<com.company.app.SlidingFrameLayout>
<ScrollView>
<LinearLayout>
<TextView />
<Button />
<android.support.design.widget.TextInputLayout>
<EditText />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout>
<EditText />
</android.support.design.widget.TextInputLayout>
<Button />
<Button />
</LinearLayout>
</ScrollView>
</com.company.app.SlidingFrameLayout>
Line 69 <android.support.design.widget.TextInputLayout
Line 70 android:layout_height="wrap_content"
Line 71 android:layout_width="match_parent"
Line 72 >
Line 73 <EditText
Line 74 android:id="@+id/password"
Line 75 android:hint="@string/prompt_password"
Line 76 android:imeOptions="actionDone"
Line 77 android:inputType="textPassword"
Line 78 android:layout_height="wrap_content"
Line 79 android:layout_width="match_parent"
Line 80 android:maxLines="1"
Line 71 android:singleLine="true"
Line 82 android:textSize="16sp"
Line 83
Line 84 />
Line 85
Line 86 </android.support.design.widget.TextInputLayout>
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_login, container, false);
mPasswordView = (EditText)rootView.findViewById(R.id.password);
Button registerButton = (Button)rootView.findViewById(R.id.register_button);
TextView registerLabel = (TextView)rootView.findViewById(R.id.register_label);
mSignInButton = (Button)rootView.findViewById(R.id.sign_in_button);
mUserNameView = (EditText)rootView.findViewById(R.id.user_name);
LoginActivity activity = (LoginActivity)getActivity();
activity.setLoginFragment(this);
checkIfComplete();
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
if (mComplete) {
beginLogin();
return true;
}
}
return false;
}
});
mPasswordView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
checkIfComplete();
}
@Override
public void afterTextChanged(Editable s) {}
});
registerButton.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.colorPrimaryDark));
registerButton.setTextColor(ContextCompat.getColor(getActivity(), R.color.colorTextEnabled));
registerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EnterCodesFragment fragment = new EnterCodesFragment();
getFragmentManager()
.beginTransaction()
.setCustomAnimations(R.animator.slide_in_from_right, R.animator.slide_out_to_left, R.animator.slide_in_from_left, R.animator.slide_out_to_right)
.replace(R.id.container, fragment, getString(R.string.basic_information_title_string))
.addToBackStack(getString(R.string.enter_codes_fragment_title))
.commit();
}
});
registerLabel.setTextColor(ContextCompat.getColor(getActivity(), R.color.colorTextDisabled));
mSignInButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
beginLogin();
}
});
Button forgotPasswordButton = (Button)rootView.findViewById(R.id.forgot_password_button);
forgotPasswordButton.setPaintFlags(forgotPasswordButton.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
forgotPasswordButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final View view = View.inflate(getActivity(), R.layout.reset_password_dialog, null);
final EightyPercentDialog dialog = new EightyPercentDialog(getActivity());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(view);
final EditText emailEditText = (EditText)view.findViewById(R.id.email_edit_text);
Button cancelButton = (Button)view.findViewById(R.id.cancel_button);
Button okButton = (Button)view.findViewById(R.id.ok_button);
cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String email = emailEditText.getText().toString();
dialog.dismiss();
sendPasswordResetEmail(email);
}
});
dialog.show();
}
});
mUserNameView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
checkIfComplete();
}
@Override
public void afterTextChanged(Editable s) {}
});
return rootView;
}
我在这里查看了与InflateException
相关的其他几篇帖子,但这些帖子似乎都不适用于我的情况。
例如:
AppCompatActivity
有关,但到目前为止我还没有看到任何有问题的内容。所以,基本上,让我感到困惑的是我在任何一台设备上都没有这个问题,而且我不太了解Android以便在她的系统上看到任何东西(也是运行5.0.1的三星手机) ,就像我的那样)会有问题。有什么我想念的吗?如何找出实际问题是什么?