2016-05-03 7 views
3

Ist die folgende Situation schlechtes Design oder bin ich etwas wichtiges übersehen?Synchronisierte Methode von Android Activity onCreate Methode

Hier ist der Code

public class MainActivity extends AppCompatActivity … { 

    … 

    @Override 
    public void onCreate(Bundle savedInstanceState){ 
    … 
    buildGoogleApiClient(); 
    } 

    /** 
    * Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API. 
    */ 
    protected synchronized void buildGoogleApiClient() { 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
    } 
} 

Warum ist buildGoogleApiClientsynchronized, wenn es überhaupt ist nur von innen onCreate genannt?

Ich weiß, es kann nicht weh tun, aber das ist kaum der Punkt der Frage. Was ich wissen muss ist: Warum ist es notwendig?

bearbeiten

Quelle vollständigen Code: https://github.com/googlesamples/android-play-location/blob/master/BasicLocationSample/app/src/main/java/com/google/android/gms/location/sample/basiclocationsample/MainActivity.java

+0

Danke für die Antwort. Aber leider verstehe ich deine Antwort nicht. Vielen Dank. –

+0

Nach der aktuellen Verwendung der Methode würde ich nein sagen, es ist nicht notwendig. In der Tat würde ich nicht wissen, warum es mehrere Threads versuchen würde, den gleichen API-Client in einer App zu erstellen. – CodeCody

+0

Dies ist von http://developer.android.com/training/location/retrieve-current.html. Ihre Ingenieure sollen Topnotch sein, und sie haben Android gebaut, also ... es lohnt sich zu fragen, was hier passiert. –

Antwort

2

In diesem Fall synchronized wird das Objekt für die Dauer des Anrufs sperren. Wenn auch andere Methoden synchronized deklariert sind, wird jeweils nur einer von ihnen ausgeführt. Wenn beispielsweise von einer synchronisierten Methode auf einen anderen Thread auf mGoogleApiClient zugegriffen wird, stellt die Synchronisierung sicher, dass der andere Thread entweder ein vollständig konstruiertes Objekt oder eine Nullreferenz erkennt.

Sogar damit können Sie immer noch einen Fall machen, dass es eine schlechte Implementierung ist. Ein besserer Ansatz wäre es, jede Methode für ein privates Objekt zu synchronisieren, sodass Code außerhalb der Klasse das Objekt nicht versehentlich sperren und unerwartetes Verhalten verursachen kann. OTOH, es kann argumentiert werden, dass synchronized Methoden für Beispiele netter sind, weil es weniger Codezeilen gibt und es ist einfach, dass die Synchronisierung für die gesamte Methode gilt.

In diesem speziellen Fall könnte volatile funktioniert haben, obwohl ich nicht sicher bin, wie das mit dem Builder-Muster spielt.

In jedem Fall müssen Sie mehr über die ... Abschnitte des Codes wissen, wenn Synchronisation erforderlich ist.

+0

Danke für die Antwort. Ich habe den ... hinzugefügt, um den Code abzuschneiden. Die Quelle befindet sich unter https://github.com/googlesamples/android-play-location/blob/master/BasicLocationSample/app/src/main/java/com/google/android/gms/location/sample/basiclocationsample/MainActivity. Javal. Sie scheinen die Nebenläufigkeit im Allgemeinen zu erklären. Wie aber gilt das Schlüsselwort im vorgegebenen Kontext? –

+0

Ich sehe ein paar Möglichkeiten: (1) Wenn die Callbacks wie 'onConnectionSuspended()' auf einem beliebigen Thread aufgerufen werden können, könnte die Synchronisation nützlich sein. Natürlich sind die Callbacks * nicht synchronisiert, das ist es also nicht. (2) Die synchronisierte Methode ist "protected", also nahm der Entwickler möglicherweise an, dass sie in einer abgeleiteten Klasse verwendet wird, die ebenfalls multi-threaded ist. (3) Es wurde kopiert und eingefügt von einem anderen Projekt, wo es tatsächlich notwendig war. Was auch immer der Fall ist, wenn auf "mGoogleApiClient" nur von einem Thread aus zugegriffen wird, müssen Sie den Zugriff darauf nicht synchronisieren. – fadden

+0

Vielen Dank für Ihre Eingabe. +1. –

Verwandte Themen