Android 从对象调用findViewById()

Android 从对象调用findViewById(),android,Android,我正在练习android应用程序开发,并编写台球记分板 public class Board extends AppCompatActivity { private Rack rack; private int currentPlayer; public Board() { rack = new Rack(); currentPlayer = 0; } public void setCurrentPlayer(int n

我正在练习android应用程序开发,并编写台球记分板

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");
    }
}
已在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()
,并引发了此异常

E/AndroidRuntime:致命异常:主 进程:com.example.android.japan9_ballscorer,PID:10399 java.lang.IllegalStateException:无法为android执行方法:onClick 在androidx.appcompat.app.appcompativiewInflater$DeclaredOnClickListener.onClick(appcompativiewInflater.java:414) 在android.view.view.performClick上(view.java:4473) 在com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)上 在android.view.view$PerformClick.run(view.java:18799) 位于android.os.Handler.handleCallback(Handler.java:808) 位于android.os.Handler.dispatchMessage(Handler.java:103) 位于android.os.Looper.loop(Looper.java:193) 位于android.app.ActivityThread.main(ActivityThread.java:5341) 位于java.lang.reflect.Method.Invokenactive(本机方法) 位于java.lang.reflect.Method.invoke(Method.java:515) 在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run上(ZygoteInit.java:825) 位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641) 在dalvik.system.NativeStart.main(本机方法) 原因:java.lang.reflect.InvocationTargetException 位于java.lang.reflect.Method.Invokenactive(本机方法) 位于java.lang.reflect.Method.invoke(Method.java:515) 在androidx.appcompat.app.appcompativiewInflater$DeclaredOnClickListener.onClick(appcompativiewInflater.java:409) 在android.view.view.performClick上(view.java:4473) 在com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)上 在android.view.view$PerformClick.run(view.java:18799) 位于android.os.Handler.handleCallback(Handler.java:808) 位于android.os.Handler.dispatchMessage(Handler.java:103) 位于android.os.Looper.loop(Looper.java:193) 位于android.app.ActivityThread.main(ActivityThread.java:5341) 位于java.lang.reflect.Method.Invokenactive(本机方法) 位于java.lang.reflect.Method.invoke(Method.java:515) 在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run上(ZygoteInit.java:825) 位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641) 在dalvik.system.NativeStart.main(本机方法) 原因:java.lang.NullPointerException 位于android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:152) 在android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:103) 位于android.content.Context.ActainStyledAttributes(Context.java:389) 位于androidx.appcompat.app.appcompatedelegateimpl.createSubDecor(appcompatedelegateimpl.java:839) 在androidx.appcompat.app.appcompatedelegateimpl.ensureubdecor(appcompatedelegateimpl.java:806) 位于androidx.appcompat.app.appcompatedelegateimpl.findViewById(appcompatedelegateimpl.java:630) 在androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:223)上 位于com.example.android.japan9_ballscorer.Board.pocket(Board.java:21) 在com.example.android.japan9_ballscorer.MainActivity.pocket5(MainActivity.java:27)上 位于java.lang.reflect.Method.Invokenactive(本机方法) 位于java.lang.reflect.Method.invoke(Method.java:515) 在androidx.appcompat.app.appcompativiewInflater$DeclaredOnClickListener.onClick(appcompativiewInflater.java:409) 在android.view.view.performClick上(view.java:4473) 在com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)上 在android.view.view$PerformClick.run(view.java:18799) 位于android.os.Handler.handleCallback(Handler.java:808) 位于android.os.Handler.dispatchMessage(Handler.java:103) 位于android.os.Looper.loop(Looper.java:193) 位于android.app.ActivityThread.main(ActivityThread.java:5341) 位于java.lang.reflect.Method.Invokenactive(本机方法) 位于java.lang.reflect.Method.invoke(Method.java:515) 在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run上(ZygoteInit.java:825) 位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641) 在dalvik.system.NativeStart.main(本机方法)

有人能解释一下吗?我不知道该怎么办你有:

public class Board extends AppCompatActivity 
...
但是你没有
onCreate
setContentView
,这就是你的应用程序崩溃的原因。这让我相信你并不完全理解什么是活动



你也不应该创建这样一个活动的新实例,你必须使用意图启动一个活动

我猜你是android新手,事情不正确,你需要了解更多

对于此问题,您可以这样尝试:-

    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";
    }
}
 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));
    }
}
您的活动如下所示:-

    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";
    }
}
 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));
    }
}

这里的问题是如何使用和理解
活动
。您的
Board
类不需要只是一个活动,就可以使用
findViewById
参数。您可以做的是将
main活动的
context
作为
constructor
参数传递给
Board

Board
类修改为:

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");
    }
}
并修改您的
main活动

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);
    }
}

谢谢大家的回答。我是如此的不耐烦以至于停止了Udacity的视频并开始写作。我认为findViewById()提供Board对象访问视图对我来说是直观而直接的。这就是为什么我愚蠢地让董事会扩展活动。谢谢你的洞察力,@Kidus!当我更改代码时,medthod无法解决如下问题。你能帮我解释一下吗?>C:\Users\mitsu\AndroidStudioProjects\Japan9ballScorer\app\src\main\java\com\example\android\japan9\u ballscorer\Board.java:22:错误:找不到symbol>TextView scoreView=(TextView)mContext.findViewById(R.id.pocketed0);>symbol:method findviewbyd(int)>位置:Context`@uemurm类型的变量mContext您没有在Board类中导入上下文库/类吗