Architecture and basic principles of Android dynamic loading framework DL

Source: Internet
Author: User

Architecture and basic principles of Android dynamic loading framework DL

For more information, see [Mr. Simple blog ].

I am participating in the blog star. Click here to vote for me. Thank you ~ Preface

In the past one or two years, the number of plug-ins used by Android apps has become larger and larger. In fact, it is caused by rapid expansion of business, increasing demand, and application bloated. Although the memory size of the mobile phone is constantly increasing, the installation package is too large to put psychological pressure on users. As a result, everyone will think of plug-in-based development methods to make apps into a platform, rather than an independent App. The platform can integrate various functions, and function modules can also be added in the form of plug-ins. These plug-ins do not need to be installed, but you only need to download them to a location as needed, then, it is dynamically loaded when used.

The idea is good, but it is still difficult to implement a relatively stable dynamic loading framework. Some large companies have mature dynamic loading frameworks, but they are not open-source. Fortunately, in 2014, Yu Gang, a well-known CSDN Bo Director, launched a DL Android dynamic loading framework, which is simple, open-source, and compatible, if you need plug-in development, you can try the framework. If you are interested in this open-source project, you can also contribute your own code. The address is provided at the end of the article.

I will not go into details about the basic situation and usage of DL. The author and friends involved in the development already have some good articles. For details, refer to the APK dynamic loading framework (DL) parse, DL dynamic loading framework technical documentation, Android uses dynamic loading framework DL for plug-in development. Here I will briefly introduce the basic structure and principle of DL, hoping to provide useful information to some friends who need it.


Basic Architecture

The most important and troublesome aspects of the Android dynamic loading framework are basically two. The first is how to run the apk without installation, the basic declaration cycle of the Activity can be called normally. The second is that the Activity can access resource files in the form of R. For details about how to load uninstalled apk and Android resources, refer to the following two articles: Android dynamic loading jar, apk implementation, Android source code analysis-resource loading mechanism. We provide the DL solution to these two problems in turn.

Loading an uninstalled apk is relatively simple, that is, using DexClassLoader to load the apk file to the virtual machine. For details, refer to the article above. Here we mainly talk about the implementation of calling the Activity lifecycle function. In DL, there are two Proxy classes: DLProxyActivity and DLProxyFragmentActivity. These two types are inherited from Activity and FragmentActivity. They are integrated from DLBasePluginActivity and DLBasePluginFragmentActivity by Proxy respectively, DLBasePluginActivity and DLBasePluginFragmentActivity inherit from Activity and FragmentActivity respectively. I will go! Is it a bit messy at this time? Let me hear it over again ~

According to the DL development specifications, the Activity of your plug-in needs to inherit from the DLBasePluginActivity or DLBasePluginFragmentActivity. These two classes encapsulate some basic calling logic. Here, we will ignore this for the time being, focusing on DLProxyActivity and DLProxyFragmentActivity. The DL mechanism is like this. In DL, only DLProxyActivity and DLProxyFragmentActivity can be started through Intent. These two activities are registered in the host apk, therefore, it can be started directly through Intent. In fact, the two proxies are only a shell, and they will call the corresponding lifecycle function of the plug-in Activity in their own lifecycle functions. This introduces a key class, DLProxyImpl, which is responsible for parsing the resources of the plug-in apk, ClassLoader, and loading the plug-in Activity through reflection, after the DLProxyImpl loads the plug-in Activity, it will call the attach method of the Proxy Activity to pass the plug-in Activity instance to the Proxy Activity, so that the Proxy Activity gets an instance of the plug-in Activity, then, you can call the function corresponding to the plug-in Activity in your own declared periodic function.

LaunchTargetActivity function of DLProxyImpl:

