最新のGoogle IOでは、安らかなクライアントアプリケーションの実装に関するプレゼンテーションが行われました。残念ながら、実装のソースコードがなく、高レベルの議論にすぎませんでした。
この図では、戻りパスに他のメソッドへのさまざまなコールバックがあります。
これらのメソッドが何であるかを宣言するにはどうすればよいですか?
コールバックのアイデアを理解しています-特定のイベントが発生した後に呼び出されるコードの一部ですが、それを実装する方法がわかりません。これまでにコールバックを実装した唯一の方法は、さまざまなメソッド(たとえばonActivityResult)をオーバーライドすることでした。
デザインパターンの基本的な理解はあるように感じますが、リターンパスの処理方法についてはつまづきます。
多くの場合、インターフェイスがあり、それを実装するオブジェクトを渡します。たとえば、ダイアログにはOnClickListenerがあります。
ランダムな例として:
// The callback interface
interface MyCallback {
void callbackCall();
}
// The class that takes the callback
class Worker {
MyCallback callback;
void onEvent() {
callback.callbackCall();
}
}
// Option 1:
class Callback implements MyCallback {
void callbackCall() {
// callback code goes here
}
}
worker.callback = new Callback();
// Option 2:
worker.callback = new MyCallback() {
void callbackCall() {
// callback code goes here
}
};
私はおそらくオプション2の構文を台無しにしました。それは早いです。
ビューで何かが発生すると、アクティビティがリッスンしているイベントを開始します。
// DECLARED IN(CUSTOM)VIEW
private OnScoreSavedListener onScoreSavedListener;
public interface OnScoreSavedListener {
public void onScoreSaved();
}
// ALLOWS YOU TO SET LISTENER && INVOKE THE OVERIDING METHOD
// FROM WITHIN ACTIVITY
public void setOnScoreSavedListener(OnScoreSavedListener listener) {
onScoreSavedListener = listener;
}
//アクティビティで宣言されています
MyCustomView slider = (MyCustomView) view.findViewById(R.id.slider)
slider.setOnScoreSavedListener(new OnScoreSavedListener() {
@Override
public void onScoreSaved() {
Log.v("","EVENT FIRED");
}
});
フラグメント間の通信(コールバック)について詳しく知りたい場合は、こちらを参照してください: http://developer.Android.com/guide/components/fragments.html#CommunicatingWithActivity
既存のものを使用できる場合は、新しいインターフェースを定義する必要はありません:Android.os.Handler.Callback
。タイプCallbackのオブジェクトを渡し、コールバックのhandleMessage(Message msg)
を呼び出します。
インターフェイスを使用してコールバックメソッドを実装する例。
インターフェイス、NewInterface.Javaを定義します。
パッケージjavaapplication1;
public interface NewInterface {
void callback();
}
新しいクラスNewClass.Javaを作成します。メインクラスのコールバックメソッドを呼び出します。
package javaapplication1;
public class NewClass {
private NewInterface mainClass;
public NewClass(NewInterface mClass){
mainClass = mClass;
}
public void calledFromMain(){
//Do somthing...
//call back main
mainClass.callback();
}
}
インターフェイスNewInterface-callback()メソッドを実装するためのメインクラスJavaApplication1.Java。 NewClassオブジェクトを作成して呼び出します。次に、NewClassオブジェクトは、そのcallback()メソッドを順番にコールバックします。
package javaapplication1;
public class JavaApplication1 implements NewInterface{
NewClass newClass;
public static void main(String[] args) {
System.out.println("test...");
JavaApplication1 myApplication = new JavaApplication1();
myApplication.doSomething();
}
private void doSomething(){
newClass = new NewClass(this);
newClass.calledFromMain();
}
@Override
public void callback() {
System.out.println("callback");
}
}
ドラゴンの答えを少し明確にするために(それはHandler.Callback
で何をすべきかを理解するのに時間がかかったので):
Handler
は、Message
sを渡すことで、現在のスレッドまたは別のスレッドでコールバックを実行するために使用できます。 Message
は、コールバックから使用されるデータを保持します。ハンドラーを直接拡張しないようにするために、Handler.Callback
をHandler
のコンストラクターに渡すことができます。したがって、現在のスレッドからコールバックを介していくつかのコードを実行するには:
Message message = new Message();
<set data to be passed to callback - eg message.obj, message.arg1 etc - here>
Callback callback = new Callback() {
public boolean handleMessage(Message msg) {
<code to be executed during callback>
}
};
Handler handler = new Handler(callback);
handler.sendMessage(message);
編集:同じ結果を得るためのより良い方法があることを認識しました(コールバックをいつ実行するかを正確に制御しません):
post(new Runnable() {
@Override
public void run() {
<code to be executed during callback>
}
});
この目的でLocalBroadcast
を使用することもできます。クイックガイドです
ブロードキャストレシーバーを作成します。
LocalBroadcastManager.getInstance(this).registerReceiver(
mMessageReceiver, new IntentFilter("speedExceeded"));
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Double currentSpeed = intent.getDoubleExtra("currentSpeed", 20);
Double currentLatitude = intent.getDoubleExtra("latitude", 0);
Double currentLongitude = intent.getDoubleExtra("longitude", 0);
// ... react to local broadcast message
}
これはあなたがそれをトリガーする方法です
Intent intent = new Intent("speedExceeded");
intent.putExtra("currentSpeed", currentSpeed);
intent.putExtra("latitude", latitude);
intent.putExtra("longitude", longitude);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
onPauseでレシーバーの登録を解除します。
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
}