The previous article [Android Componentized Development Framework] analyzed the technical principles of building a componentized framework as a whole. A brief analysis of componentization is given.

Stitch is a framework organized by perfecting the previous theories in the process of project practice. It has completed the basic functions of component life cycle, page routing and data routing, and the source code of the framework also includes examples of scripts that may be needed to build componentization.

The framework consists of three parts: component lifecycle management, page interaction, and data interaction. We parse them in turn.

Rely on

// compile is used before AS 3.0'bamboo.com ponent: stitcher: 1.0'Implementation is recommended after AS 3.0'bamboo.com ponent: stitcher: 1.0'
Copy the code

Component lifecycle management

Each component is equivalent to one Module, and the services of many components need to be initialized when the App is started. For example, carrier payment SDK basically needs to be initialized in the onCreate method of Application.

Stitch framework adopts manual configuration. Components inject themselves into stitch framework, and the main project manages the life cycle of components uniformly through stitch framework.

Specific use method:

1. ComponentApplication inheritance
public abstract class ComponentApplication {
    //Application object injection
    public void setApplication(Application application);// Controls the initialization order of components, see ComponentPriority
    public int level(a);

    // Proxy Application's OnCreate method
    public void onCreate(a);

    // Delay the initialization lifecycle for page injection and data interaction interfaces
    public void onCreateDelay(ComponentRouterRegistry routerRegistry, ActivityRouterRegistry activityRouterRegistry);// Proxy the Application attachBaseContext method
    public void attachBaseContext(Context baseContext) ;

    // Delegate Application's onTrimMemory method
    public void onTrimMemory(int level) ;

    // Delegate the Application's onConfigurationChanged method
    public void onConfigurationChanged(Configuration newConfig);

    // Delegate Application's onLowMemory method
    public void onLowMemory(a);
}
Copy the code

ComponentApplication is a proxy class for component life cycle, which represents the key methods of Application. If the component does some initialization at App startup or needs to listen for the lifecycle, you can do so with ComponentApplication.

2. Configure it in the Androidmanifest.xml file of the Module
    <application>
        ...
        <meta-data
            android:name="bamboo.sample.account.component.AccountComponentApp"
            android:value="ComponentApplication" />
    </application>
Copy the code

Note that meta-data value is ComponentApplication and name is our Module’s proxy Application class. Don’t get it backwards.

3. Modification of custom Application in the main project

In the main project Application, we need to actively call the component’s proxy Application method. Stitcher provides two ways:

1. Directly inherit StitcherApplication

public class MainApplication extends StitcherApplication {
}
Copy the code

2. Invoke the component lifecycle through StitcherHelper. Reference StitcherApplication.

public class StitcherApplication{
    public void onCreate() {
        super.onCreate();
        StitcherHelper.onCreate();
    }

    public void onCreateDelay() {
        StitcherHelper.onCreateDelay();
    }

    public void attachBaseContext(Context baseContext) {
        super.attachBaseContext(baseContext);
        StitcherHelper.init(this);
        StitcherHelper.attachBaseContext(baseContext);
    }

    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        StitcherHelper. onTrimMemory(level);
    }

    public void onLowMemory() { super.onLowMemory(); StitcherHelper.onLowMemory(); } public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); StitcherHelper.onConfigurationChanged(newConfig); }}Copy the code

With the above steps, you can manage the life cycle of components.

Before we use page interaction and data interaction, let’s think about the following question:

Components can’t depend on each other, so if we want to get data, we have to rely on a third-party Module for transfer. How can we design this Module to be more convenient?

Yes, we do need an extra Module for interaction relay, namely routing Module. From a developer’s perspective, this Module should have the following factors: 1. Make it easier for modules to manage their interfaces. 2. Other modules should be able to see our modifications in real time.

So before introducing interactive functions, we need to implement the configuration of the routing Module first.

Public routing Module configuration

Create a Module: sampleOuter
Modify sampleOuter’s build.gradle file and add the following code to it:

The purpose of this step is to add the Router folder of all Module projectDir to sampleOuter’s source folder, so that we can manage our own exposed interfaces and pages within the Router folder of our Module.

