1. ホーム
  2. ジャワ

[解決済み] IllegalStateException: 別のページに移行しようとすると、android:onClickのメソッドを実行できない?

2022-03-03 05:34:37

質問

大学のインターンシップの関係で、あるアプリ(講師の推薦で他の学生の最終学年のプロジェクトを引き継いだもの)を作っているのですが、メインメニュー画面からログイン画面への移行に問題があります。

(ログインページのみに問題があり、アプリケーションのメインメニューから登録ページまでは全く問題がありません。したがって、問題はxmlファイルかLoginActivity.javaのどちらかにあると思われますが、方法はわかりません)。

logcatのエラーはこのように表示されます。

TAL EXCEPTION: main
Process: com.finchvpn.androidcloudpark, PID: 1579
    java.lang.IllegalStateException: Could not execute method for android:onClick
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:389)
    at android.view.View.performClick(View.java:4438)
    at android.view.View$PerformClick.run(View.java:18422)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5001)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384)
    at android.view.View.performClick(View.java:4438) 
    at android.view.View$PerformClick.run(View.java:18422) 
    at android.os.Handler.handleCallback(Handler.java:733) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:136) 
    at android.app.ActivityThread.main(ActivityThread.java:5001) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:515) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.NullPointerException
    at com.finchvpn.androidcloudpark.MainActivity.loginButtonClick(MainActivity.java:74)

以下、関連するxmlファイルです。

メインメニューのxmlファイルです。

<?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"                xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/asd2">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar3"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@drawable/side_nav_bar"
            app:popupTheme="@style/PopupOverlay" />

        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="239dp"
            android:layout_height="73dp"
            android:layout_gravity="center"
            android:layout_marginBottom="8dp"
            android:text="CloudPark.my"
            android:textColor="@color/md_white_1000"
            android:textSize="14pt"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.11"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.014" />

        <ImageButton
            android:id="@+id/loginButtonPic"
            android:layout_width="132dp"
            android:layout_height="120dp"
            android:layout_gravity="end"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_weight="1"
            android:background="@null"
            android:onClick="loginButtonClick"
            android:scaleType="fitCenter"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.19"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.559"
            app:srcCompat="@drawable/loginnew2"
            tools:ignore="ContentDescription" />

        <ImageButton
            android:id="@+id/RegisterButtonPic"    
            android:layout_width="132dp"
            android:layout_height="120dp"
            android:layout_gravity="end"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_weight="1"
            android:background="@null"
            android:onClick="registerButtonClick"
            android:scaleType="fitCenter"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.813"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.559"
            app:srcCompat="@drawable/registernew1"
            tools:ignore="ContentDescription" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="279dp"
            android:layout_height="63dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:text="CloudPark, the next generation parking app."
            android:textColor="@color/md_white_1000"
            android:textSize="10pt"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.505"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.181" />

    </android.support.constraint.ConstraintLayout>

ログイン用xmlファイルです。

<?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/asd2">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar3"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@drawable/side_nav_bar"
            app:popupTheme="@style/PopupOverlay" />

       <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="307dp"
            android:layout_height="91dp"
            android:layout_gravity="center"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp"
            android:text="Login"
            android:textColor="@color/md_white_1000"
            android:textSize="14pt"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.506"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.0" />

       <TextView
            android:id="@+id/textView2"
            android:layout_width="281dp"
            android:layout_height="50dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:text="Enter your credentials to access CloudPark."
            android:textColor="@color/md_white_1000"
            android:textSize="10pt"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.505"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.181" />

       <EditText
            android:id="@+id/textUsername"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp"
            android:ems="10"
            android:hint="Username"
            android:inputType="textEmailAddress"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.503"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.352" />

       <EditText
            android:id="@+id/textPassword"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:ems="10"
            android:hint="Password"
            android:inputType="textPassword"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.503"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.443" />

      <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp"
            android:background="#0026FF"
            android:onClick="loginButtonClick"
            android:text="Login to CloudPark"
            android:textColor="#FFFF"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.687" />

      <android.support.constraint.Guideline
            android:id="@+id/guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_begin="20dp" />

  </android.support.constraint.ConstraintLayout>

LoginActivity.java

public class LoginActivity extends AppCompatActivity {

    private EditText textUsername;
    private EditText txtPassword;
    private static RestClient restClient = new RestClient();

    private SharedPreferences.Editor sharedPreferencesEditor;

