【问题标题】:Calling findViewById() from an object从对象调用 findViewById()
【发布时间】:2021-05-06 13:54:22
【问题描述】:

我正在练习一个安卓应用程序开发和写台球记分板。

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: 致命异常: main 进程:com.example.android.japan9_ballscorer,PID:10399 java.lang.IllegalStateException:无法执行 android:onClick 的方法 在 androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.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.invokeNative(Native Method) 在 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.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:515) 在 androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.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.invokeNative(Native Method) 在 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.obtainStyledAttributes(Context.java:389) 在 androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:839) 在 androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:806) 在 androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.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.invokeNative(Native Method) 在 java.lang.reflect.Method.invoke(Method.java:515) 在 androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.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.invokeNative(Native Method) 在 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(本机方法)

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

【问题讨论】:

  • 谢谢大家的回答。我太不耐烦了,停止了 Udacity 的视频并开始写作。我认为通过 findViewById() 让 Board 对象访问视图对我来说是直观和直接的。这就是为什么我愚蠢地让 Board 扩展 AppCompatActivity。

标签: android


【解决方案1】:

你有:

public class Board extends AppCompatActivity 
...

但您没有onCreatesetContentView,这就是您的应用崩溃的原因。这使我相信您对究竟是什么活动没有一个完整的了解


board = new Board();

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

【讨论】:

    【解决方案2】:

    我猜你是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));
        }
    }
    

    【讨论】:

      【解决方案3】:

      这里的问题是ActivitiesClasses的使用和理解。您的 Board 类不需要是 Activity 就可以使用 findViewById 参数。您可以做的是将MainActivitycontext 作为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");
          }
      }
      

      然后修改你的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(this);
          }
      
      
          public void pocket5(View v) {
              board.pocket(5);
          }
      }
      

      【讨论】:

      • 感谢您的洞察力,@Kidus !当我更改代码时,方法无法解决如下。你能解释一下吗? >C:\Users\mitsu\AndroidStudioProjects\Japan9ballScorer\app\src\main\java\com\example\android\japan9_ballscorer\Board.java:22:错误:找不到符号 > TextView scoreView = (TextView) mContext.findViewById( R.id.pocketed0); > ^ > 符号:方法findViewById(int) > 位置:Context`类型的变量mContext`
      • @uemurm 您没有在 Board 类中导入 Context 库/类吗? import android.content.Context;
      • 感谢您的评论,@Kidus。是的,import android.content.Context; 在那个类文件中,所以mContext 被解析,而findViewById 不是。
      • @uemurm 我编辑了我的代码,检查一下,将Context 切换为Activity,因为需要findViewById,很抱歉我第一次没有彻底检查。跨度>
      • 现在我可以继续了。非常感谢你,@Kidus !!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-22
      相关资源
      最近更新 更多