uemurm
uemurm

Reputation: 21

Calling findViewById() from an object

I'm practising an android app development and writing score board of billiards.

public class Board extends AppCompatActivity {
    private Rack rack;
    private int currentPlayer;

    public Board() {
        rack = new Rack();
        currentPlayer = 0;
    }

    public void setCurrentPlayer(int n) {
        currentPlayer = n;
    }

    public void pocket(int ballNumber) {
        TextView scoreView = (TextView) findViewById(R.id.pocketed0);
        scoreView.setText("FOO");
    }
}

Having instantiated this board in MainActivity,

public class MainActivity extends AppCompatActivity {
    Board board;

    String pocketedHistory = "";
    String pointString = "";
    int points = 0;
    String selectedPocket = "S";

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

        board = new Board();
    }


    public void pocket5(View v) {
        board.pocket(5);
    }

pocket5() is called when I tap a button and this exception was raised.

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.android.japan9_ballscorer, PID: 10399 java.lang.IllegalStateException: Could not execute method for android:onClick at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:414) at android.view.View.performClick(View.java:4473) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992) at android.view.View$PerformClick.run(View.java:18799) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:103) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:5341) 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:825) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641) 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 androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409) at android.view.View.performClick(View.java:4473)  at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)  at android.view.View$PerformClick.run(View.java:18799)  at android.os.Handler.handleCallback(Handler.java:808)  at android.os.Handler.dispatchMessage(Handler.java:103)  at android.os.Looper.loop(Looper.java:193)  at android.app.ActivityThread.main(ActivityThread.java:5341)  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:825)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)  at dalvik.system.NativeStart.main(Native Method)  Caused by: java.lang.NullPointerException at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:152) at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:103) at android.content.Context.obtainStyledAttributes(Context.java:389) at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:839) at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:806) at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:630) at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:223) at com.example.android.japan9_ballscorer.Board.pocket(Board.java:21) at com.example.android.japan9_ballscorer.MainActivity.pocket5(MainActivity.java:27) at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:515)  at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:409)  at android.view.View.performClick(View.java:4473)  at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)  at android.view.View$PerformClick.run(View.java:18799)  at android.os.Handler.handleCallback(Handler.java:808)  at android.os.Handler.dispatchMessage(Handler.java:103)  at android.os.Looper.loop(Looper.java:193)  at android.app.ActivityThread.main(ActivityThread.java:5341)  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:825)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)  at dalvik.system.NativeStart.main(Native Method) 

Could anyone shed a light about this? I'm at a loss what to do..

Upvotes: 0

Views: 631

Answers (3)

Ramanand Prajapati
Ramanand Prajapati

Reputation: 116

I guess you are new in android the things are not correct you need to learn more.

For this problem you can try like this:-

    public class Board{
    private Rack rack;
    private int currentPlayer;

    public Board() {
        rack = new Rack();
        currentPlayer = 0;
    }

    public void setCurrentPlayer(int n) {
        currentPlayer = n;
    }

    public String pocket(int ballNumber) {
        return "FOO";
    }
}

Your Activity would be like this:-

 public class MainActivity extends AppCompatActivity {
    Board board;

    String pocketedHistory = "";
    String pointString = "";
    int points = 0;
    String selectedPocket = "S";
    TextView scoreView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        scoreView = scoreView.findViewById(R.id.pocketed0);
        board = new Board();

    }

    public void pocket5(View v) {
        scoreView.setText(board.pocket(5));
    }
}

Upvotes: 0

Kidus
Kidus

Reputation: 474

The problem here is usage and understanding of Activities and Classes. Your Board class doesn't need to be an Activity just to use the findViewById parameter. What you can do is pass the context of the MainActivity to the Board class as a constructor parameter.

Modify Board class as this:

public class Board {
    private Rack rack;
    private int currentPlayer;
    private Activity mActivity;

    public Board(Activity activity) {
        mActivity = activity;
        rack = new Rack();
        currentPlayer = 0;
    }

    public void setCurrentPlayer(int n) {
        currentPlayer = n;
    }

    public void pocket(int ballNumber) {
        TextView scoreView = (TextView) 
        mActivity.findViewById(R.id.pocketed0);
        scoreView.setText("FOO");
    }
}

And modify your MainActivity as such:

public class MainActivity extends AppCompatActivity {
    Board board;

    String pocketedHistory = "";
    String pointString = "";
    int points = 0;
    String selectedPocket = "S";

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

        board = new Board(this);
    }


    public void pocket5(View v) {
        board.pocket(5);
    }
}

Upvotes: -1

a_local_nobody
a_local_nobody

Reputation: 8191

you have:

public class Board extends AppCompatActivity 
...

but you don't have an onCreate or a setContentView, which is why your app is crashing. this leads me to believe that you don't have a complete understanding of what exactly is an activity


board = new Board();

you shouldn't be creating a new instance of an activity like this either, you have to launch an activity using an intent

Upvotes: 2

Related Questions