Routage personnalisé sous Android

Préface :
 Cet article concerne le routage principal, pas ARouter ! Il est recommandé de l'utiliser dans un composant séparé. Bien sûr, il est également possible si vous souhaitez l'utiliser entre des composants, à condition que le composant ait une relation de référence correcte, telle que comme entre deux composants Saut d'interface, lorsque le composant A passe au composant B, il doit y avoir une référence à B dans A, ARouter peut se rendre compte qu'il n'y a pas de relation de référence entre les différents composants à sauter, car les données pertinentes ont été extraites séparément via APT pendant la compilation Oui, lorsque vous l'utilisez, vous pouvez obtenir les données pertinentes grâce au principe de réflexion, puis vous pouvez les exploiter.
Si vous souhaitez utiliser plusieurs composants, il est recommandé d'utiliser ARouter.

Pourquoi
et comment écrire le routage Avant, parlons de la raison pour laquelle le routage est utilisé, des avantages et des inconvénients de son utilisation.

Contexte : à mesure que les exigences commerciales et la logique de l'APP deviennent de plus en plus complexes, la quantité de code pour les développeurs et le seuil pour les projets d'entrée de gamme sont de plus en plus élevés, en particulier pour les projets avec un volume d'affaires particulièrement important. S'il n'est pas optimisé à temps, comme la composantisation, etc., de nombreux problèmes seront exposés à mesure que la demande augmente.

Avantages : Le routage est très adapté aux scénarios commerciaux complexes. En termes techniques, cela signifie simplification du code et découplage. Et il convient également pour itérer lentement, sans avoir beaucoup d’impact sur le cadre et les fonctions d’origine.

Inconvénients : étant donné que le routage sacrifie le couplage et le découplage, la logique métier doit être traitée de manière centralisée. Afin de distinguer différents scénarios métier, un grand nombre de « nombres » (constantes) seront générés. Ici, la réflexion sur les numéros de fonction et les numéros d'interface peut être utilisé, comme les constantes pour une interface

public static final String A = "A";  

Au lieu de cela, passez à l'interface XX avec

public static final String B = "B"; 

Il est plutôt fortement recommandé que chaque constante soit annotée pour indiquer ce qu’elle signifie, sans quoi de nouveaux partenaires pourraient être amenés à en parler.

Autres : ce qui précède conduit à l'idée du numéro de fonction et du numéro d'interface. Il est fortement recommandé à tout le monde de l'utiliser ici. Il est très intuitif d'utiliser une constante spécifique pour représenter une certaine fonction ou méthode, et cela réduit également le quantité de code. Il est très confortable à utiliser.

Il existe de nombreuses façons d’écrire un routage. Ici, je ne partagerai que celle que j’ai rencontrée. Ne la vaporisez pas.

pratique:

