2016-09-17 21 views
0

Gesamt Anfänger hier.Fragment to Fragment Kommunikation - Warum ist die Schnittstelle wirklich notwendig?

Wie ich verstehe, sollten Fragmente durch ihre Hosting-Aktivitäten miteinander kommunizieren, um in anderen Situationen unabhängig und wiederverwendbar zu bleiben.

Ich habe gelesen, dass sollte getan werden, indem Interfaces im Fragment deklarieren und sie in der Aktivität implementieren. Ist das der beste Weg, "nur" zu gehen, weil Sie sicherstellen können, dass die Aktivität für diese Kommunikation bereit ist (es hat wirklich diese Methode, um mit der Kommunikation umzugehen)?

Da ich mich nur schwer mit Schnittstellen (und vielen anderen Dingen in Java/Android) herumschlagen kann, könnte dies ohne die Schnittstelle geschehen? Kann ich einen Verweis auf die Hosting-Aktivität im Fragment erhalten und einfach die Methode der Aktivität aufrufen?

(Fragment Klasse)

Activity activity = getActivity(); 

activity.doThatThingToOtherFrag(String myString); 

(Aktivitätsklasse)

Fragment otherFragment = getSupportFragmentManager().findFragmentById(R.id.myOtherFrag); 

public void doThatThingToOtherFrag(String string) { 
//do something to myOtherFrag 
} 

Oder ist es etwas anderes, über eine Schnittstelle in diesem Fall der Umsetzung, die ich nicht bekommen?

* EDIT *

Sagen wir, ich, dass Fragment in einer anderen Aktivität wiederverwenden. Solange diese Tätigkeit auch eine doThatThingToOtherFrag (String myString) Methode hat, kann ich einen Verweis auf sie durch getActivity() bekommen und noch activity.doThatThingToOtherFrag (String myString) von meinem Fragment nennen, nicht wahr? Ich müsste an meinem Fragmentcode nichts ändern - oder verpasse ich hier etwas?

Ich denke, meine Frage sollte sein: ist die Schnittstelle dort nur, um sicherzustellen, dass die/jede Hosting-Aktivität implementiert doThatThingToOtherFrag Methode? Oder gibt es noch etwas, das ich in dieser Situation nicht über Schnittstellen weiß? Danke für die Hilfe!

+0

Nun, Sie vermissen die Tatsache, dass es nicht 'Activity' sein wird, sondern' MyActivity' und Ihre Methode mehr wie '((MyActivity) activity) .doThatThing' ... mit anderen Worten, da' doThatThing' zu '' gehört MyActivity' wirst du wirken müssen, was eng mit MyActivity gekoppelt ist. – trooper

+0

... um sie erneut zu verwenden, müssen Sie diese Umwandlung jedes Mal ändern, es sei denn, Sie programmieren eine Schnittstelle. Wenn Sie immer mit Activity arbeiten (und nicht mit einer Subklasse), dann hat die Schnittstelle keinen Sinn, aber sie geht davon aus, dass 'doThatThing' eine von Ihnen geschriebene Methode ist und nicht etwas, das bereits zu Ihrer' Activity'-Basisklasse gehört. – trooper

+0

Ich dachte, ich könnte jede Unterklasse von Activity (zB 'FragmentActivity') einfach in' (Activity) 'umwandeln und solange die doThatThing-Methode da wäre, müsste ich nichts in meinem Fragmentcode ändern. –

Antwort

2

"Programm an die Schnittstelle." ist eine gemeinsame Maxime der objektorientierten Programmierung. Sie können sicherlich direkt mit der Aktivität kommunizieren, ohne die Schnittstelle zu verwenden. Dies erzeugt jedoch eine enge Kopplung zwischen dem Fragment und der Aktivität.

Betrachten Sie eine Situation, in der Sie dasselbe Fragment in zwei verschiedenen Aktivitäten wiederverwenden möchten. Die Verwendung der Schnittstelle ermöglicht die Flexibilität, dies zu tun.

Antwort zu bearbeiten:

Solange diese Tätigkeit auch eine doThatThingToOtherFrag (String myString) Methode hat, kann ich einen Verweis auf sie durch getActivity() erhalten und rufen Sie noch activity.doThatThingToOtherFrag (String myString) von meinem Fragment, richtig?

Ich nehme an, Sie so etwas wie dies bedeuten:

Activity activity = getActivity(); 
activity.doThatThingToOtherFrag(String myString); 

Dies wird nicht kompiliert, da Activity keine Methode doThatThingToOtherFrag() benannt hat. Wenn Sie jedoch tun

FragmentCommunicationInterface activity = (FragmentCommunicationInterface) getActivity(); 
activity.doThatThingToOtherFrag(String myString); 

