[JAVA] Une histoire que les personnes qui ont fait iOS solidement peuvent être accro à la mise en œuvre de Listener lors du passage à Android

en premier

Après un certain temps d'implémentation d'iOS, si vous commencez à implémenter Android après une longue période, Pour une raison quelconque, j'étais un peu ennuyé que l'instance Listener soit sortie à un moment étrange.

Ce que j'ai fait

Peut-être que tout le monde a écrit une fois, Delegate sous iOS, Listener sous Android ↓ Je l'ai implémenté comme ça. Je me fiche du fait que le nom de la méthode ou le style soit étrange.

iOS


import UIKit

// UI
class ViewController: UIViewController, ModelDelegate {
    
    let model = Model()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        model.delegate = self
    }
    
    func notify(model: Model) {
    }
}

//Modèle et protocole pour les notifications
protocol ModelDelegate: class {
    func notify(model: Model)
}
class Model {
    weak var delegate: ModelDelegate?
    
    func doSomething() {
        //Faire quelque chose
        delegate?.notify(model: self)
    }
}

Android


import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.lang.ref.WeakReference;

// UI
public class MainFragment extends Fragment {

    private Model model;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        this.model = new Model();
        model.setListener(new ModelListener() {
            @Override
            public void notify(Model model) {

            }
        });

        return super.onCreateView(inflater, container, savedInstanceState);
    }
}

//Modèle et interface pour la notification
interface ModelListener {
    void notify(Model model);
}

class Model {

    private WeakReference<ModelListener> mListener;

    void setListener(ModelListener listener) {
        mListener = new WeakReference<>(listener);
    }

    void doSomething() {
        //Faire quelque chose
        //Vérifier en fait null

        mListener.get().notify(this);
    }
}

Donc, cela fonctionne très bien sur iOS. Cela semble fonctionner correctement sur Android, mais à un moment donné, mListener.get () retourne soudainement null.

Cause

Il a été dit que si elle était implémentée avec une classe anonyme, aucune instance ne ferait fortement référence à Listener, elle serait donc soumise à GC. MListener.get () retournera null lors de l'exécution du GC.

C'était correct car il était fortement référencé lorsqu'il était implémenté dans une classe normale, pas dans une classe anonyme.

Pensées

(Alors ne devrait-il pas être une référence faible? Mais si vous faites une référence forte, elle circulera lorsque vous l'implémenterez dans une classe normale qui n'est pas une classe anonyme. Eh, est-ce que java est un putain de langage qui vous oblige à implémenter une interface?)

Bien sûr, ce n'était pas le cas, et c'était moi qui baisais.

Après tout

Comme vous l'avez peut-être remarqué, java possède un GC, il n'y a donc pas de problème même s'il circule. Je l'ai donc changé pour une référence normale au lieu de WeakReference.

Les personnes qui n'ont fait qu'iOS doivent être prudentes lors de l'écriture d'un langage avec GC.

À la fin

Ce fut une bonne expérience de réaliser que les classes anonymes sont un concept possible grâce à GC.

Recommended Posts

Une histoire que les personnes qui ont fait iOS solidement peuvent être accro à la mise en œuvre de Listener lors du passage à Android
L'histoire de l'introduction de Gradle en tant que modernisation d'un système existant qui ne gérait pas de packages
Un mémo sobrement accro à la demande de multipart / form-data
Une histoire à laquelle j'étais accro lors du test de l'API à l'aide de MockMVC
Une histoire confirmant l'implémentation de la bibliothèque Java SendGrid lorsque la livraison du courrier échoue
Une histoire accro à EntityNotFoundException de getOne de JpaRepository
Notez que j'étais accro aux paramètres du projet Android d'IntelliJ IDEA
Une histoire à laquelle j'étais accro lors de l'obtention d'une clé qui a été automatiquement essayée sur MyBatis
Convertir un tableau potentiellement nul en flux
L'histoire à laquelle j'étais accro lors de la création de STS
Une collection de modèles dont vous voulez être conscient pour ne pas compliquer le code
Essayons la mise en œuvre pour trouver l'aire du triangle que nous avons fait dans la formation des nouveaux arrivants
Une histoire qui m'a fait regretter quand une "NotReadablePropertyException" s'est produite pendant le développement de l'application Spring Boot.
[Rails] Une histoire qui a continué à vérifier incorrectement la raison pour laquelle l'action de mise à jour n'a pas réussi (mise à jour)
Une histoire qui pourrait être mise en œuvre proprement en utilisant le polymorphisme lorsque vous souhaitez exprimer deux types de données dans une table