    @SuppressLint("CommitPrefEdits")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        try {
            Toolbar toolbar = findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);

            Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(true);
        } catch (Exception e) {
        }

        textUsername = findViewById(R.id.textUsername);
        txtPassword = findViewById(R.id.textPassword);
        SharedPreferences sharedPreferences = getSharedPreferences("UserInfo", 0);
        sharedPreferencesEditor = sharedPreferences.edit();
            textUsername.setText(sharedPreferences.getString("textUsername", ""));
            txtPassword.setText(sharedPreferences.getString("txtPassword", ""));
    }

    public static RestClient getRestClient() {
        return restClient;
    }

    public void loginButtonClick(View v) {
        if (!textUsername.getText().toString().equals("") && !txtPassword.getText().toString().equals("")) {
            apiPostLogin(Constants.ANDROID_KEY + ":" + textUsername.getText().toString() + ":" + txtPassword.getText().toString());
            sharedPreferencesEditor.putString("textUsername", textUsername.getText().toString());
            sharedPreferencesEditor.putString("txtPassword", txtPassword.getText().toString());
            sharedPreferencesEditor.commit();
        } else {
            Toast.makeText(LoginActivity.this, "NULL", Toast.LENGTH_LONG).show();
        }
    }

    private void apiPostLogin(String data) {
        final ProgressDialog progress = new ProgressDialog(this);
        progress.setTitle("Logging in");
        progress.setMessage("Please wait ...");
        progress.setCancelable(false); // disable dismiss by tapping outside of the dialog
        progress.show();
        Call<ResponseBody> call = getRestClient().getLoginService().postLogin(data);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.isSuccessful() && response.body() != null) {
                    try {
                        String data = response.body().string();
                        JSONObject jsonObject = new JSONObject(data);
                        Constants.uid = Integer.parseInt(jsonObject.getString("id"));
                        Constants.username = jsonObject.getString("username");
                        Constants.email = jsonObject.getString("email");
                        Constants.credit = jsonObject.getString("credit");
                        Constants.qr_code = jsonObject.getString("qr_code");
                        Constants.created_at = jsonObject.getString("created_at");
                        Constants.updated_at = jsonObject.getString("updated_at");
                        Toast.makeText(LoginActivity.this, "apiPostLogin onResponse <<<< \r\n\r\n" + jsonObject.toString(), Toast.LENGTH_LONG).show();
                        Intent returnIntent = new Intent();
                        setResult(Activity.RESULT_CANCELED, returnIntent);
                        finish();
                    } catch (IOException | JSONException e) {
                        e.printStackTrace();
                    }
                }
                progress.dismiss();
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Toast.makeText(LoginActivity.this, "Incorrect username/password, please try again." + t.getMessage(), Toast.LENGTH_LONG).show();
                progress.dismiss();
            }
        });
    }
}

解決方法は?

の衝突が問題なのではと思います。 android:onClick="loginButtonClick" を、メインメニューxmlとログインxmlに追加しました。

に依存してはいけません。 android:onClick 属性は、ビューのクリックを処理するために使用されます。というのも android:onClick を処理するメソッドが、そのメソッドに対応したものであるかどうかを確認することはできません。 onClick は動作します。あなたのコードがViewに接続されていることを確認する正確なメカニズムはありません。もうひとつの問題は android:onClick はFragmentでは動作しません。 . そこで、私は android:onClick はバッドプラクティスです。

この問題を解決するには setOnClickListener をViewに追加します。と組み合わせて findViewById に不正な ID を指定した場合、常にエラーが表示されるため、コードがより堅牢になります。 findViewById . コードをより堅牢にし、id の衝突を避けるには、ビューの id をわかりやすい名前にする必要があります。このような命名規則を使用します。

layout name + _ + What the view for + _ + type of view

例えば、ログイン用のxmlには、次のようなものを使用できます。

....

<Button
    android:id="@+id/login_cloudpark_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp"
    android:background="#0026FF"
    android:text="Login to CloudPark"
    android:textColor="#FFFF"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.687" />

<android.support.constraint.Guideline
    android:id="@+id/login_begin_gdl"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_begin="20dp" />

...

を使用すると、それを findViewById :

public class LoginActivity extends AppCompatActivity {

  ...

  private Button mBtnLogin;

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

    ...

    mBtnLogin = findViewById(R.id.login_cloudpark_btn);
  }
}

にclickListenerを追加します。 mBtnLogin :

mbtnLogin.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
         // place your clicking handle code here.
      }
    });

上記のようにすることで、xmlのViewとロジックをきれいに分離することができます。