使用Butterknife的NPE按钮

时间:2016-07-10 22:50:28

标签: android nullpointerexception butterknife

我正在尝试从edx.org(聊天Firebase,来自https://github.com/ykro/android-chat-firebase的完整代码)进行练习,我无法理解这个错误来自哪里,它是一个NPE,但是它让我失望,它在崩溃时崩溃应用程序在Genymotion Emulator上运行。

错误

java.lang.RuntimeException: Unable to start activity ComponentInfo{cat.edx_manel.exercises.chatfirebase/cat.edx_manel.exercises.chatfirebase.activities.LoginActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setEnabled(boolean)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)                                                                                     
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setEnabled(boolean)' on a null object reference
at cat.edx_manel.exercises.chatfirebase.activities.LoginActivity.setInputs(LoginActivity.java:114)
at cat.edx_manel.exercises.chatfirebase.activities.LoginActivity.disableInputs(LoginActivity.java:57)
at cat.edx_manel.exercises.chatfirebase.implementations.login.LoginPresenterImpl.checkForAuthenticateUser(LoginPresenterImpl.java:43)
at cat.edx_manel.exercises.chatfirebase.activities.LoginActivity.onCreate(LoginActivity.java:46)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:110)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
at android.app.ActivityThread.-wrap11(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method)

LOGINACTIVITY

public class LoginActivity extends AppCompatActivity implements LoginView {

@BindView(R.id.user)
EditText inputEmail;
@BindView(R.id.pass)
EditText inputPassword;
@BindView(R.id.signIn)
Button btnSignIn;
@BindView(R.id.signUp)
Button btnSignUp;
@BindView(R.id.progressBar)
ProgressBar progressBar;
@BindView(R.id.layoutMainContainer)
RelativeLayout container;

private LoginPresenter loginPresenter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    ButterKnife.bind(this);

    loginPresenter = new LoginPresenterImpl(this);
    loginPresenter.onCreate();
    loginPresenter.checkForAuthenticateUser();
}

@Override
protected void onDestroy() {
    loginPresenter.onDestroy();
    super.onDestroy();
}

@Override
public void disableInputs() {
    setInputs(false);
}

@Override
public void enableInputs() {
    setInputs(true);
    hideProgress();
}

@Override
public void showProgress() {
    progressBar.setVisibility(View.VISIBLE);
}

@Override
public void hideProgress() {
    progressBar.setVisibility(View.INVISIBLE);
}

@Override
@OnClick(R.id.signUp)
public void handleSignUp() {
    loginPresenter.registerNewUser(inputEmail.getText().toString(),
            inputPassword.getText().toString());
}
@Override
@OnClick(R.id.signIn)
public void handleSignIn() {
    loginPresenter.validateLogin(inputEmail.getText().toString(),
            inputPassword.getText().toString());
}

@Override
public void navigateToMainScreen() {
    startActivity(new Intent(this, ContactListActivity.class));
}

@Override
public void loginError(String error) {
    inputPassword.setText("");
    String msgError = String.format(getString(R.string.login_error_message_signin), error);
    inputPassword.setError(msgError);
}

@Override
public void newUserSuccess() {
    Snackbar.make(container, R.string.login_error_message_signup, Snackbar.LENGTH_SHORT).show();
}

@Override
public void newUserError(String error) {
    inputPassword.setText("");
    String msgError = String.format(getString(R.string.login_error_message_signup), error);
    inputPassword.setError(msgError);
}

private void setInputs(boolean enabled) {
    btnSignIn.setEnabled(enabled);
    btnSignUp.setEnabled(enabled);
    inputEmail.setEnabled(enabled);
    inputPassword.setEnabled(enabled);
    }
}

正如您所看到的,按钮是由Butterknife框架绑定的,但我不知道是什么导致它...

非常感谢你

已更新

布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layoutMainContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".activities.LoginActivity">

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:hint="Name"
        android:ems="10"
        android:id="@+id/user"/>

</android.support.design.widget.TextInputLayout>

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:hint="Password"
        android:ems="10"
        android:id="@+id/pass"/>

</android.support.design.widget.TextInputLayout>

<LinearLayout
    android:id="@+id/layoutButtons"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:id="@+id/signIn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/signUp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

<ProgressBar
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_below="@id/layoutButtons"/>

更新2

LOGINVIEW INTERFACE

public interface LoginView {
void enableInputs();
void disableInputs();
void showProgress();
void hideProgress();

void handleSignUp();
void handleSignIn();

void navigateToMainScreen();
void loginError(String error);

void newUserSuccess();
void newUserError(String error);
}

2 个答案:

答案 0 :(得分:1)

首先,here是我分享正确设置ButterKnife的答案之一。

考虑这个可能的问题:

你在这里压倒什么?

@Override //this line here
@OnClick(R.id.signUp)
public void handleSignUp() {
   loginPresenter.registerNewUser(inputEmail.getText().toString(),
        inputPassword.getText().toString());
}

@Override //this line here
@OnClick(R.id.signIn)
public void handleSignIn() {
   loginPresenter.validateLogin(inputEmail.getText().toString(),
        inputPassword.getText().toString());
}

尝试此操作而不使用覆盖:

@OnClick(R.id.signUp)
public void handleSignUp() {
   loginPresenter.registerNewUser(inputEmail.getText().toString(),
        inputPassword.getText().toString());
}


@OnClick(R.id.signIn)
public void handleSignIn() {
  loginPresenter.validateLogin(inputEmail.getText().toString(),
        inputPassword.getText().toString());
}

然后清理您的项目并再次运行!

我希望这有帮助!

答案 1 :(得分:-1)

我指的是ButterKnife tutorial的教程。我认为不应该使用@BindView,而应该是@Bind

@Bind(R.id.button)
Button button;
@Bind(R.id.textView)
TextView textView;
@Bind(R.id.radioButton)
RadioButton radioButton;
@Bind(R.id.checkBox)