The only way to realize project componentization: decoupling, decoupling again!

A component-based project will subdivide the business, and the common functions are encapsulated in common modules. Different common function modules have a horizontal relationship, and different business modules will rely on several common modules as needed.

As shown in the above figure, business A cannot call the API in business B, and business B cannot open the page in business A. the two business modules are independent, and the same is true between common modules.

If the API needs to be accessed between modules, strong dependencies must be established, and the coupling degree of the project will become very high. The general module loses its general characteristics because it needs a variety of dependencies.

Therefore, we need a loosely coupled way to establish the communication mode between peer modules and realize componentization.

There are many scenarios for communication between modules, such as page access, UI event notification, callback and so on. This paper introduces a library I wrote to help realize the Componentization of the project: KRouter. It is a very lightweight, efficient and stable Android component library. It is written in kotlin and can be used in java, kotlin and even mixed programming projects. It supports multiple modules. Through annotation, it can easily solve the problem of page access between independent modules API call problem.

At the time of writing, KRouter has been developed to version 1.0.4 and is still under maintenance. Readers can visit the project github address: https://github.com/jamgudev/KRouter , get the latest version information.

If you think the library is practical, you are welcome to start and fork. If you find that the inventory has bug s or improvements, you are welcome to submit it issues Or submit pull requests!

Next, let me briefly talk about how to use KRouter.

text

How to use

First, import the library, edit your project build.gradle file, and add the plug-in address in the file:

buildscript {
    dependencies {
        classpath "io.github.jamgudev:krouter-plugin:1.0.4"
    }
}

And reference the plug-in in the application module:

plugins {
    id 'com.jamgu.krouter.plugin'
}

After adding, synchronize the code and you can use all the functions of KRouter.

You may wonder why all libraries supporting annotations need annotation processors. Why can they be used without adding the dependency of annotation processors?

In fact, the com.jamgu.krouter.plugin automatically completes the operation of adding other dependent libraries. I built the latest version number of other dependent libraries into the plug-in. You only need to use the latest version of the plugin plug-in, and you should be able to obtain the latest version of the required dependent libraries.

You can also specify the version of the dependent Library in the build.gradle file of the project:

ext {
	krouter_core_version = "1.0.4" // edit the version number you need
	krouter_compiler_version = "1.0.3"
	
	// flag whether to print compiler logs 
	krouter_compile_loggable = false
}
Multi module support

If you need to use krouter for other dependent modules besides the main project module, you only need to apply the krouter plug-in in the build.gradle of the corresponding module:

plugins {
    id 'com.jamgu.krouter.plugin'
}
Simple use

Activity routing

@KRouter(value = "setting_activity", intParams = {"userId", "gameId"}, stringParams = {"user_name"})
public class SettingActivity extends AppCompatActivity {

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

// Simple call
KRouters.open(context, "setting_activity");
// Call with parameters
KRouters.open(context, new KRouterUriBuilder("router")
              .with("userId", 10000)
              .with("gameId", 20010)
              .with("user_name", "jamgu")
              .build());
// startForResult
KRouters.openForResult(context, "setting_activity", 10010);
// activity routers api
Intent intent = KRouters.getRawIntent(this, "setting_activity");
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), (callback) -> {})
          .launch(intent);

Register global interceptors for Activity routes

KRouters.registerGlobalInterceptor(new IRouterInterceptor() {
    @Override
    public boolean intercept(@NotNull Uri uri, @Nullable Bundle bundle) {
        Log.d(TAG, "uri = " + uri + " bundle = " + bundle);
        return false;
    }
});

When the intercept() method returns true, this route will be intercepted and no jump will be made.

Fragment routing

@KRouter(value = "main_frag", intParams = "col_id")
public class MainFragment extends Fragment {}

// After configuring annotations, you can use main_frag gets the fragment instance
Fragment fragment = KRouters.createFragment(context, "main_frag");

Method routing

@MethodRouter(value = "get_some_state2")
public static boolean getSomeState(Map<String, Object> map, IAsyncMethodCallback<Boolean> callback) {
    // do something
    // If parameters are passed, they can be retrieved as follows
    String userName = (String) map.get("userName");
    long userId = Long.parseLong(map.get("userId").toString());
    Log.d("jamgu", "hhhh userID = " + userId);
    return false;
}

// Simple call without passing parameters. In this case, the map is null,
MethodRouters.invoke("get_some_state2");
// Pass with parameters
boolean state = MethodRouters.invoke("get_some_state2", new MethodMapBuilder()
                     .with("userId", "12345")
                     .with("userName", "jamgu")
                     .build());
// Pass with parameters and a callback at the same time. The callback position is determined by the user
MethodRouters.invoke("get_some_state2", new MethodMapBuilder()
                     .with("userId", "12345")
                     .with("userName", "jamgu")
                     .build(), new IAsyncMethodCallback<Integer>() {
                       @Override
                       public void onInvokeFinish(Integer integer) {
                         // Callbacks for designation elsewhere
                       }
                     });

The MethodRouter has large restrictions. The MethodRouter annotation only supports static methods and only allows the passing of up to two parameters. The passed parameter type can only be Map type or IAsyncMethodCallback type, and two Map types or Callback types cannot be passed at the same time.

For example, you can apply the MethodRouter annotation to static methods in the following format

@MethodRouter(value = "xxx")
public static void getSomeState() {
    // Null return type, no parameters need to be passed 
    return;
}

@MethodRouter(value = "xxx")
public static Integer getSomeState(Map<String, Object> map) {
    // Integer return value type, which can support a Map type parameter
    // When calling, the map can not be passed. When not passed, the map is null
    return 0;
}

@MethodRouter(value = "xxx")
public static Integer getSomeState(Map<String, Object> map, IAsyncMethodCallback<Integer> callback) {
  // It supports passing two parameters. If neither parameter is passed, the two parameters are null
  return false;
}

That's all for the simple usage of KRouter. Let's explore more usage~

If you find a bug when using KRouter or feel that there is anything to be improved, you are welcome to give feedback! I need your suggestions to improve!

Brother dei, if you think my writing is good, please do me a favor 😃

  1. Give me some praise, inspire me, and let more people see this article, (#. #)
  2. Don't order. Oh, don't order. Why did you order? How sorry!

Please, thank you!

Keywords: Android

Added by styler1971 on Wed, 08 Sep 2021 20:35:26 +0300