The original address: https://www.jianshu.com/p/35a8959c2f86

  • Solving Retrofit multi-baseurL and dynamically changing BaseUrl at runtime
  • Solving Retrofit multi-baseurL and dynamically changing BaseUrl at runtime (II)

preface

In my previous article, “Solving Retrofit Multiple BaseUrl and Dynamically Changing BaseUrl at runtime,” I described four common solutions on the market to solve this problem and opened source my own optimized solution, RetrofitUrlManager. Now for the second article in this series, this article focuses on RetrofitUrlManager’s major upgrade to the BaseUrl replacement logic, because this upgrade is important enough for RetrofitUrlManager, Will enable Retrofit Manager to cope with more complex requirements, so write a separate article to let more people know

Github: Your Star is my motivation ✊

Why not use multiple Retrofit instances?

In the previous article, “Solving Retrofit Multi-BaseurL and Dynamically changing BaseUrl at runtime,” I described the features and disadvantages of the four solutions very clearly. If you haven’t read this article, please read it to broaden your knowledge. In the later years, I was often asked why I didn’t use multiple Retrofit instances, as multiple Retrofit instances didn’t seem to take up a lot of resources.

Before answering, in order to make the readers of this article understand what I am talking about, I will paste part of the description of this scheme from the previous article

Common folk solutions: I have seen the source code of many open source aggregator apps, such as some apps that integrate the data of zhihu, Douban, Gank and other platforms. Because the domain name of each platform is different, most of these apps will create a Retrofit object for each platform. That is, different BaseurLs use different Retrofit objects to create ApiService requests, so whenever a different BaseUrl is added, a new Retrofit object needs to be created

To answer this question again in this article, creating a Retrofit instance with the same other configuration properties for each different BaseUrl is not only a waste of resources, but also an increase in interface management costs, for example

All ApiService in our usual project starts the request for the interface by instantiating the Retrofit# Create (ApiService) method of the same Retrofit instance

However, when there are multiple Retrofit instances in the project, we need to distinguish not only which interfaces use which ApiService, but also which ApiService needs to be instantiated with which Retrofit instance. If an ApiService is instantiated with the wrong Retrofit instance, all interface requests to the ApiService are doomed to complete failure

The more complex the project, the larger the number of people working on it, the greater the risk of error, the less scalable it is, and the later changes will be painful, as the number of interfaces in the project and the number of Retrofit instances (BaseUrl) increases exponentially

The solution using multiple Retrofit instances has high initial investment cost, which may affect the way of previous project management interface. Some projects that encapsulate Retrofit may also need major changes, which is not good for the access of old projects. RetrofitUrlManager can not only meet the needs of multiple BaseUrl and dynamic change of BaseUrl at runtime, but also has the characteristics of hot swap and low invasion, which will not affect the previous interface management mode and use mode in the process of use, and has strong scalability. It can cope with the increasingly complex base L replacement requirements

A problem with retrofit Manager prior to the upgrade

The previous version of RetrofitUrlManager only fully implemented the ideas of the previous article and had the foundation of the whole framework. However, it was not strong enough to dynamically replace BaseUrl. The most ridiculed version was only able to replace the domain name of BaseUrl

Such as a need to replace the BaseUrl Url “https:www.google.com/api/v2”, including “https:www.google.com/api” is we to Retrofit BaseUrl, Using the RetrofitUrlManager framework, we want to replace BaseUrl with “HTTPS :www.github.com”, and we expect the URL to be” HTTPS :www.github.com/v2″. But after using a framework to replace the actual URL address is “https:www.github.com/api/v2”, “/ API” as part of the BaseUrl has not been replaced new BaseUrl, and just replace the domain name in the BaseUrl

How does Retrofit Manager improve

Why is it so? Because the URL that the RetrofitUrlManager framework intercepts in the interceptor is the final path that Retrofit has merged BaseUrl with the relative path in the interface annotations, So the framework doesn’t know that the BaseUrl you pass to Retrofit contains the following “/ API “in addition to the domain name. The framework doesn’t know the exact value of BaseUrl, so the framework just defaults to all BaseUrl containing only domain names, so it can only replace domain names

