2012-04-16 167 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

相關問題