Androidのコールバック事件の詳細

5301 ワード

ネット上のいくつかのコールバックの解釈はすべて複雑で、特にAndroidのカスタムコールバックに基づいて、霧の水を感じて、そこで、私もこのコールバックに対する解釈を書きました.
まず簡単な例を見てみましょう.クラスClassAとClassB、ClassAがClassBを呼び出す方法が2つあります.

public class ClassB {

  public void method_from_classB(){
    
    for(int i=0;i<10;i++)
      System.out.print("..."+i);
  }
}
public class ClassA {

   
  
  public static void main(String args[]){
   
    ClassB classB = new ClassB();
    
    classB.method_from_classB();
  }
}


出力:
...0...1...2...3...4...5...6...7...8...9
寝槽、どの馬鹿が書いた博文、私のIQを侮辱したのではないでしょうか.ヒヒ、比較するためです.次に、コールバックを利用して、ClassAがどのようにClassBの中の方法を呼び出したのかを見てみましょう.注意はコールバックです.
ClassBにClassA定義のインタフェースを実装させる

public class ClassB implements ClassA.ClassAInterface{

  public ClassB(){
    
    new ClassA().RegisterInterface(this);
    System.out.println("...ClassB..."+this);
  }

  @Override
  public void method_from_interface() {

    for(int i=0;i<10;i++)
      System.out.print("..."+i);
  }
  
  /*  public void method_from_classB(){
  
  for(int i=0;i<10;i++)
    System.out.print("..."+i);
  }*/
}


ClassAでは、インタフェースと抽象メソッドを定義します.

public class ClassA {

  public static ClassAInterface classAInterface;
  
  public interface ClassAInterface{
    
    public void method_from_interface();
  }
  public void RegisterInterface(ClassAInterface a_interface){

    this.classAInterface = a_interface;
    System.out.println("...a_interface..."+a_interface);
  }
 
  public static void main(String args[]){
   
    ClassB classB = new ClassB();//   @1,      
    //classB.method_from_classB();
    System.out.println("...classAInterface..."+classAInterface);
     if(classAInterface != null){
        classAInterface.method_from_interface();
      }
  }
}


出力:
...0...1...2...3...4...5...6...7...8...9
整理して、つまり私はClassAの中で1つのインターフェース(interface)を定義して、インターフェースの中でまた1つの方法を定義して、しかし方法体がなくて、何もしません.
ClassAがmian()関数を実行すると、インタフェースのメソッドが呼び出されますが、前述したように、インタフェースのメソッドは具体的なことを実現していません.ClassBの中で対応するメソッドを見つけて、具体的なことを実現します.
おやおや、ClassAのインタフェースの方法はどのようにClassBの方法を探し当てて、まさか天に昇ることができますか??
つまり、このコードがどのように天に昇ったのかを分析します.
//インタフェースのコールバックでClassBの方法を実現する具体的なこと classAInterface.method_from_interface();
私は上のコードでSystemを使います.out.printlnはログを印刷して分析しました:
1つ目(ClassAの方法):

  public void RegisterInterface(ClassAInterface a_interface){

    this.classAInterface = a_interface;
    System.out.println("...a_interface..."+a_interface);
  }


出力:
...a_interface...ClassB@3ddb8962
2つ目:

public ClassB(){
    
    new ClassA().RegisterInterface(this);
    System.out.println("...ClassB..."+this);
  }

出力:
...ClassB...ClassB@3ddb8962
3つ目:

System.out.println("...classAInterface..."+classAInterface);
     if(classAInterface != null){
        classAInterface.method_from_interface();
      }

出力:
...classAInterface...ClassB@3ddb8962
ここを見てはっと悟ったのか、出力はすべて「ClassB@3ddb8962"つまりClassBオブジェクトの引用!!!
ああ!インタフェースはClassBオブジェクトの引用をClassAに伝えるだけなので、この天に昇る文は説明しやすいのではないでしょうか.
       classAInterface.method_from_interface();
に相当[email protected]_from_interface();
これは一番上のコードではありませんか.

    ClassB classB = new ClassB();  
    classB.method_from_classB();

同じように、これも私が最初にこの例を挙げた理由です!!!
ここを見てインタフェースのコールバックがどうなっているのか理解できたと思います.しかし、なぜインタフェースのコールバックがこんなに面倒なのか、一番上のものはClassAで実行されています.

    ClassB classB = new ClassB();  
    classB.method_from_classB();

同じようにClassAがClassBの中の方法を呼び出すことができるわけではありません...でもClassAがClassCを呼び出すならClassD...、中の方法は、ClassAのコードを変更し、ClassC、ClassDをインスタンス化する必要がありますか?の対象は、明らかに良くなくて、インタフェースを使うならばClassAの中のコードを変える必要はなくて、いかなる類はClassAの中のインタフェースを実現するだけでいいです.
タグ@1を説明します.
上の話はタグ@1とは逆のようですが、ClassAでもClassBオブジェクトをインスタンス化する必要があります.
初期化するときに构造方法のコードを実行するからです.

public ClassB(){
    //           ,                  ‘  ' 
    new ClassA().RegisterInterface(this);
  }

これをClassAに渡します.つまり、ログ分析を利用した役割です.
しかし、Android開発で助ける必要はありません.Activityの初期化時に実行できます.

@Override
  protected void onCreate(Bundle savedInstanceState) {

     //           ,                  ‘  ' 
    new ClassA().RegisterInterface(this);
}


Android開発ではClassAのmian()関数をイベントに置き換えることができ、トリガー:

button.setOnClickListener(new OnClickListener() {
      
      @Override
      public void onClick(View v) {
        // TODO          
        if(classAInterface != null){
        classAInterface.method_from_interface();
      }
    });