jetzt wird es kompilieren. Dies hat noch ein weiteres Problem: Was ist, wenn das Fragment, wo dieses aufgerufen wird, zu einem Activity hinzugefügt wurde, das FragmentCommunicationInterface implementiert nicht. Jetzt erhalten Sie einen Laufzeitfehler, wenn Sie den Fall ausführen.

Eine mögliche Lösung dieses Problems ist ein FragmentCommunicationInterface als Argument an das Fragment Konstruktor zu nehmen:

public class MyFragment extends Fragment { 
    private FragmentCommunicationInterface communication; 

    public MyFragment(FragmentCommunicationInterface communication) { 
     this.communication = communication; 
    } 
} 

Sie jetzt ein Fragment mit

MyFragment frag = new MyFragment(this); 

Ein weiterer Vorteil bei der Verwendung eine Schnittstelle schaffen ist, dass Die Schnittstelle kann implementiert werden durch jede Klasse nicht nur Klassen, die Activity erweitern. Dies ermöglicht noch mehr Flexibilität als ich oben angedeutet habe. Es ermöglicht Ihnen, den Code so zu organisieren, dass er mit der Aktivität oder anderen Fragmenten beliebig kommuniziert.

+0

Wird die Schnittstelle nur verwendet, um zu garantieren, dass die Aktivität eine doThatThingToOtherFrag-Methode implementiert hat oder gibt es einen Grund, warum ich immer noch nicht weiß? Bitte lesen Sie meine Bearbeitung wenn möglich. Vielen Dank! –

+0

@ bernardo.g Das ist ein Grund. Siehe meine Bearbeitung für Details zu Ihrer eigenen Bearbeitung. –

-1

Schnittstellen sind am besten für die Kommunikation von zwei Fragmenten, 2 Aktivitäten oder kommunizieren mit jeder Klasse, weil Schnittstelle gleichzeitig ausgelöst wird, wenn andere kommunizieren möchten.

2

Es ist nicht wirklich notwendig, aber es kann wünschenswert sein.

Im Allgemeinen helfen Schnittstellen Code nicht von der Klasse, deren Code Sie aufrufen. Es interessiert Sie nicht, welche Fragment-Klasse Sie aufrufen, was Sie wirklich interessieren ist, dass was auch immer Sie aufrufen, es muss die Fähigkeit haben, doThisOrThat() - das ist, was Sie in Ihre Schnittstelle einfügen.

Diese Entkopplung hilft eigentlich Polymorphie zu verwenden. Angenommen, Ihr Code könnte zwei Fragmentklassen verwenden, in denen Sie jetzt eine verwenden, und beide können doThisOrThat(). In diesem Fall hilft Ihnen die Verwendung einer Schnittstelle, saubereren Code zu schreiben, da Sie keinen doppelten Code schreiben müssen, um die gleiche Methode aufzurufen, außer zu ändern, auf was Sie ihn umsetzen.

Wie auch immer, um Ihre Klassen wirklich zu entkoppeln, möchten Sie vielleicht etwas über EventBus erfahren (egal welche Implementierung).

+0

Ich habe kürzlich von EventBus gehört, ich wollte es überprüfen. Vielen Dank! –

2

Auf diese Weise können Sie Ihr Fragment mit jeder Aktivität arbeiten lassen, die die Schnittstelle implementiert. Dies trägt zur Unabhängigkeit und Wiederverwendbarkeit bei, auf die Sie in Ihrer Frage hingewiesen haben.

Wenn Sie die Methode der Aktivitätsklasse verwenden würden, um zu "kommunizieren", könnten Sie andere (andere) Aktivitäten nicht ausführen, weil sie einer anderen Klasse angehören.

+0

Könnten Sie sich bitte meinen Schnitt ansehen? Es passte hier nicht. –

+1

Die Methode, die Sie aus dem Fragment aufrufen möchten, muss zur Laufzeit in einer Klasse oder in einer von einer Klasse implementierten Schnittstelle definiert sein, damit sie ordnungsgemäß verknüpft ist. Zur Erinnerung: In Java zur Laufzeit existieren keine Namen; Sie werden in Symbole umgewandelt, und daher ist eine strenge Definition obligatorisch. – whitebrow

+1

Mit anderen Worten: Zwei Methoden mit demselben Namen haben zur Laufzeit unterschiedliche Symbole. – whitebrow

0

Ein guter Grund, die oben beschriebene Implementierung nicht durchzuführen, ist eine lose Kopplung. Es ist ein Programm-Design-Muster, um gut gestaltete Software zu erstellen. Ich werde hier keine neue Diskussion erstellen, da viele andere Diskussionen in StackOverflow verfügbar sind.

What is "loose coupling?" Please provide examples

Bitte Zeit nehmen, um dieses Konzept zu verstehen, wie dieses Sie als Programmierer viel Zeit sparen.

Prost!

Verwandte Themen