Load resource (layout) from another apk dynamically

半世苍凉 提交于 2019-12-21 05:22:19

问题


I managed to pull the layouts, and i add it to my viewflipper, however, there it is loaded as blank.

The code is,

Resources packageResources;
Context packageContext;
try
{   
    packageResources = pm.getResourcesForApplication(packageName);
    packageContext = this.createPackageContext(packageName,     Context.CONTEXT_INCLUDE_CODE + Context.CONTEXT_IGNORE_SECURITY);                
 }
 catch(NameNotFoundException excep)
 {
     // the package does not exist. move on to see if another exists.
 }

 Class layoutClass;
 try
 {
       // using reflection to get the layout class inside the R class of the package
       layoutClass = packageContext.getClassLoader().loadClass(packageName + ".R$layout");
 }
 catch (ClassNotFoundException excep1)
 {
     // Less chances that class won't be there.
 }

 for( Field layoutID : layoutClass.getFields() )
 {
    try
    {
        int id = layoutID.getInt(layoutClass);
        XmlResourceParser xmlResourceLayout = packageResources.getLayout(id);

        View v = new View(this, Xml.asAttributeSet(xmlResourceLayout));

        this.viewFlipper.addView(v);                 
    }
    catch (Exception excep)
   {
    continue;
   }
}

I get no errors, and i debugged and checked. The layout IDs are correct. However, in my viewFlipper its just blank. No warnings or errors i can find.


回答1:


Finally got it.... Its actually simple !!!!

Here is what i did...

  1. In the target apk, there is only resources and layouts with no application or activity code. I created a class,

    public final class ViewExtractor
    {
        private static final int NUMBER_OF_LAYOUTS = 5;
    
        public static View[] getAllViews(Context context)
        {
            View[] result = new View[ViewExtractor.NUMBER_OF_LAYOUTS];
    
            result[0] = View.inflate(context, R.layout.layout_0, null);
            result[1] = View.inflate(context, R.layout.layout_1, null);
            result[2] = View.inflate(context, R.layout.layout_2, null);
            result[3] = View.inflate(context, R.layout.layout_3, null);
            result[4] = View.inflate(context, R.layout.layout_4, null);
    
            return result;
        }
     }
    

Then in my current application, I modified my earlier code. The modification takes place once package has been verified to exist.

        // If the package exists then get the resources within it.
        // Use the method in the class to get the views.
        Class<?> viewExtractor;
        try
        {
            viewExtractor = packageContext.getClassLoader().loadClass(packageName + ".ViewExtractor");
        }
        catch (ClassNotFoundException excep)
        {
            continue;
        }

        View[] resultViews;
        try
        {
            Method m = viewExtractor.getDeclaredMethod("getAllViews", Context.class);

            resultViews= (View[])m.invoke(null, new Object[]{packageContext});

            for( View v : resultViews)
            {
                this.viewFlipper.addView(v);
            }
        }
        catch (Exception excep)
        {
            excep.printStackTrace();
        }   



回答2:


You are not inflating a layout. You are creating an empty View and adding it to your ViewFlipper.




回答3:


I am currently doing this. It only works if a know the packageName of activity or fragment from the .apk that should provide the layout hierarchy (I call this foreign context). And you need to know the name of the layout you want to inflate (e.g. R.layout.mylayout -> "mylayout")

Context c = createPackageContext(foreignPackageName,
    Context.CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNORE_SECURITY); //create foreign context
int resId = c.getResources.getIdentifier(mylayoutName,"layout",foreignPackageName); 
LayoutInflater myInflater = LayoutInflater.from(c); //Inflater for foreign context
View myLayout = myInflater.inflate(resId,null,false); //do not attach to a root view


来源:https://stackoverflow.com/questions/13218819/load-resource-layout-from-another-apk-dynamically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!