@ TargetApi (Build. VERSION_CODES.ICE_CREAM_SANDWICH) protected void launchTargetActivity () {try {// mClass is the Class name of the target plug-in Activity <?> LocalClass = getClassLoader (). loadClass (mClass); Constructor <?> LocalConstructor = localClass. getConstructor (new Class [] {}); // build the Agent Activity Object instance = localConstructor through reflection. newInstance (new Object [] {}); mPluginActivity = (DLPlugin) instance; // inject the agent Activity to the Proxy Activity (DLAttachable) mProxyActivity ). attach (mPluginActivity, mPluginManager); // The plug-in activity also obtains the reference mPluginActivity of Proxy. attach (mProxyActivity, mPluginPackage); Bundle bundle = new Bundle (); bundle. putInt (DLConstants. FROM, DLConstants. FROM_EXTERNAL); // call the onCreate function of the plug-in Activity to start the plug-in Activity mPluginActivity. onCreate (bundle);} catch (Exception e) {e. printStackTrace ();}}

When the host loads the plug-in apk, it will parse the relevant information of the apk, such as its default started Activity. The above form will run the apk, in the plug-in apk, you need to pass the package name and class name of the target activity to the DL framework through the DLIntent class. The DL will be parsed internally and the corresponding loading logic.


Core DLProxyActivity code: 

Public class DLProxyActivity extends Activity implements DLAttachable {// plug-in Activity protected DLPlugin mRemoteActivity; // DLProxyImpl load private DLProxyImpl impl = new DLProxyImpl (this) such as plug-in Activity and resource ); @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); // call the onCreate of DLProxyImpl during Proxy onCreate to load the Activity impl plug-in. onCreate (getIntent ();} // loads the actiins Activ Ity and then pass the plug-in Activity to the Proxy Activity @ Override public void attach (DLPlugin remoteActivity, DLPluginManager pluginManager) {mRemoteActivity = remoteActivity;} // obtain the resource. DLProxyImpl loads the resources of the plug-in apk, here, the agent resource operation is performed, so that the agent Activity can access the resource file through R. @ Override public Resources getResources () {return impl. getResources () = null? Super. getResources (): impl. getResources ();} /********************** the following are the life cycle functions of the agent plug-in Activity ******* * **************/@ Override protected void onStart () {mRemoteActivity. onStart (); super. onStart () ;}@ Override protected void onRestart () {mRemoteActivity. onRestart (); super. onRestart () ;}@ Override protected void onResume () {mRemoteActivity. onResume (); super. onResume () ;}@ Override protected void onPause () {mRemoteActivity. onPause (); super. onPause () ;}@ Override protected void onStop () {mRemoteActivity. onStop (); super. onStop () ;}@ Override protected void onDestroy () {mRemoteActivity. onDestroy (); super. onDestroy ();} // Code omitted}

Next let's look at another key point, that is, the resource loading of the plug-in apk. For details about the resource Loading Mechanism of apk, refer to the above article. Let's look at the Code directly.

Private DexClassLoader createDexClassLoader (String dexPath) {File dexOutputDir = mContext. getDir ("dex", Context. MODE_PRIVATE); dexOutputPath = dexOutputDir. getAbsolutePath (); // create ClassLoader DexClassLoader loader = new DexClassLoader (dexPath, dexOutputPath, mNativeLibDir, mContext. getClassLoader (); return loader;} // construct AssetManager Based on the path of the plug-in apk, add the path of its resource to AssetManager, and then construct a Resources object through AssetManager, this object is the resource object of the plug-in apk. when accessing resources inside the plug-in apk, the private AssetManager createAssetManager (String dexPath) {try {AssetManager assetManager = AssetManager. class. newInstance (); Method addAssetPath = assetManager. getClass (). getMethod ("addAssetPath", String. class); addAssetPath. invoke (assetManager, dexPath); return assetManager;} catch (Exception e) {e. printStackTrace (); return null ;}} private Resources createResources (AssetManager assetManager) {Resources superRes = mContext. getResources (); Resources resources = new Resources (assetManager, superRes. getDisplayMetrics (), superRes. getConfiguration (); return resources ;}

In this way, the lifecycle of the plug-in Activity is handed over to the Proxy Activity Proxy, while the startup and resource access of the plug-in Activity are handed over to the DLProxyImpl Proxy. In this way, the plug-in Activity is started through two proxies, and the resource access problem is also solved.

Finally, we can see the basic structure of DL through a figure.

DLPluginManager loads and manages plug-in packages. DLIntent is the information carrier for redirection between plug-ins. Base Plugin Activity is the Base class of the plug-in Activity, which encapsulates proxy operations. The Life Cycle Function of the Proxy Activity agent Activity is also the shell of the agent Activity. DLProxy is responsible for loading plug-in Activity and resource operations. As a result, the entire dynamic loading framework is running. If you are interested in more details, go to the source code.


Later features

1. Support for service, static broadcast, and ContentProvider

Bug

1. Support for transparent themes of plug-ins

2. Complete activity api Rewriting


Finally, the github address of the DL framework is provided. We hope more people will participate in the development of the DL framework.


I am participating in the blog star. Click here to vote for me. Thank you ~


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.