Implement Android dynamic load apk (Fragment or activity implementation)

Source: Internet
Author: User

Respect for the original: http://blog.csdn.net/yuanzeyao/article/details/38565345

Recently due to the project is too large, resulting in the compilation pass (Android to an application of the number of methods seems to be limited), so has been wondering whether some of the modules can not install the APK, dynamic loading, through the Internet to find information and the help of netizens, finally realize the APK dynamic loading, There are a lot of articles on the web about apk dynamic loading, but I think it is the Daniel who writes very well, and I basically use his scheme, and then add his own elements. This Daniel was implemented through activity, I modified it to be dynamically loaded through fragment, and I personally think it is simpler to use fragmnet because the fragment implementation does not need to consider the fragment life cycle.

Article Address: http://blog.csdn.net/singwhatiwanna/article/details/22597587
http://blog.csdn.net/singwhatiwanna/article/details/23387079
Be sure to read these two articles and then read my article, because I borrowed the idea of this article.


The first problem is that because any program in Java has to be run, a class must be added to memory through the ClassLoader, and when we add activity to memory through a classloader, the activity is an ordinary class that has no concept of life cycle, In Android, the life cycle of activity is controlled by Activitymanager, and if we load the activity in a dynamically loaded way, then Activitymanager doesn't know that the activity exists. , so we have to deal with the activity life cycle, as for the second problem, in Android, we get the resources are obtained through the context, and dynamically loaded apk is not the context, so we can not be the same as before to take. The previous two articles recommended methods have been able to solve the above two problems, so that the apk dynamic loading.
Let me first describe the idea of dynamic loading in Daniel's blog:
Create a proxyactivity, by name know, it is a proxy activity, we call any activity is implemented by calling Proxyactivity, I just need to pass in the path of dynamically loaded APK and the class name that needs to be loaded dynamically. For example, after an activity is loaded, all of the activity's life cycle functions and functions, such as Onactivityresult, are read through the reflection mechanism and stored in a list. The oncreate of dynamically loaded activity is called by reflection in the oncreate of Proxyactivity, and because proxyactivity is a normal activity, its life cycle is normal, So it is OK to invoke the life cycle function of dynamic load activity in the life cycle function of proxyactivity, so that dynamic loading activity has a life cycle. At the same time altogether is the agent, then the agent thoroughly, simply put the dynamic load of all the logic in the activity into the proxyactivity. Then this requires the loaded activity to have a proxyactivity reference, which allows all dynamically loaded activity to inherit a baseactivity, which has a SetProxy method, Used to set proxyactivity. So not any apk, can be dynamically loaded, and generally only dynamically loaded their own written apk, dynamic loading other people's apk is not very realistic.
Look at the above thinking, is not a little borrow the belly of the feeling, in fact, the dynamic load of the activity of the logic transferred to the proxyactivity

The method of solving the problem of resource access is to build the proxyactivity two functions of the overloaded man
Public abstract Assetmanager getassets ();
Public abstract Resources getresources ();
As to why we can solve the problem of resources, I still recommend a few articles to learn about it:
My other article: http://blog.csdn.net/yuanzeyao/article/details/12955459
An article explaining the Android resource loading mechanism: http://blog.csdn.net/singwhatiwanna/article/details/24532419

OK, the above is the dynamic loading apk by activity, see below how I fragment to achieve dynamic loading, if familiar with fragment students should know, fragment is equivalent to a life cycle view, Its life cycle is managed by the activity's lifecycle, even though we add a fragment to memory through the ClassLoader, which is no different from the fragment we used before, as long as we add this fragment to Proxyactivity, Proxyactivity will automatically manage the life cycle of this fragment. So we don't have to worry about the life cycle of fragment, let's take a look at the code implementation:

1, Basefragment.java

public class Basefragment extends Fragment implements iconstant{  private static final String TAG = "Basefragment"; 
   
    protected String Mdexpath;  @Override public  void OnCreate (Bundle savedinstancestate)  {    super.oncreate (savedinstancestate);    Bundle bundle=this.getarguments ();//dynamic load apk path    mdexpath=bundle.getstring (Dex_path);  }    Start another fragment  protected void Replacefragmentbyproxy (String name)  {    if (mdexpath==null) in fragment      return;    Proxy_view_action is proxyactivity ACTION    Intent intent=new Intent (proxy_view_action);//Pass the APK path    Intent.putextra (Dex_path, Mdexpath);//is the start fragment or start fragment, here is Fragment    Intent.putextra (start_type, type_fragment);//FRAGMENT class name    Intent.putextra (class_name, name) that needs to be loaded;    This.startactivity (intent);      }}
   

All fragment that need to be loaded dynamically need to inherit this basefragment, and each time you start a fragment, you only need to pass the APK path.
Here is a myfragment I wrote, used to load the network pictures using Bitmapfun, here is just load and display pictures, no consideration of other, if you want to learn more about the use of bitmapfun, please see my other article:
http://blog.csdn.net/yuanzeyao/article/details/38355719

public class Myfragment extends basefragment{private static final String TAG = "Myfragment";  private static final String IMAGE_CACHE_DIR = "thumbs";  Private Imagefetcher Mimagefetcher;  Private GridView Mgridview;  Private context context;    Private Button btn;    @Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);    Imagecacheparams cacheparams = new Imagecacheparams (getactivity (), image_cache_dir); Cacheparams.setmemcachesizepercent (0.25f); Set memory Cache to 25% of app memory//The Imagefetcher takes care of loading images into our ImageView children a    synchronously mimagefetcher = new Imagefetcher (Getactivity (), 200);    Mimagefetcher.setloadingimage (R.drawable.empty_photo);  Mimagefetcher.addimagecache (Getactivity (). Getsupportfragmentmanager (), cacheparams); } @Override Public View oncreateview (layoutinflater inflater, ViewGroup container, Bundle savedinstancestate) {//here in fact R.layout.fragment Resour can be used directlyCES mresources=this.getactivity (). Getresources ();  Return Inflater.inflate (Mresources.getidentifier ("Fragment", "Layout", "Com.dl.client"), Container,false); } @Override public void onviewcreated (view view, Bundle savedinstancestate) {super.onviewcreated (view, Savedinsta    Ncestate);    mgridview= (GridView) View.findviewbyid (R.id.gridview);    Btn= (Button) View.findviewbyid (r.id.btn_fragment); Btn.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View arg0) {//in F      Ragment dynamic loading of another fragment Replacefragmentbyproxy ("Com.dl.client.TempFragment");    }    });    Context=this.getactivity (); Mgridview.setadapter (New Baseadapter () {@Override public View getView (int position, view Contentview,        ViewGroup arg2) {ImageView mimg;        if (contentview==null) {contentview=layoutinflater.from (context). Inflate (R.layout.item,null); } mimg= (ImageView) Contentview.findvieWbyid (R.id.img_11);        Mimg.setimageresource (R.drawable.empty_photo);        Mimagefetcher.loadimage (Images.imagethumburls[position], mimg);      return contentview;      } @Override public long getitemid (int arg0) {return 0;      } @Override public Object getItem (int arg0) {return images.imagethumburls[arg0];      } @Override public int getcount () {return Images.imageThumbUrls.length;  }    }); }}

Here's how this app works:


The last thing to note is that the dynamically loaded APK cannot contain the same jar package as the host app, or it will error ...

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.