Advanced mode

To solve this problem, you can simply tell the RetrofitUrlManager framework the specific value of the BaseUrl that you passed to Retrofit, So the framework update added RetrofitUrlManager#startAdvancedModel(String) method. Pass the BaseUrl that you passed to Retrofit when your App is initialized to this method to enable advanced mode. Advanced mode can replace BaseUrl with multiple pathSegments, not just domain names

What is a pathSegment?

In “https://www.github.com/wiki/part?name=jess”, “/ wiki” and “/ part” is pathSegment, PathSize is pathSegment number

The PathSize of this URL is 2. The first pathSegment is “/wiki” and the second pathSegment is “/part”

Substitution rules for advanced mode

  1. Old URL address is “https://www.github.com/wiki/part”, You when the App is initialized to RetrofitUrlManager# startAdvancedModel BaseUrl (String) for “https://www.github.com/wiki”, Do you want to replace the BaseUrl address is “https://www.google.com/api”, after a framework to replace the generated the final URL address is “http://www.google.com/api/part”

  2. Old URL address is “https://www.github.com/wiki/part”, You when the App is initialized to RetrofitUrlManager# startAdvancedModel BaseUrl (String) for “https://www.github.com/wiki”, Do you want to replace the BaseUrl address is “https://www.google.com”, after a framework to replace the generated the final URL address is “http://www.google.com/part”

  3. Old URL address is “https://www.github.com/wiki/part”, You pass in the BaseUrl of RetrofitUrlManager#startAdvancedModel(String) as “https://www.github.com” during App initialization, Do you want to replace the BaseUrl address is “https://www.google.com/api”, after a framework to replace the generated the final URL address is “http://www.google.com/api/wiki/part”

Super model

Super mode is an enhanced version of advanced mode, taking precedence over advanced mode, which supposedly meets most of your development needs. What is super mode? Let’s talk about advanced mode first

Principles of advanced mode

In advanced mode you need to send a copy of the BaseUrl that you passed to Retrofit at App initialization to enable advanced mode. After successfully enabling Advanced mode, The BaseUrl passed to RetrofitUrlManager#startAdvancedModel(String) is used as the base for the framework to replace BaseUrl

What is a benchmark? Using this BaseUrl to enable advanced mode does not mean that the framework can only replace urls with the domain name “www.github.com” with the first two pathSegments of “/wiki/part”. Any URL with a domain name and two pathSegments greater or equal can be replaced by the framework. So advanced mode only saves the format of the BaseUrl passed in RetrofitUrlManager#startAdvancedModel(String) (the number of pathSegments), not the specific value

Limitations of advanced modes

If to RetrofitUrlManager# startAdvancedModel BaseUrl (String) for “https://www.github.com/wiki/part” (PathSize = 2), The framework treats the domain name in all urls in the project and the first two pathSegments following the domain name as the whole BaseUrl that can be replaced, That means the framework simply cuts and replaces the domain name and the first two pathSegments in the URL with the desired BaseUrl

Then the server suddenly adjusts, Project only a part of the URL need to “https://www.github.com/wiki” (PathSize = 1), the second pathSegment “/ part” is no longer as part of the BaseUrl, cannot be replaced, It has to be preserved

At this time, there are multiple BaseUrl formats that need to be replaced (different pathsizes). Some urls only need to be replaced with the domain name and the first two pathSegments, and some only need to be replaced with the domain name and the first pathSegments. However, when the advanced mode is enabled, When only one BaseUrl format is saved, implementing this requirement with advanced mode is trickier

This requirement is quite abnormal, and many people may not meet it, but I want you to know that when you meet it, don’t be afraid, because the super mode of Retrofit Manager has given you full consideration

The use of super mode