android {
    ...
    source// Set the router folder in all modules as the source folder of the routing Module. ArrayList<String> strings = new ArrayList<String>() File[] modules = Rootdir.listfiles (newFileFilter() {
                boolean accept(File pathname) {
                    return(pathname.isDirectory() && pathname.name ! ="gradle"&& pathname.name ! ="build"
                            && !pathname.name.startsWith("."))}})for (File f : modules) {
                strings.add(f.absolutePath + File.separator + "router"} // Don't forget to add the original source directory strings.addall (java.srcdirs) java.srcdirs = strings}}Copy the code

Once configured, click the Refresh button to create the Router folder in The Module and you’ll see something like this.

3. Configure the samplerOuter dependency in Module
    implementation 'bamboo.com ponent: stitcher: 1.0'
    implementation project(":samplerouter")
Copy the code

OK, now that the SampleOuter Module is configured, let’s move on to the page interaction.

Page interaction

You may have seen a method in the component lifecycle proxy class when we talked about component lifecycle management

// Delay the initialization lifecycle, Public void onCreateDelay(ComponentRouterRegistry routerRegistry, ActivityRouterRegistry ActivityRouterRegistry);Copy the code

ActivityRouterRegistry is the registry where we interact with pages, and we just need to inject the pages we need to expose into it to interact. Specific implementation steps:

1. Create a TaskInfopage. class in the Router folder and inherit ActivityPage
package bamboo.sample.tasksrouter; Public Class TaskInfoPage extends ActivityPage {public Final String taskId; public TaskInfoPage(Context context, String taskId) { super(context); this.taskId = taskId; }}Copy the code
2. Create a Taskspageconsumer.class
Public class TasksPageConsumer {// This method will connect to TaskInfoPage. // All TaskInfoPage page interaction requests end up in this method. public void consume(TaskInfoPage page) { Intent intent = new Intent(page.context, TaskInfoActivity.class); intent.putExtra("TaskInfoPage", page); page.context.startActivity(intent); }}Copy the code
3. Register in the Module’s ComponentApplication implementation class
public class TasksComponentApp extends ComponentApplication { public void onCreateDelay(ComponentRouterRegistry routerRegistry, ActivityRouterRegistry ActivityRouterRegistry) {/ / will TasksPageConsumer into page routing registry ActivityRouterRegistry. Regiest (new TasksPageConsumer()); }Copy the code
4. Interactive invocation
// Use stitcherHelper. start(new TaskInfoPage(this,"taskId"));
StitcherHelper.start(new TaskInfoPage(this, "taskId"),1000/*requestCode*/);
Copy the code
5. Easier to use (PageConsumer notes)

There are actually easy ways to do page injection, so why am I talking about the normal mode first? Because in case the simple approach doesn’t meet your needs, you still need to develop the conventional approach.

When we inherit ActivityPage, we can also use PageConsumer to configure activities or actions directly to connect activities <->ActivityPage.

@PageConsumer(clasz = "bamboo.sample.tasks.ui.TaskCountActivity") public class TaskListPage extends ActivityPage { public TaskListPage(Context context) { super(context); }}Copy the code

This method does not need to be registered in TaskPageConsumer, the framework will automatically search.

6. Configure special Intent parameters

If you want to Flag an Intent or interact with it via an Action or Data, you can pass it through ActivityPage’s targetIntent and temporarily close the ActivityPage connection. Stitch abandons the class parameter link in the PageConsumer annotation in this case and attempts to start the Activity directly.

    public void onActionTest(View view) {
        ActionTestPage page = new ActionTestPage(this);
        Intent targetIntent = new Intent();
        targetIntent.setAction("bamboo.sample.actiontest");
        targetIntent.addCategory(Intent.CATEGORY_DEFAULT);
        page.setTargetIntent(targetIntent);
        page.setAutoLink(false);
        StitcherHelper.start(page);
    }
Copy the code

Priority: TaskPageConsumer > unAutolink > PageConsumer

Data interaction

Data interaction between components is similar to page interaction. The ComponentRouterRegistry in the onCreateDelay method is the routing registry for data interaction that we use to register. Refer to the following steps for specific use:

1. Define ComponentOutput for the Module in the Router folder
package bamboo.sample.tasksrouter;
public interface ITaskComponent extends ComponentOutput{
    int getTaskCount();
}
Copy the code
2. Implement this interface in Module
public class TasksComponentOutput implements ITaskComponent {
    public int getTaskCount() {
        return 1000;
    }
Copy the code
3. Register in the onCreateDelay method
public class TasksComponentApp extends ComponentApplication { public void onCreateDelay(ComponentRouterRegistry routerRegistry, ActivityRouterRegistry) {// Inject TasksComponentOutput into the data routing registry RouterRegistry. Regiest (registerComponentOutput, new TasksPageConsumer ()); }}Copy the code
Use 4.
public class ComponentInput {
    public int getTaskCount() {
        ITaskComponent taskComponent = StitcherHelper.searchComponentOutput(ITaskComponent.class);
        returntaskComponent == null ? -1 : taskComponent.getTaskCount(); }}Copy the code

The specific data interaction process is as follows:

All right, stitcher’s about the usage.

Componentized script configuration see: Componentized Android: build.gradle configuration

See the Basic concept of componentization: Android Componentization Framework

For detailed examples, go to: Stitch source code and examples

Welcome to forward and use.