コールバックはウィキペディアで次のように定義されています。
コンピュータープログラミングでは、コールバック関数とは、関数パラメーターを介して他のコードに渡される特定の実行可能コードへの参照を指します。
目的は、基礎となるコードがより高いレベルで定義されたサブルーチンを呼び出すことを許可することです。
たとえば、より明確な場合があります。AndroidでのネットワークリクエストにRetrofitの使用を例にとると、これは非同期コールバックの例です。
ネットワークリクエストを開始した後、アプリは他のものを継続できます。ネットワークリクエストの結果は、一般に、2つのOnsResponseとOnfailureの方法を通じて取得されます。関連する部分のコードを見てみましょう。
call.enqueue(new callback <historybean>(){@override public void onresponse(call <historybean> call、response <historybean> response){historybean hb = respons.body(); if(hb == null)return; showtext.append(hb.iserror() + "); showtext.append(rb.getTitle() + "/n");上記のコールバックのジェネリックを無視してください。ウィキペディアの定義によると、匿名の内部クラスのすべてのコードは、他のコードに渡される特定の実行可能コードへの参照と見なすことができます。 2つのメソッドが繰り返されると、コールバックメソッドです。基礎となるコードは、書き込まれた変更されていないネットワークリクエストパーツであり、より高いレベルで定義されるサブルーチンはコールバックです。特定の実装はユーザーに引き渡されるため、柔軟性が高くなります。上記は、メソッドenqueue(コールバックコールバック)を介して関連しています。
コールバックメソッドの手順
上記のコールバックは非常に一般的な概念です。プログラムライティングに掲載すれば、次のように言うことができます。
クラスAでは、クラスBのメソッドCが呼び出され、クラスBでは、クラスAのメソッドDが逆に呼び出されます。 Dはコールバックメソッドです。クラスBは基礎となるコードであり、クラスAは高レベルのコードです。
したがって、上記の説明を通して、私たちは何かを推測することができます。方法Dの普遍性を表すために、インターフェイスフォームを使用して、インターフェイスメソッドと呼ばれるメソッドDを作成します。クラスBがクラスAでメソッドDを呼び出す場合は、クラスAがこのインターフェイスを実装する必要があります。このようにして、実装に応じて多型が存在し、方法が柔軟になります。
クラスAがクラスBのメソッドCを呼び出す場合、クラスAにはBへの参照が含まれている必要があります。そうしないと、呼び出されません。このステップは、登録コールバックインターフェイスと呼ばれます。したがって、クラスBのクラスAで上記の方法Cを直接介して逆コールメソッドDを実装する方法C.クラスBのメソッドCは、インターフェイス型パラメーターを受け入れます。次に、メソッドCでのみ、このインターフェイスタイプのパラメーターを使用して、クラスBのメソッドDを呼び出す必要があります。これは、クラスAの方法Dを呼び出します。この手順は、コールバックインターフェイスを呼び出すと呼ばれます。
これにより、クラスBのCメソッドでは、クラスAのDメソッドを逆に呼び出す必要があることも実装しています。これはコールバックです。 b bを直接調整するために呼び出します。これは、高レベルのコードに基礎となるAPIを使用していると見なすことができます。私たちはしばしばこのようなプログラムを書きます。 bはaを呼び出してコールバックすると、基礎となるAPIでは、実行するには高レベルのコードが必要です。
最後に、コールバックメソッドの手順を要約しましょう。
コールバックの例
息子がゲームをしていて、母親が食事を準備し、息子が例として来て食事をするように通知し、上記の手順に従ってコールバックを書くのを待っています。
上記の例では、息子がコールバックインターフェイスを実装し、母親がコールバックインターフェイスを呼び出す必要があることは明らかです。そこで、最初にコールバックインターフェイスを定義し、次に息子にこのコールバックインターフェイスを実装させます。
コードは次のとおりです。
パブリックインターフェイスコールバック{void eat();}パブリッククラスの息子はコールバックを実装しています{プライベートママのお母さん。 //クラスAは、クラスBパブリックボイドSetMom(Mom Mom)への参照を保持しています{this.mom = mom; } @Override public void eat(){system.out.println( "食事をするためにここにいる"); } public void askmom(){//クラスBを参照してインターフェイスパラメーターを使用してメソッドを呼び出すSystem.out.println( "食事は調理されましたか?"); System.out.println( "完了していない、ゲームをプレイしている");新しいスレッド(() - > mom.docook(son.this))。start(); system.out.println( "ゲームのプレイ..."); }}また、インターフェイスパラメーターを備えたメソッドドクックを含む母親のクラスを定義する必要があります
パブリッククラスママ{//インターフェイスパラメーターを含むメソッドのインターフェイスパラメーターを使用してコールバックメソッドを呼び出しますpublic void docook(callback callback){new runnable(){@override public void run(){try {system.out.println( "cooking ..." cooking ... "); swree(5000); callback(5000); e.printstacktrace(); }}テストクラスに合格します。
public class test {public static void main(string [] args){mom mom = new Mom();息子の息子=新しい息子(); son.setmom(Mom); son.askmom(); }}この例は、典型的なコールバックの例です。息子のクラスは、インターフェイスのコールバック方法を実装します。 AskMomメソッドを介してMom ClassのDoCookを呼び出して、Callbackインターフェイスを登録します。これは、クラスAのクラスBコードCを呼び出すことに相当します。
このようにして、シンプルで定義されたコールバックを実装します。
コールバックの例のさらなる調査
主に息子のクラスのコードを見てみましょう。
パブリッククラスの息子はコールバックを実装しています{パブリックママ。パブリックソン(お母さんのお母さん){this.mom = mom; } public void askmom(){system.out.println( "食事は調理されましたか?"); System.out.println(「私はそれをうまくやっていない、ゲームをプレイした」);新しいスレッド(() - > mom.docook(son.this))。start(); System.out.println( "ゲームをプレイしました..."); } @Override public void eat(){system.out.println( "わかりました、食事をするためにここにいます"); }}このクラスでは、いくつかのステートメントの出力に加えて、本当に有用な部分はMom.docook(son. this)とEat Methodの書き換えです。したがって、匿名のインナークラスの形式を介してこのコールバックを省略できます。コードは次のとおりです。
public class callbacktest {public static void main(string [] args){mom mom = new Mom(); new shood(() - > mom.docook(() - > system.out.println( "食事を食べました..."))。start(); }}息子のクラスをキャンセルし、メインメソッドの匿名の内部クラスを介してEATメソッドを直接実装します。実際、匿名の内部クラスはコールバックの具体化です。
非同期コールバックと同期コールバック
コールバック:クラスBのメソッドCを呼び出し、クラスAからクラスAのメソッドAを通るメソッドDを呼び出します。C。
非同期と同期について話しましょう。最初に同期の概念について話しましょう。
同期
同期とは、メソッドを呼び出すとき、前のメソッド呼び出しが実行されない場合、新しいメソッド呼び出しが行わないことを意味します。言い換えれば、物事は一度に行われなければならず、次のことを次のようにすることができます。
非同期
非同期性は同期と比較して、新しいメソッドを呼び出す前に前のメソッド呼び出しが終了するまで待つ必要はありません。したがって、非同期メソッド呼び出しでは、メソッドコール結果をユーザーに通知するには方法が必要です。
非同期方法を実装します
Javaで非同期を実装する最も一般的な方法は、新しいスレッドで非同期に実行する方法を可能にすることです。
ユーザーの呼び出し結果に通知する非同期メソッド呼び出しでメソッドが必要であることがわかります。上記に基づいて、コールバックメソッドはこれを行うのに適していることがわかり、コールバックメソッドを介してユーザーに通話結果を通知します。
非同期コールバックは、BのメソッドCを呼び出すときに新しいスレッドで行われます。
息子に夕食のために通知する母親の上記の例は、非同期コールバックの例です。新しいスレッドでは、dookokメソッドが呼び出され、戻り値は最終的にEATによって受け入れられます。もちろん、Lamdbaの最適化を使用した後、エッセンスは同じです。
同期コールバックとは、aが新しいスレッドではないことを呼び出すことを意味します。この方法Cを実行するとき、私たちは何もできず、それが完了するのを待つことしかできません。
同期コールバックと非同期コールバックの例
Androidでの同期コールバックの例を見てみましょう。
button.setOnClickListener(new View.onclickListener(){@Override public void onclick(View v){log.i( "button"、 "clicked");}});ボタンは、 setonclicklistenerを介してコールバック関数を登録し、上記のように、匿名の内部クラスの形でインターフェイスの参照を渡します。ボタンは新しいスレッドを作成せずにSetonClickListenerを呼び出すため、これは同期コールバックです。
非同期コールバックは、最初に話した例です。
call.enqueue(new callback <historybean>(){@override public void onresponse(call <historybean> call、response <historybean> response){historybean hb = respons.body(); if(hb == null)return; showtext.append(hb.iserror() + "); showtext.append(rb.getTitle() + "/n");このEnqueueメソッドは、リモートネットワークデータを要求する非同期方法です。内部で実装されると、新しいスレッドを介して実行されます。
これら2つの例を通じて、同期コールバックと非同期コールバックの使用は、実際にはさまざまなニーズに応じて設計されていることがわかります。一方が他方を置き換えるとは言えません。たとえば、上記のボタンクリックイベントでは、非同期コールバックの場合、ユーザーがボタンをクリックし、ユーザーが他の操作を実行しないとすぐにクリック効果が表示されません。奇妙に感じます。ネットワークリクエストの非同期コールバックは、要求されたリソースが存在しない可能性があり、ネットワーク接続が不安定であり、他の理由であるため、ユーザーはメソッドの実行について明確ではないため、非同期コールバックを使用し、メソッドコールを開始して他のことを行い、コールバック通知を待ちます。
通信におけるコールバックメソッドの適用
ネットワーク要求フレームワークのコールバックを除き、上記のコールバック方法には、すべてパラメーターがありません。コールバックメソッドにパラメーターを追加して、コミュニケーションの問題を実装してみましょう。
一連の計算と処理後にクラスAにクラスBのデータを取得したい場合、2つのクラスはクラスAのデータを単に参照することはできません。コールバックを検討できます。
手順は次のとおりです。
上記の手順は少し抽象的です。以下の例を見てみましょう。1つはクライアントで、もう1つはサーバーです。クライアントは、サーバーの時間のかかるデータを要求します。
パブリッククラスクライアント{パブリックサーバーサーバー;パブリック文字列リクエスト; //サーバーをリンクし、サーバーの参照を取得します。 public client connect(server server){this.server = server;これを返します。 } //クライアント、[リクエスト]リクエスト[パブリッククライアント[文字列要求] {this.request = request;これを返します。 } //その後、リクエストメソッド、lamdba式を送信します。 public void enqueue(server.callback callback){new Thread(() - > server.setCallback(request、callback))。start(); }} public class server {public string Response = "これはHTML"です。 //コールバックインターフェイスのメソッドを登録し、パラメーターを使用してデータをコールバックインターフェイスに渡しますpublic void setCallback(String request、callback callback){system.out.println( "要求が受信され、計算されています..."); new shood(() - > {try {shood.sleep(5000); callback.onesponse(request + response);} catch(arturtedexception e){e.printstacktrace(); callback.onfail(e);}})。start(); start(); } //データパブリックインターフェイスコールバックを所有するクラスにインターフェイスを書き込む{void onResponse(string response); void onfail(スロー可能なスロー可能); }}次に、テストの例を見てみましょう。
パブリッククラスCallBackTest {public static void main(string [] args){client client = new Client(); client.connect(new server())。setRequest( "このファイルとは?")。enqueue(new server.callback(){@override public void onresponse(string response){system.out.println(response);} @override public void onfail(投げ可能な投げ) }}結果は次のとおりです。
リクエストが受信され、計算されています...このファイルは何ですか?これはHTMLです
上記は、コールバックを介して通信することです。
上記はこの記事のすべての内容です。この記事の内容が、すべての人の勉強や仕事に役立つことを願っています。また、wulin.comをもっとサポートしたいと思っています!