更具体地说,我创建了一个创建帐户片段和一个登录片段。当切换到创建帐户片段中的横向时,它实际上返回到登录片段。然后,如果您尝试切换回肖像,那么应用程序崩溃。我看过类似的问题,但我无法从中得到任何结论。我非常感谢帮助人员!
CreateAccountFragment
package com.keyconsultant.parse.logintutorial;
/**
* Create an Account. Username is the primary method of login. Email is used for forgotten password recovery.
*
* @author Trey Robinson
*
*/
public class CreateAccountFragment extends BaseFragment implements OnClickListener {
protected static final String EXTRA_EMAIL = "com.keyconsultant.parse.logintutorial.fragment.extra.EMAIL";
protected static final String EXTRA_USERNAME = "com.keyconsultant.parse.logintutorial.fragment.extra.USERNAME";
protected static final String EXTRA_PASSWORD = "com.keyconsultant.parse.logintutorial.fragment.extra.PASSWORD";
protected static final String EXTRA_CONFIRM = "com.keyconsultant.parse.logintutorial.fragment.extra.CONFIRMPASSWORD";
private EditText mUserNameEditText;
private EditText mEmailEditText;
private EditText mPasswordEditText;
private EditText mConfirmPasswordEditText;
private Button mCreateAccountButton;
private String mEmail;
private String mUsername;
private String mPassword;
private String mConfirmPassword;
/**
* Factory method for creating fragment instances.
* @return
*/
public static CreateAccountFragment newInstance(){
return new CreateAccountFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_create_account, container, false);
mUserNameEditText = (EditText)view.findViewById(R.id.etUsername);
mEmailEditText = (EditText)view.findViewById(R.id.etEmail);
mPasswordEditText = (EditText)view.findViewById(R.id.etPassword);
mConfirmPasswordEditText = (EditText)view.findViewById(R.id.etPasswordConfirm);
mCreateAccountButton = (Button)view.findViewById(R.id.btnCreateAccount);
mCreateAccountButton.setOnClickListener(this);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(savedInstanceState != null){
mEmailEditText.setText(savedInstanceState.getString(EXTRA_EMAIL));
mUserNameEditText.setText(savedInstanceState.getString(EXTRA_USERNAME));
mPasswordEditText.setText(savedInstanceState.getString(EXTRA_PASSWORD));
mConfirmPasswordEditText.setText(savedInstanceState.getString(EXTRA_CONFIRM));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_EMAIL, mEmailEditText.getText().toString());
outState.putString(EXTRA_USERNAME, mUserNameEditText.getText().toString());
outState.putString(EXTRA_PASSWORD, mPasswordEditText.getText().toString());
outState.putString(EXTRA_CONFIRM, mConfirmPasswordEditText.getText().toString());
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnCreateAccount:
createAccount();
break;
default:
break;
}
}
/**
* Some front end validation is done that is not monitored by the service.
* If the form is complete then the information is passed to the service.
*/
private void createAccount(){
clearErrors();
boolean cancel = false;
View focusView = null;
// Store values at the time of the login attempt.
mEmail = mEmailEditText.getText().toString();
mUsername = mUserNameEditText.getText().toString();
mPassword = mPasswordEditText.getText().toString();
mConfirmPassword = mConfirmPasswordEditText.getText().toString();
// Check for a valid confirm password.
if (TextUtils.isEmpty(mConfirmPassword)) {
mConfirmPasswordEditText.setError(getString(R.string.error_field_required));
focusView = mConfirmPasswordEditText;
cancel = true;
} else if (mPassword != null && !mConfirmPassword.equals(mPassword)) {
mPasswordEditText.setError(getString(R.string.error_invalid_confirm_password));
focusView = mPasswordEditText;
cancel = true;
}
// Check for a valid password.
if (TextUtils.isEmpty(mPassword)) {
mPasswordEditText.setError(getString(R.string.error_field_required));
focusView = mPasswordEditText;
cancel = true;
} else if (mPassword.length() < 4) {
mPasswordEditText.setError(getString(R.string.error_invalid_password));
focusView = mPasswordEditText;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(mEmail)) {
mEmailEditText.setError(getString(R.string.error_field_required));
focusView = mEmailEditText;
cancel = true;
} else if (!mEmail.contains("@")) {
mEmailEditText.setError(getString(R.string.error_invalid_email));
focusView = mEmailEditText;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
UserManager.getInstance().signUp(mUsername.toLowerCase(Locale.getDefault()), mEmail, mPassword);
}
}
/**
* Remove error messages from all fields.
*/
private void clearErrors(){ mEmailEditText.setError(null);
mUserNameEditText.setError(null);
mPasswordEditText.setError(null);
mConfirmPasswordEditText.setError(null);
}
@Subscribe
public void onSignInError(AuthenticateUserErrorEvent event){
clearErrors();
switch (event.getErrorCode()) {
case ParseException.INVALID_EMAIL_ADDRESS:
mEmailEditText.setError(getString(R.string.error_invalid_email));
mEmailEditText.requestFocus();
break;
case ParseException.EMAIL_TAKEN:
mEmailEditText.setError(getString(R.string.error_duplicate_email));
mEmailEditText.requestFocus();
break;
case ParseException.USERNAME_TAKEN:
mUserNameEditText.setError(getString(R.string.error_duplicate_username));
mUserNameEditText.requestFocus();
break;
default:
UnknownErrorDialogFactory.createUnknownErrorDialog(this.getActivity()).show();
break;
}
}
}
LoginFragment
package com.keyconsultant.parse.logintutorial;
/**
* Fragment for logging in. Includes button for loading the Create account view.
*
* @author Trey Robinson
*
*/
public class LoginFragment extends BaseFragment {
public static final String EXTRA_USERNAME = "com.keyconsultant.parse.logintutorial.activity.extra.USERNAME";
public static final String EXTRA_PASSWORD = "com.keyconsultant.parse.logintutorial.activity.extra.PASSWORD";
// UI references.
private EditText mUserNameEditText;
private EditText mPasswordEditText;
/**
* Factory method for creating new fragments
*
* @return
*/
public static LoginFragment newInstance() {
return new LoginFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_login, container, false);
mUserNameEditText = (EditText) view.findViewById(R.id.username);
mPasswordEditText = (EditText) view.findViewById(R.id.password);
mPasswordEditText
.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int id,
KeyEvent keyEvent) {
if (id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
view.findViewById(R.id.sign_in_button).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
attemptLogin();
}
});
view.findViewById(R.id.register_button).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
createAccount();
}
});
view.findViewById(R.id.forgot_button).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
forgotPassword();
}
});
return view;
}
/**
* Open the forgotPassword dialog
*/
private void forgotPassword() {
FragmentManager fm = getActivity().getSupportFragmentManager();
ForgotPasswordDialogFragment forgotPasswordDialog = new ForgotPasswordDialogFragment();
forgotPasswordDialog.show(fm, null);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
mUserNameEditText.setText(savedInstanceState
.getString(EXTRA_USERNAME));
mPasswordEditText.setText(savedInstanceState
.getString(EXTRA_PASSWORD));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_USERNAME, mUserNameEditText.getText()
.toString());
outState.putString(EXTRA_PASSWORD, mPasswordEditText.getText()
.toString());
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
public void attemptLogin() {
clearErrors();
// Store values at the time of the login attempt.
String username = mUserNameEditText.getText().toString();
String password = mPasswordEditText.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password.
if (TextUtils.isEmpty(password)) {
mPasswordEditText
.setError(getString(R.string.error_field_required));
focusView = mPasswordEditText;
cancel = true;
} else if (password.length() < 4) {
mPasswordEditText
.setError(getString(R.string.error_invalid_password));
focusView = mPasswordEditText;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(username)) {
mUserNameEditText
.setError(getString(R.string.error_field_required));
focusView = mUserNameEditText;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// perform the user login attempt.
UserManager.getInstance().authenticate(
username.toLowerCase(Locale.getDefault()), password);
}
}
/**
* Load the create account view.
*/
private void createAccount() {
FragmentManager fragmentManager = getActivity()
.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.replace(
((ViewGroup) getView().getParent()).getId(),
CreateAccountFragment.newInstance());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
/**
* Remove all edit text errors
*/
private void clearErrors() {
mUserNameEditText.setError(null);
mPasswordEditText.setError(null);
}
@Subscribe
public void onSignInError(AuthenticateUserErrorEvent event) {
clearErrors();
switch (event.getErrorCode()) {
case ParseException.OBJECT_NOT_FOUND:
mPasswordEditText
.setError(getString(R.string.error_incorrect_password));
mPasswordEditText.requestFocus();
break;
default:
UnknownErrorDialogFactory.createUnknownErrorDialog(
this.getActivity()).show();
break;
}
}
}
以防万一你需要它是我的LoginActivity
package com.keyconsultant.parse.logintutorial;
/**
* Activity which displays a login screen to the user, offering registration as
* well. Based loosley on the default Login template.
*
* @author Trey Robinson
*/
public class LoginActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Parse.initialize(this, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction
.replace(R.id.main_view, LoginFragment.newInstance());
fragmentTransaction.commit();
parseCache();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity_login, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_forgot_password:
forgotPassword();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Open the forgotPassword dialog
*/
private void forgotPassword() {
FragmentManager fm = getSupportFragmentManager();
ForgotPasswordDialogFragment forgotPasswordDialog = new ForgotPasswordDialogFragment();
forgotPasswordDialog.show(fm, null);
}
@Subscribe
public void onSignInStart(AuthenticateUserStartEvent event) {
showProgress(true, getString(R.string.login_progress_signing_in));
}
@Subscribe
public void onSignInSuccess(AuthenticateUserSuccessEvent event) {
showProgress(false, getString(R.string.login_progress_signing_in));
Intent loginSuccess = new Intent(this, MainActivity.class);
startActivity(loginSuccess);
finish();
}
@Subscribe
public void onSignInError(AuthenticateUserErrorEvent event) {
showProgress(false, getString(R.string.login_progress_signing_in));
}
@Subscribe
public void onForgotPasswordStart(UserForgotPasswordStartEvent event) {
showProgress(true, getString(R.string.login_progress_signing_in));
}
@Subscribe
public void onForgotPasswordSuccess(UserForgotPasswordSuccessEvent event) {
showProgress(false, getString(R.string.login_progress_signing_in));
Toast toast = Toast.makeText(this,
"A password reset email has been sent.", Toast.LENGTH_LONG);
toast.show();
}
@Subscribe
public void onForgotPasswordError(UserForgotPasswordErrorEvent event) {
showProgress(false, getString(R.string.login_progress_signing_in));
Toast toast = Toast.makeText(this,
"An error has occured. Please try again.", Toast.LENGTH_LONG);
toast.show();
}
private void parseCache() {
Intent intent;
if (ParseUser.getCurrentUser() != null) {
intent = new Intent(this, MainActivity.class);
startActivity(intent);
this.finish();
}
}
}
这是logcat
01-10 16:09:05.796: I/Process(1923): Sending signal. PID: 1923 SIG: 9
01-10 17:00:57.513: I/Choreographer(1975): Skipped 111 frames! The application may be doing too much work on its main thread.
01-10 17:00:57.513: D/gralloc_goldfish(1975): Emulator without GPU emulation detected.
01-10 17:00:58.363: I/Choreographer(1975): Skipped 36 frames! The application may be doing too much work on its main thread.
01-10 17:00:58.833: I/Choreographer(1975): Skipped 37 frames! The application may be doing too much work on its main thread.
01-10 17:00:59.163: I/Choreographer(1975): Skipped 32 frames! The application may be doing too much work on its main thread.
01-10 17:01:11.253: D/dalvikvm(1975): GC_FOR_ALLOC freed 74K, 5% free 5533K/5820K, paused 2ms, total 3ms
01-10 17:01:11.253: I/dalvikvm-heap(1975): Grow heap (frag case) to 7.992MB for 2500620-byte allocation
01-10 17:01:11.263: D/dalvikvm(1975): GC_FOR_ALLOC freed 2K, 4% free 7972K/8264K, paused 2ms, total 3ms
01-10 17:01:11.273: D/dalvikvm(1975): GC_FOR_ALLOC freed <1K, 4% free 7972K/8264K, paused 3ms, total 4ms
01-10 17:01:11.273: I/dalvikvm-heap(1975): Grow heap (frag case) to 10.696MB for 2838540-byte allocation
01-10 17:01:11.283: D/dalvikvm(1975): GC_FOR_ALLOC freed 0K, 3% free 10744K/11040K, paused 4ms, total 4ms
01-10 17:01:15.953: D/dalvikvm(1975): GC_FOR_ALLOC freed 5268K, 45% free 6880K/12360K, paused 0ms, total 3ms
01-10 17:01:15.953: I/dalvikvm-heap(1975): Grow heap (frag case) to 8.489MB for 1642512-byte allocation
01-10 17:01:15.973: D/dalvikvm(1975): GC_FOR_ALLOC freed <1K, 32% free 8483K/12360K, paused 13ms, total 13ms
01-10 17:01:16.053: I/Choreographer(1975): Skipped 42 frames! The application may be doing too much work on its main thread.
01-10 17:01:17.473: I/Choreographer(1975): Skipped 58 frames! The application may be doing too much work on its main thread.
01-10 17:01:18.043: I/Choreographer(1975): Skipped 57 frames! The application may be doing too much work on its main thread.
01-10 17:01:23.363: D/AndroidRuntime(1975): Shutting down VM
01-10 17:01:23.363: W/dalvikvm(1975): threadid=1: thread exiting with uncaught exception (group=0xb0f2e648)
01-10 17:01:23.363: E/AndroidRuntime(1975): FATAL EXCEPTION: main
01-10 17:01:23.363: E/AndroidRuntime(1975): java.lang.NullPointerException
01-10 17:01:23.363: E/AndroidRuntime(1975): at com.keyconsultant.parse.logintutorial.LoginFragment.onSaveInstanceState(LoginFragment.java:119)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.support.v4.app.Fragment.performSaveInstanceState(Fragment.java:1607)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.support.v4.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1587)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1655)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:527)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.app.Activity.performSaveInstanceState(Activity.java:1147)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1223)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3714)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.app.ActivityThread.access$700(ActivityThread.java:141)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.os.Handler.dispatchMessage(Handler.java:99)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.os.Looper.loop(Looper.java:137)
01-10 17:01:23.363: E/AndroidRuntime(1975): at android.app.ActivityThread.main(ActivityThread.java:5103)
01-10 17:01:23.363: E/AndroidRuntime(1975): at java.lang.reflect.Method.invokeNative(Native Method)
01-10 17:01:23.363: E/AndroidRuntime(1975): at java.lang.reflect.Method.invoke(Method.java:525)
01-10 17:01:23.363: E/AndroidRuntime(1975): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
01-10 17:01:23.363: E/AndroidRuntime(1975): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-10 17:01:23.363: E/AndroidRuntime(1975): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:0)
您的logcat显示您在LoginFragment.onSaveInstanceState()
首先,使super.onSaveInstanceState()
成为最后一行,而不是现在的第一行。
然后确保您没有mUserName和mPassword及其文本nulls
在某处将mUserName和密码文本初始化为“”,错误应该消失了。我想。