2012-01-24 7 views
1

私はこれをしばらく使用していましたが、このテクニックを例で見つけたのか、それが最終的にうまくいくまで数多くのことを試したのかは分かりません。私の質問は、このコード行が実際にどのようにしてこのコード行がListReadyObjectからコールバックをリッスンするかを確認することです。カスタムArrayAdapterで新しいカスタムハンドラをインスタンス化するのはなぜですか?

package com.scs.stuff; 

import java.util.ArrayList; 

import android.content.Context; 
import android.os.Handler; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.LinearLayout; 
import android.widget.TextView; 

public class ListReadyObjectAdapter extends ArrayAdapter<ListReadyObject> { 

    public ListReadyObjectAdapter(Context context, int textViewResourceId, 
      ArrayList<ListReadyObject> lro) { 
     super(context, textViewResourceId, lro); 

    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     LinearLayout v; 
     v = new LinearLayout(getContext()); 
     LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
       Context.LAYOUT_INFLATER_SERVICE); 
     vi.inflate(R.layout.list_row, v, true); 

     ListReadyObject o = getItem(position); 

     if (o != null) { 

      TextView tt = (TextView) v.findViewById(R.id.toptext); 
      TextView bt = (TextView) v.findViewById(R.id.bottomtext); 

      if (tt != null) { 
       tt.setText(o.getDisplayText()); 
      } 

      if (o.isLiving()) { 
       if (bt != null) { 
        // set default text to be shown 
        // until the status thread completes 
        bt.setText("---"); 
       } 
       // start a background thread to update Display State 
       o.updateStatus(); 
       // why does this work 
       new ObjectInterfaceHandler(position, o, v); 

      } else { 
       if (bt != null) { 
        bt.setText("Not Living"); 
       } 
      } 
     } 
     return v; 
    } 

    // provides a way for the Object to call back to the list without 
    // blocking the UI 
    public class ObjectInterfaceHandler implements ListReadyObjectStatusListener { 
     int position; 
     ListReadyObject o; 
     View v; 

     private final Handler handler = new Handler(); 

     public ObjectInterfaceHandler(int position, ListReadyObject o, View v) { 
      this.position = position; 
      this.o = o; 
      this.v = v; 
      // register to observe an update from the Object 
      o.registerObserver(this); 
     } 
     @Override 
     public void objectInterfaceUpdate() { 
      // called from the Object's observer pattern 
      handler.post(updateBottomText); 
     } 
     // runnable to put the update on the UI Thread 
     private Runnable updateBottomText = new Runnable() { 
      @Override 
      public void run() { 
       TextView bt = (TextView) v.findViewById(R.id.bottomtext); 
       if (bt != null) { 
        bt.setText(o.getStatusText()); 
       } 
      } 
     }; 
    } 
} 

ListReadyObjectインタフェース:

package com.scs.stuff; 

public interface ListReadyObject { 

    public void registerObserver(ListReadyObjectStatusListener o); 

    public void removeObserver(ListReadyObjectStatusListener o); 

    public void notifyObservers(); 

    public String getDisplayText(); 

    public String getStatusText(); 

    public boolean isLiving(); 

    public void updateStatus(); 

} 

ListReadyObjectStatusListenerインタフェース:

package com.scs.stuff; 

public interface ListReadyObjectStatusListener { 

    public void objectInterfaceUpdate(); 

} 

答えて

1

それは(直接)ビューは、コールバックを待ち受けることはありません。ここで

あなたはListReadyObjectObjectInterfaceHandlerのコンストラクタに渡されます参照してください。

ListReadyObject o = getItem(position); 
... 
new ObjectInterfaceHandler(position, o, v); 

そのコンストラクタでは、あなたがこれを見つける:

o.registerObserver(this); 

だからObjectInterfaceHandlerが実際にListReadyObjectを聞い一つです。それは更新が通知されるとその後:

private Runnable updateBottomText = new Runnable() { 
    @Override 
    public void run() { 
     TextView bt = (TextView) v.findViewById(R.id.bottomtext); 
     if (bt != null) { 
      bt.setText(o.getStatusText()); 
     } 
    } 
}; 

これはObserver Patternと呼ばれる非常に一般的なパターンです:

@Override 
public void objectInterfaceUpdate() { 
    // called from the Object's observer pattern 
    handler.post(updateBottomText); 
} 

これは、ビューを更新し、あなたのRunnableを呼び出すために、独自のハンドラにメッセージをポストします。

+0

私はObjectInterfaceHandlerへの参照を持っていないので、メモリにはどこにそれがありますか? ListViewの各ビューに対して1つずつインスタンス化します。 – tunneling

+0

他のオブジェクトと同様、ヒープにも存在します。 'ListReadyObject'の実装はオブザーバーとして登録する際に参照を保持しているので(ガーベッジコレクションが壊れていない場合)、ガベージコレクションは行われません。 – kabuko

0

私はまったくAndroidの新機能ですが、コードの半分しか得られませんが、私が考えることができるのは、ObjectInterfaceHandlerのコンストラクタ内の何かが呼び出され、コードの続き。

o.registerObserver(this); 

ListReadyObjectパラメータは、ここでObjectInterfaceHandlerへの参照を取る:あなたが唯一のインスタンスを(あなたがそれに任意の参照を保持していない)を作成するので、唯一の違いは、コンストラクタのコードである可能性があります。

関連する問題