Unlike advanced mode, super mode does not require an API call to enable, Just add RetrofitUrlManager#IDENTIFICATION_PATH_SIZE (#baseurl_path_size=) + PathSize to the end of the Url that requires super mode to be enabled. The BaseUrl that needs to be replaced in this URL contains several pathSegments, which means that each URL can specify the format of the BaseUrl that needs to be replaced. This way, compared with the advanced mode, the BaseUrl can only be replaced during App initialization. Specifying a global BaseUrl format is much more flexible; if you enable super mode when you enable advanced mode, only super mode will be executed because super mode takes precedence over advanced mode

Replacement rules for super mode

  1. Old URL address is “https://www.github.com/wiki/part#baseurl_path_size=1”, # baseurl_path_size = 1 “” said one BaseUrl for” https://www.github.com/wiki “, you want to replace the BaseUrl address is “https://www.google.com/api”, Generated after a framework to replace the final URL address is “http://www.google.com/api/part”

  2. Old URL address is “https://www.github.com/wiki/part#baseurl_path_size=1”, # baseurl_path_size = 1 “” said one BaseUrl for” https://www.github.com/wiki “, you want to replace the BaseUrl address is “https://www.google.com”, Generated after a framework to replace the final URL address is “http://www.google.com/part”

  3. Old URL address is “https://www.github.com/wiki/part#baseurl_path_size=0”, “# baseurl_path_size = 0,” said one BaseUrl for “https://www.github.com”, you want to replace the BaseUrl address is “https://www.google.com/api”, Generated after a framework to replace the final URL address is “http://www.google.com/api/wiki/part”

  4. Old URL address is “https://www.github.com/wiki/part/issues/1#baseurl_path_size=3”, “# baseurl_path_size = 3” said one BaseUrl for “https://www.github.com/wiki/part/issues”, Do you want to replace the BaseUrl address is “https://www.google.com/api”, after a framework to replace the generated the final URL address is “http://www.google.com/api/1”

Comparison of the three modes

Before upgrading, the framework is a default normal mode (can only replace the domain name), after the upgrade of new advanced mode and super model, these two modes framework become more powerful, in the content above also detailed introduced the two patterns, to summarize the three patterns, that is now let you can according to their own needs to choose the most suitable model

Degree of freedom to replace BaseUrl (extensibility)

Normal mode < Advanced mode < Super mode

  • Common mode: Only domain names can be replaced

  • Advanced mode: can only replace the fixed BaseUrl format passed in RetrofitUrlManager#startAdvancedModel(String)

  • Supermode: Each URL can optionally specify a BaseUrl format that can be replaced

Degree of complexity in use

Normal mode < Advanced mode < Super mode

  • Common mode: You do not need to configure too much

  • Advanced mode: call RetrofitUrlManager#startAdvancedModel(String) once during App initialization

  • Super mode: RetrofitUrlManager#IDENTIFICATION_PATH_SIZE (#baseurl_path_size=) + PathSize is added to the end of every URL that requires super mode

conclusion

Therefore, the greater the degree of freedom, the more complex the use, so they can choose the corresponding mode according to their own needs, and can also upgrade or downgrade the three modes according to the change of needs

This update takes RetroFit Manager up a notch to handle complex Base L replacement needs, and because Retrofit Manager is extremely scalable, it can even be done now, Lets the server remotely control multiple baseurls in a project dynamically

If you have any questions or needs, please give me Issues. If Retrofit Manager can bring you substantial help, please don’t be too frugal with your Star

The public,

Scan the code to follow my official account JessYan to learn and make progress together. If there is any update to the framework, I will inform you immediately on my official account


Hello, my name is JessYan. If you like my articles, you can follow me on the following platforms

  • Personal homepage: Jessyan.me
  • Making: github.com/JessYanCodi…
  • The Denver nuggets: juejin. Cn/user / 976022…
  • Jane: www.jianshu.com/u/1d0c0bc63…
  • Weibo: weibo.com/u/178626251…

— The end