findViewById()在extends子类中

时间:2012-10-10 15:52:20

标签: java android class android-view

我有两个类,如:

public class Game extends Activity

public class CoreGame extends Game

CoreGame 课程中,我有:

public void init(){
    layout = (RelativeLayout)findViewById(R.id.rlayout);
}

NullPointerException CoreGame 类别行的执行返回layout = (RelativeLayout)findViewById(R.id.rlayout);

为什么呢?

OnCreate:

   @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.game);

        core = new CoreGame(this);
        core.runCoreGame();

    }

Core.runCoreGame():

public void runCoreGame(){
    init();
}

public void init(){
    layout = (RelativeLayout)findViewById(R.id.rlayout);
}

StackTrace:

FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{gianbalex.mgs_revenge/gianbalex.mgs_revenge.Game}: java.lang.NullPointerException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
        at android.app.ActivityThread.access$2300(ActivityThread.java:125)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:123)
        at android.app.ActivityThread.main(ActivityThread.java:4627)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:521)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
        at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.NullPointerException
        at android.app.Activity.findViewById(Activity.java:1637)
        at gianbalex.mgs_revenge.CoreGame.initVariables(CoreGame.java:118)
        at gianbalex.mgs_revenge.CoreGame.runCoreGame(CoreGame.java:84)
        at gianbalex.mgs_revenge.Game.onCreate(Game.java:28)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)

3 个答案:

答案 0 :(得分:2)

好的......所以这段代码中存在多个问题,所以我将逐点解决。

<强> 1。您没有以正确的方式启动活动

要启动CoreGame,您需要使用Intent行:

Intent intent = new Intent(getBaseContext(), CoreGame.class);
startActivity(intent);

这将运行活动,Android将调用CoreGame.onCreate()。您不需要调用构造函数等。您在构造函数中执行的任何操作都应该使用onCreate()onStart()方法完成。

现在到了你的第二个问题

<强> 2。修复意图位

后,您将最终得到NPE

我不确定发布的onCreate()是哪个类,所以我将把它分成两个场景:

场景1:已发布onCreate()属于Game

在这种情况下,当您使用new CoreGame启动方法替换Intent行时,在尝试使用NullPointerException时仍会获得findViewById()。这是因为您只在setContentView()活动中调用了Game,现在您将尝试从其他Views访问Activity。要解决此问题,您还必须在setContentView()中致电CoreGame

场景2:已发布onCreate()属于CoreGame

在这种情况下,您可以完全删除这两行:

core = new CoreGame(this);
core.runCoreGame();

相反,只需调用runCoreGame()就足够了

答案 1 :(得分:0)

使用此方法,这是初始化和创建对象的正确方法。

 RelativeLayout layout = (RelativeLayout) findViewById(R.id.rlayout);

答案 2 :(得分:-2)

如果我错了,请纠正我,但看起来你正试图

  1. 声明一个变量,但在类型周围有()。这应该在编译时给你一个错误信息。

  2. 使用强制转换来获取变量的属性,它可能没有。 layout实际上是RelativeLayout对象吗?

  3. 我的钱是第二种选择。如果对象不是正确的类,您将获得异常,这就是为什么转换可能听起来正确。当我还在学习Java和Objective-C时,这是一个简单的思路:“如果它不是正确的类型,我可以转换为使它成为正确的类型”。简单地说,不。你在这里做的是尝试从没有该属性的东西获取/设置属性,因此该函数返回nilnull。在Java中,如果我没有弄错的话,应该不惜一切代价避免这些。

    您可以通过声明layout这样来解决此问题:

    RelativeLayout layout = (RelativeLayout) findViewById(R.id.rlayout);
    

    这使它成为正确的类型,因此它可以正确接收任何和所有信息。现在,我是Java和Android SDK的新手,但我仍然有一个建议:在尝试用它构建一个真实的应用程序之前,尝试学习Java并熟悉它。不幸的是,很明显,你并不完全熟悉这种语言,而且它的特质也是如此。如果我错了,可能是因为我很困惑。你真的应该发布显示layout声明的代码,以便我们可以看到任何潜在的问题。

    编辑:正如AedonEtLIRA在给你的评论中所说,无论如何你应该在其他地方这样做。除非你确实知道完全你正在做什么,否则将这种代码放入构造函数中是非常危险的。即使之后应用程序看起来很好,这种事情也会导致它运行得更慢并且更不稳定。其他代码可能导致它崩溃,没有明显的原因。这是因为它可以在应用程序中创建僵尸和“死记忆”,当其他活动需要内存时会导致问题。