Android Small plugin Framework Source analysis

Source: Internet
Author: User

Android Small plugin framework Source analysis Directory

Overview
Small how to use
Plug-in loading process
Areas to be improved

I. Overview

Small is a very concise written plug-in framework, engineering source location: Https://github.com/wequick/Small
Plug-in solution, in the final analysis to solve the core problem only three:

  • 1.1 Loading of plug-in classes

    • The solution to this problem is similar to that of other plug-in frameworks. The Android class is loaded by Dexclassloader, which dynamically loads the plug-in package through reflection. The small Gradle plug-in generates a. So package that, when initialized, generates a. zip file through the. so file, and then generates a DEX element from the. zip file, which is added to the dexpathlist of the host ClassLoader.
  • 1.2 plug-in resource handling

    • Here are two common ideas for plug-in framework solutions: a Is that the plug-in does not share resource access, the way is that each plug-in generates a Assertmanager to access its own resources, so there is no resource ID conflict, and the other is that everyone shares a assetmanager, so that the plug-in resources are shared, can access each other, However, the issue of resource ID conflicts should be resolved. Small adopts the latter, which solves the problem of resource ID conflict by modifying the product of AAPT, which can reduce the size of the plug-in package because of the access of shared resources, so as to achieve minimal or no resource redundancy;
  • 1.3 activity registration and life cycle issues

    * Most plug-in framework solutions use pre-registered activity-occupying pits in the host project and then pass the lifecycle callback back to the plugin through the pit activity Activi Ty's way. Here small processing of comparative features, by replacing the minstrumentation in the Activitythread, in the newactivty implementation of the instrumentation instantiation of the plug-in activity, The problem of lifecycle callbacks can be completely resolved with minor changes.

The main function modules of small are:
Gradle-small plugin: A gradle custom plugin in small for packaging components;
Small library: To provide users with the Android library, mainly to provide plug-ins loading, parsing and other functions;

Second, the use of small

2.1 Engineering Nomenclature
First small The project name as follows:

  • App:host Engineering
  • App.*:app plug-in engineering;
  • Lib.*:library plug-in engineering;
  • Web.*:web plug-in engineering;
  • Other: other assert works;

2.2 Plugin Introduction
In the host project of the Rootproject Build.gradle need to introduce small plug-in;
After introducing the small plug-in, the default helps all of your projects to introduce a library-dependent small, we use the various interfaces provided by small to achieve plug-in functions, such as loading plug-ins, open a plugin UI interface, create a plugin to provide fragment objects, etc.;

2.3 Plugin Declaration
As the host program, the most important thing to do is plug-in management, plug-in jump URI declaration:
The plug-in declaration is declared in the Assert/bundle.json of the host program in the following format:

{"Version":"1.0.0","Bundles": [    {"uri":"Lib.utils","Pkg":"Net.wequick.example.small.lib.utils"},    {"uri":"Lib.style","Pkg":"Com.example.mysmall.lib.style"},    {"uri":"Main","Pkg":"Net.wequick.example.small.app.main"},    {"uri":"Home","Pkg":"Net.wequick.example.small.app.home","Rules"{"Page1",". MyPage1 ","Page2","Net.wequick.example.small.app.home.MyPage2"}    },    {"uri":"Message","Pkg":"Net.wequick.example.small.app.message"},    {"uri":"Find","Pkg":"Net.wequick.example.small.app.find"},    {"uri":"Mine","Pkg":"Net.wequick.example.small.app.mine"},    {"uri":"Detail","Pkg":"Net.wequick.example.small.app.detail"},    {"uri":"About","Pkg":"Net.wequick.example.small.web.about"}  ]}

Each element in the bundles is a plug-in declaration;

    {      "uri""home",      "pkg""net.wequick.example.small.app.home",      "rules"{          "page1",".MyPage1",          "page2","net.wequick.example.small.app.home.MyPage2"       }    }

