2012-04-16 251 views
1

我试图拦截类的Android android.view.ViewonDraw()方法,以了解视图何时完成绘制自己(以及随后启动其他操作)的线索。超类的Java子类构造函数

但是,这让我想到了一些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()方法更换行:

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){}; 
    } 
} 
+0

看到我的编辑..这可能有助于.. – ngesh 2012-04-16 13:46:49

回答

3

,我需要重新定义在我的子类的所有公共构造,如上面?

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

Java默认不会调用它们吗?

号如果不申报任何构造,编译器将尝试为您创建一个表单:

public ClassName() { 
    super(); 
} 

对于任何声明的构造,如果你不明确链到另一个构造函数(在超类或这个类),它会隐式地添加super() - 即调用超类中的无参数构造函数。如果该构造函数不存在或无法访问,则会导致编译时失败。

我不能在我的onCreate replace()方法行:

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

我不太了解充气器,以确定它是否可行。

+0

其很难想象你输入的那很短的时间.. :) – ngesh 2012-04-16 13:23:47

+0

谢谢你的快速答案。如果我没有定义构造函数(我不需要),那么我会收到:“隐式超级构造函数View()未定义为默认构造函数。必须定义一个显式构造函数”。第二个问题是inflater.inflate()实际上返回一个View(不是MyView)对象。但是,我想以某种方式选择该视图对象,将其转换为MyView对象(以便在onDraw())上进行攻击,最后将新的MyView对象提供给setContentView()方法(该方法接受View对象) 。 – user1284631 2012-04-16 13:23:51

+0

@sandy:那么它的一些引用 - 所以剪切和粘贴帮助:) – 2012-04-16 13:24:19

1
  1. 是的,如果你想调用超类的构造函数如图所示。这是必要的。
  2. 试着将从膨胀返回的View铸造成MyView
  3. ,而不是宣布 <View>...</View>
+0

谢谢。它以这种方式工作(请参阅我上面的评论),但我担心最初接受View对象的继承的方法setMyContentView()并不真正了解我传递给它的MyView对象。它“编译”,但它在JVM上崩溃。 – user1284631 2012-04-16 13:35:12

+0

MyView IS-A视图的一个实例。如果它在运行时在JVM中崩溃,则表明您的实现无法满足Liskov替换原则。 – duffymo 2012-04-16 14:30:36

+0

我会进一步挖掘。谢谢。 – user1284631 2012-04-16 14:42:31

0

在你nessiean.xml文件,你需要简单地将其chagne到< MyView>...</MyView>。这样,你实际上是返回一个MyView的对象,当你调用findViewById

此外,您的onCreate方法应该仅仅是:

​​
+0

嘿,谢谢!这似乎有帮助! – user1284631 2012-04-18 08:21:38

相关问题