Conditions : une interface, une classe qui stocke les codes (numéro de fonction, numéro d'interface), une classe de routage (peut être placée dans des composants publics), une classe d'implémentation concrète (dans les composants correspondants)

Introduction : Écrivez les méthodes associées dans l'interface, stockez les interfaces et les codes associés dans la classe de routage et renvoyez différents rappels d'interface via différents codes, afin de fonctionner dans la classe d'implémentation relative. ConcurrentHashMap est utilisé pour le stockage ici (Introduction : recommandation officielle, collection efficace et sécurisée pour les threads)

Remarque : le routage doit être enregistré avant utilisation (utilisé pour stocker les données dans la classe de routage, généralement dans l'application), la classe d'implémentation doit hériter de l'interface et effectuer un rappel dans la méthode associée de l'interface.

Effet : envoyer le routage et réaliser les fonctions associées.
Code d'implémentation (tous indiqués dans les commentaires) :

interface

/**
 * 作者:zch
 * 时间:2022/4/24 10:21
 * 描述:路由接口
 */
public interface MyRouterCallBack {
    
    
    //路由方法,根据需求可以写多个
    MyRouter doCallBack(Map<String, Object> reqMap);

}

classe de routage

/**
 * 作者:zch
 * 时间:2022/4/24 10:08
 * 描述:路由类
 */
public class MyRouter {
    
    

    //用于存储接口和对应的编码号,根据编码拿出对应的接口,进行操作
    private ConcurrentHashMap<String, Object> mTztRouterActions;

    //单例模式或者实例
    private static MyRouter myRouter;

    public static MyRouter getIns(){
    
    
        if (myRouter == null){
    
    
            myRouter = new MyRouter();
        }
        return myRouter;
    }

    //注册路由,也就是将路由存储在集合里
    public void registerRouter(String action, MyRouterCallBack callBack) {
    
    
        //非空判断,防止重复创建实例
        if (mTztRouterActions == null){
    
    
            mTztRouterActions = new ConcurrentHashMap<>();
        }
        //如果存在就移除重新添加,防止重复,所以相同编码号是不能重复注册的
        if (mTztRouterActions.containsKey(action)){
    
    
            mTztRouterActions.remove(action);
        }
        //添加到集合里
        mTztRouterActions.put(action,callBack);
    }

    //路由操做
    public MyRouter callRouter(Map<String, Object> reqMap){
    
    
        //拿到编码号
        String o = (String)reqMap.get(MyNumber.key);
        //条件判断
        if (!TextUtils.isEmpty(o) && mTztRouterActions != null){
    
    
            //拿到对应的接口实例
            MyRouterCallBack mRouter = (MyRouterCallBack)mTztRouterActions.get(o);
            if (mRouter != null){
    
    
                //接口内方法操作,在对应的实现类里面回进行响应,也就是在对应类里面进行操作
                mRouter.doCallBack(reqMap);
            }
        }

        return this;
    }
}

Codage

/**
 * 作者:zch
 * 时间:2022/4/24 15:07
 * 描述:存放编码类
 */
public class MyNumber {
    
    
    //通过HashMap传递信息,者个是统一的存放编码号的key,下面的编码号放到value里面
    public static final String key = "Key";
    //不同的编码号,要对应不用的功能
    public static final String A = "A";
    //不同的编码号,要对应不用的功能
    public static final String B = "B";
    //不同的编码号,要对应不用的功能
    public static final String C = "C";
    //不同的编码号,要对应不用的功能
    public static final String D = "D";
}

Classe de mise en œuvre concrète

/**
 * 作者:zch
 * 时间:2022/4/24 10:50
 * 描述:具体实现类
 */
public class MyRouter_now implements MyRouterCallBack {
    
    

    //单例获取实例
    @SuppressLint("StaticFieldLeak")
    private static MyRouter_now myRouter_now;
    private Context c;
    public static MyRouter_now getIns(Context c){
    
    
        if (myRouter_now == null){
    
    
            myRouter_now = new MyRouter_now();
        }
        myRouter_now.c = c;
        return myRouter_now;
    }

    //不同的编码号以及接口注册,因为该类以及实现了相关接口,所以之间用 this 即可
    public void registerRouter() {
    
    
        MyRouter.getIns().registerRouter(MyNumber.A,this);
        MyRouter.getIns().registerRouter(MyNumber.B,this);
        MyRouter.getIns().registerRouter(MyNumber.C,this);
        MyRouter.getIns().registerRouter(MyNumber.D,this);
    }

    //接口回调
    @Override
    public MyRouter doCallBack(Map<String, Object> reqMap) {
    
    
        //回调过来的 Map,拿到对应的编码号
        String wwe = (String) reqMap.get(MyNumber.key);
        //防异常
        try {
    
    
            //根据不同的编码号进行不同的操作,在这集中处理
            switch (Objects.requireNonNull(wwe)){
    
    
                case MyNumber.A:
                     Toast.makeText(c.getApplicationContext(),"我是A的操作",Toast.LENGTH_SHORT).show();
                     break;
                case MyNumber.B:
                     Toast.makeText(c.getApplicationContext(),"我是B操作",Toast.LENGTH_SHORT).show();
                     break;
                case MyNumber.C:
                     Toast.makeText(c.getApplicationContext(),"我是C操作",Toast.LENGTH_SHORT).show();
                     break;
                case MyNumber.D:
                     Toast.makeText(c.getApplicationContext(),"我是D操作",Toast.LENGTH_SHORT).show();
                     break;
                default:
                     break;
            }
        }catch (Exception e){
    
    
            e.printStackTrace();
        }

        return null;
    }
}

Activité

public class MainActivity extends AppCompatActivity{
    
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //注册路由,正常在Application那里注册
        MyRouter_now.getIns(getBaseContext()).registerRouter();

        findViewById(R.id.tv_o).setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //发送路由,不管想要使用什么方法,都可通过此方式,前提是 规定好编码号,路由那里进行注册,才能正常使用
                HashMap<String, Object> hashMap = new HashMap<>();
                //编码号 key 固定,用于路由类获取,后面对应操作
                hashMap.put(MyNumber.key,MyNumber.D);
                MyRouter.getIns().callRouter(hashMap);
            }
        });

    }
}

Ce qui précède représente l’intégralité du contenu de la classe de routage, juste pour donner une idée.

Guess you like

Origin blog.csdn.net/As_thin/article/details/124388310