In the application of small framework, the interface of jump plug-in is specified by URI, that is, a URI only corresponds to a plugin;
PKG is the package name of the plugin;
Rules: If the plugin provides multiple interfaces for others to use, we need to differentiate them by rules;

As an example:

Small.openUri("home"

The above line of statement is to open a plugin interface, home corresponding to the above URI field, we go through home, find the corresponding plug-in, and then it will open the plugin in Androidmanifest.xml declared the first activity.

If you want to adjust the other acitivity that are declared in the plugin, you need to use the rules, first of all in the Bundles.json declaration you want to jump acitivity, as above, if you want to call the home plugin interface activity MyPage1,
You only need to write the following statement:

Small.openUri("home/page1"

This is the net.wequick.example.small.app.home.MyPage1 kind of activity that this class corresponds to.

You can also pass the QueryParameter when you call the plugin:

Small.openUri("home?from=main", context);在调起的插件工程获取参数:Uri uri = Small.getUri(this);ifnull) {    from = uri.getQueryParameter("from");    // Do stuff by `from‘}

2.4 Plugin Load Management
In host we usually do two things:
Initializes the baseuri of the plugin;
This is generally done in application's OnCreate: Small.setbaseuri ("http://m.wequick.net/demo/");

In addition to loading all plugins (to be optimized, loading all plugins at once is too time consuming, we should just load the necessary plugins and then slowly load the other plugins)
Small.setup (This, new Net.wequick.small.Small.OnCompleteListener () {
@Override
public void OnComplete () {
Mcontentview.postdelayed (New Runnable () {
@Override
public void Run () {
Small.openuri ("main", launchactivity.this);
Finish ();
}
}, 2000);
}
});
Setup provides plug-in loading completed callback, generally we wait for the plug-in after loading to start the interface display through Openuri;

2.5 Common operations

  • Open the interface:
    Small.openuri ("main", context);

  • Create the fragment provided by the plugin:
    Fragment Fragment = Small.createobject ("Fragment-v4", "Home", context);
    If the class name is not specified by rules, the default class name is the package name. Mainfragment
    If a class name is specified, the same as the previous rule.
    The first parameter of CreateObject currently supports only "fragment" or "fragment-v4"

  • Get the intent of a plugin interface
    Sometimes we do not directly open the interface, such as notification bar notification, we need to set a pendingintent, then this time need is a intent
    This is done by getting:

Small.getIntentOfUri("main",context)
  • Gets the query information at the time of the call:
//调用Small.openUri("home?from=main", context);//参数获取;Uri uri = Small.getUri(this);ifnull) {    from = uri.getQueryParameter("from");    // Do stuff by `from‘}
Third, the plug-in loading process

The core analogies of small are few and consist of three main categories:

  • Small: interface class, provide all kinds of interface that the user can use;
  • Bundle: Represents the plugin, saves all the information of the plugin, controls the load flow of the plug-in, and the lauch process; it calls all kinds of bundlelauncher to work;
  • Bundlelauncher: There are many subcategories, such as. App. ,. lib. Class of plug-ins, corresponding to the apkbundlelauncher,.web.* corresponds to is Webbundlelauncher, other corresponding is Activitylauncher

Plug-in-related operations are mainly load and lauch:

When the application starts to prepare the plug-in environment, is the load operation, mainly to parse the plug-in information and cache, and add the plugin Dex and resources to the host;load to complete the other plug-in operations

  • In the load plug-in, the general two-step:
    Preloadbundle, general judge whether the plug-in can be loaded, return false does not need to load; Here we generally check the validity of the plugin
    Loadbundle (Bundle bundle): Real load parsing plug-in information and deposited into the bundle object;
    Lauch refers to the general point of loading plug-in interface, the typical is to call Small.openuri to open the plugin interface;
  • Lauch plug-in time is also divided into two steps:
    Prelaunchbundle (Bundle bundle): To prepare the bundle of some necessary information: generally generate bundles of intent information, mainly to start the generation of the class name; (see Apkbundlelauncher)
    Launchbundle (Bundle bundle, Context context): Determine whether the plug-in can be loaded, can be loaded to start acitivity;

The 3.1 load process

Small. Setup-Bundle. Setuplaunchers(Call the setup of each bundlelauncher, where the Apkbundlelauncher setup replaces the Activitythread minstrumentation member variable)-->bundle. Loadlaunchablebundles(Parsing bundles. JSON, and load Bundle)-->bundle. Loadmanifest(Read the bundle. JSON)--Bundle. Loadbundles(Open asynchronous thread to load) the process inside the asynchronous thread:-->bundle. Prepareforlaunch--traverse Activitylauncher,webbundlelauncher,apkbundlelauncher, call their bundlelauncher. ResolvebundleMethods to find the appropriate Bundlelauncher parsing plug-in package;-->bundlelauncher. Preloadbundle(mainly to determine whether it can be loaded)-->bundlelauncher. LoadbundleIn addition to the three Bundlelauncher classes (Activitylauncher,webbundlelauncher,apkbundlelauncher) that are directly used, there are two intermediate classes, Sobundlelauncher and Assetbundlelauncher, where Sobundlelauncher mainly provides a preloadbundle function implementation, which implements the1According to the supported type and the package name comparison, quickly determine whether this bundlelauncher can resolve this plugin;2Check whether the plug-in signature is legitimate to determine whether to parse the secondary plug-in; Assetbundlelauncher inherited from Sobundlelauncher, dried webbundlelauncher to do loadbundle most of the work.

3.2 Start Interface Flow

Small. OpenUri-Bundle. Getlaunchablebundle-->bundle. Matchesrule(Match the appropriate bundle by URI)--bundle. Launchfrom-->apkbundlelauncher. Launchbundle-->apkbundlelauncher. Prelaunchbundle-->bundlelauncher. Launchbundle->activity. Startactivityforresult-->apkbundlelauncher. Instrumentationwrapper. Execstartactivity--"Apkbundlelauncher. Instrumentationwrapper. Wrapintent(Save the plug-in activity class in the intent category, and replace the class inside the intent component with the placeholder activity declared in the host to pass the Activitymanager check)--" Apkbundlelauncher. Instrumentationwrapper. Newactivity(Remove the plug-in activity class from the intent and instantiate the return for the receive lifecycle callback)--"Apkbundlelauncher. Instrumentationwrapper. Callactivityoncreate(Add plugin apk to Assertmanager, to read plugin resources, apply plugin theme)
3.3 Plug-in packaging process

Todo

Iv. points that need improvement
  • Load plug-in priority
    The current load plug-in is the time to load all the plug-ins are ready, should be loaded only the necessary plug-in can be ready to send a callback to let the main process continue to run, the other plug-ins continue to load in the background;

  • Optimized for in-package activity information via Packagemanager
    After practical testing, it takes a lot of time to get the activity information through Packagemanager (700MS), but the loading plug-in also needs the activity information in the plug-in package, which is to be put into the file by extracting the corresponding information in the package, the loading plugin only needs to read the file parsing;

  • Plug-in legitimacy check
    The current plug-in legitimacy is achieved through the signature comparison of the package, but also the packagemanager of the call, the efficiency is lower.

  • string resource more than 128 compile error problem
    At present, when the plug-in processing resources are found, if there is a string resource in the project Strings.xml more than 128 characters will be error, there is also a string style will be problematic, should be the author of the Resource Index table in the Stringpoll structure understanding error.

The original team of embedded Penguin Circle consists of senior engineers such as Ali, Meizu, nvidia, godson, Ju Li, and so on. Hundreds of original, two articles a week, sharing embedded, Linux, Internet of Things, GPU, Android, autonomous driving and other technologies. Welcome to sweep code attention to the public number: embedded Penguin ring, real-time push the original article!

Android Small plugin Framework Source analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.