来自超类的Java子类构造函数

时间:2012-04-16 13:19:09

标签: java android subclass

我试图拦截Android onDraw()类的android.view.View方法,以了解视图何时完成绘制自身(并随后启动其他操作)。

然而,这引发了我一些Java问题(我对Java的经验有限)。

我的活动onCreate()方法包含以下代码:

LayoutInflater inflater = (LayoutInflater)   getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
View view = inflater.inflate(R.layout.nessiean, null);
setContentView(view);
doSomeOperations();

我定义了一个子类,其主要目的是定义内部状态并提供wait()方法:

class MyView extends View{
    int state=0;

    public MyView(Context context){
        super(context);
    }

    public MyView(Context context, AttributeSet attrs){
        super(context,attrs);
    }

    public MyView(Context context, AttributeSet attrs, int defStyle){
        super(context,attrs,defStyle);
    }

    protected void onDraw (Canvas canvas){
        super.onDraw(canvas);
        state=1;
    }

    public void waitforDraw(){
        while(state==0){};
    }
}

问题是:

  1. 我是否需要重新定义子类中的所有公共构造函数,如上所述? Java默认不调用它们?

  2. 我无法在我的onCreate()方法中替换以下行:

  3. View view = inflater.inflate(R.layout.nessiean, null);

    MyView view = inflater.inflate(R.layout.nessiean, null);

    错误为:cannot convert from View to MyView

    任何提示?

    ==========================完整代码如下:================== ============

    package com.example;
    
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.os.Bundle;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    
    public class SoundActivity extends Activity {
    
        private Thread mWorkerThread;
    
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //START: ALTERNATIVE WAY FOR CREATING THE VIEW
            //*first variant:
            //setContentView(R.layout.nessiean);
            //*second variant:
            LayoutInflater inflater = (LayoutInflater)   getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
            MyView view = (MyView) inflater.inflate(R.layout.nessiean, null);
            setContentView(view);
            //STOP: ALTERNATIVE WAY FOR CREATING THE VIEW
            System.loadLibrary("soundtest");
            mWorkerThread =  new Thread(new Runnable() {
                public void run() {
                    execute();      
                }
            },"Worker Thread");
            try{
                mWorkerThread.start();
                mWorkerThread.join(); 
            }
            catch (Exception e) {
                System.exit(1); 
            }
        }   
    
        private native void execute();
    }
    
    class MyView extends View{
        int state=0;
    
        public MyView(Context context){
            super(context);
        }
    
        public MyView(Context context, AttributeSet attrs){
            super(context,attrs);
        }
    
        public MyView(Context context, AttributeSet attrs, int defStyle){
            super(context,attrs,defStyle);
        }
    
        @Override
        protected void onDraw (Canvas canvas){
            super.onDraw(canvas);
            state=1;
        }
    
        public void waitforDraw(){
            while(state==0){};
        }
    }
    

3 个答案:

答案 0 :(得分:3)

  

我是否需要重新定义子类中的所有公共构造函数,如上所述?

这取决于 - 您想拥有所有这些构造函数吗?仅声明您的类需要的那些。

  

默认情况下,Java不会调用它们吗?

没有。如果您没有声明任何构造函数,编译器将尝试为您创建一个构造函数:

public ClassName() {
    super();
}

对于任何声明的构造函数,如果没有显式链接到另一个构造函数(在超类或此类中),它将隐式添加super() - 即调用超类中的无参数构造函数。如果该构造函数不存在或无法访问,则会出现编译时失败。

  

我无法在我的onCreate()方法中替换行:

View view = inflater.inflate(R.layout.nessiean, null);
     

MyView view = inflater.inflate(R.layout.nessiean, null);

如果对inflate的调用将实际返回MyView的实例,那么您只需添加一个演员:

MyView view = (MyView) inflater.inflate(R.layout.nessiean, null);

我对inflater的了解不足以确定这是否有效。

答案 1 :(得分:1)

  1. 是的,如果你想调用超类构造函数,如图所示。这是必要的。
  2. 尝试将从膨胀返回的View投射到MyView

答案 2 :(得分:0)

在你的nessiean.xml文件中,你需要简单地将它变为&lt; <View>...</View>,而不是声明MyView>...</MyView>。这样,当您调用findViewById

时,实际上是在返回MyView对象

另外,你的onCreate方法应该是:

setContentView(R.layout.nessiean);
MyView myView = (MyView) findViewById(R.id.<whatever tag you gave the view);