Android app development enhancement series (5) -- Android dynamic loading (bottom) -- loading classes and resources in installed APK

Source: Internet
Author: User

Preface

Android dynamic loading (bottom) -- load the classes and resources in the installed APK.

 

StatementWelcome to repost, but please keep the original source of the article :) blog Park: http://www.cnblogs.com farmer UNCLE: http://over140.cnblogs.com

Android Chinese Wiki: http://wikidroid.sinaapp.com

 

Body

I. Objectives

Note that the called APK has been installed in the Android system.

Previous Article: Android app development enhancement series (4) -- Android dynamic loading (on) -- loading classes in APK Not Installed

Call another installed APK string, color value, image, layout file resource, and Activity from the current APK.

 

II. Implementation

2.1 called projects

Basically, the previous project is followed, and the called strings and images are added. Therefore, the project will not be pasted here, and a download link will be provided later.

 

2.2 call the project code

Public class TestAActivity extends Activity {

/** TestB package name */
Private static final String PACKAGE_TEST_ B = "com. nmbb. B ";

@ Override
Public void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. main );
Try {
Final Context ctxTestB = getTestBContext ();
Resources res = ctxTestB. getResources ();
// Obtain the string
String hello = res. getString (getId (res, "string", "hello "));
(TextView) findViewById (R. id. testb_string). setText (hello );

// Obtain the image Drawable
Drawable drawable = res
. GetDrawable (getId (res, "drawable", "testb "));
(ImageView) findViewById (R. id. testb_drawable ))
. SetImageDrawable (drawable );

// Obtain the color value
Int color = res. getColor (getId (res, "color", "white "));
(TextView) findViewById (R. id. testb_color ))
. SetBackgroundColor (color );

// Obtain the layout File
View view = getView (ctxTestB, getId (res, "layout", "main "));
LinearLayout layout = (LinearLayout) findViewById (R. id. testb_layout );
Layout. addView (view );

// Start TestB Activity
FindViewById (R. id. testb_activity). setOnClickListener (
New OnClickListener (){
@ Override
Public void onClick (View v ){
Try {
@ SuppressWarnings ("rawtypes ")
Class cls = ctxTestB. getClassLoader ()
. LoadClass ("com. nmbb. TestBActivity ");
StartActivity (new Intent (ctxTestB, cls ));
} Catch (ClassNotFoundException e ){
E. printStackTrace ();
}
}
});
} Catch (NameNotFoundException e ){
E. printStackTrace ();
}
}

/**
* Obtain the resource ID.
*
* @ Param testb
* @ Param resName
* @ Param resType
* Layout, drawable, string
* @ Return
*/
Private int getId (Resources testb, String resType, String resName ){
Return testb. getIdentifier (resName, resType, PACKAGE_TEST_ B );
}

/**
* Retrieving views
*
* @ Param ctx
* @ Param id
* @ Return
*/
Public View getView (Context ctx, int id ){
Return (LayoutInflater) ctx
. GetSystemService (Context. LAYOUT_INFLATER_SERVICE). inflate (id,
Null );
}

/**
* Obtain the Context of TestB.
*
* @ Return
* @ Throws NameNotFoundException
*/
Private Context getTestBContext () throws NameNotFoundException {
Return createPackageContext (PACKAGE_TEST_ B,
Context. CONTEXT_IGNORE_SECURITY | Context. CONTEXT_INCLUDE_CODE );

}

Code Description:

Basic principle: Get the Context of the called application through package, and get the corresponding resources and classes through Context.

Note:

A ). many articles on the Internet use the R. id to call the resources of the called Project. This is incorrect. Even if no error is reported, it is coincidentally because R is automatically generated and the IDs of the two applications cannot be matched, therefore, you need to search by getIdentifier.

B). Context. CONTEXT_INCLUDE_CODE generally does not need to be added. If layout contains a custom control, it must be added. Note that this custom control cannot be obtained by force conversion in the current project because it is in two ClassLoader and cannot be converted.

C). You do not need to upload userid to obtain these resources.

 

Iii. Summary

Compared with the previous article, it is more convenient to obtain resources, but there are also some restrictions:

3.1 The called apk must have been installed to reduce the user experience.

3.2 style cannot be set dynamically, even if it can be obtained.

3.3 According to the current research results, if a custom control is used for the called Project, it will be subject to a large limit and cannot be forcibly converted for use (as mentioned earlier ).

3.4 because a project is mixed with two contexts, it is easy to cause confusion and resource retrieval is also troublesome. Here we will share with you the method of hiding two apk IDs in batches. You can obtain the R classes of the two apk through reflection, get each id and value at a time, and match each id and value by name one by one, in this way, you do not need to manually input strings.

@ SuppressWarnings ("rawtypes ")
Private static HashMap <String, Integer> getR (Class cls) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
HashMap <String, Integer> result = new HashMap <String, Integer> ();
For (Class r: cls. getClasses ()){
If (! R. getName (). endsWith ("styleable ")){
Object owner = r. newInstance ();
For (Field field: r. getFields ()){
Result. put (field. getName (), field. getInt (owner ));
}
}
}
Return result;

}

 

4. Download

Test2012-4-19.zip

 

V. Articles

Android dynamic loading technology

 

End

If it is a large area of skin replacement, it is still complicated, and this method is not very convenient, which is why there are very few skin replacements on the market, there is also a very simple skin replacement. Another solution that I have come up with over the past few days has not been put into practice. If it works, I will share it with 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.