android编程时布局文件,图片资源等都是放在同一个文件夹下,这样照成一个问题就是我们想重用UI布局文件和图片时就还需要其分离这些资料,相信大部分android程序员都遇到过这样的问题,其痛苦程度不亚于世纪末日赶不上诺亚方舟。
今天我用apkplug框架实现将不同的资源放在不同的插件apk包中,然后通过插件间类查找的方式实现插件机布局文件共享。不说废话了!
一 新建一个插件myBundle1由它提供布局文件供myBundle插件调用
结合上一篇文章本章我再建一个插件工程myBundle1新增实现3个java类分别是
BundleContextFactory.java 这个类的唯一功能就是存储插件启动时获取的BundleContext,该类中有我们需要的android.content.Context
public class BundleContextFactory implements BundleInstance{ private static BundleContextFactory _instance=null; private BundleContext mcontext = null; synchronized public static BundleContextFactory getInstance(){ if(_instance==null){ _instance=new BundleContextFactory(); } return _instance; } private BundleContextFactory(){ } public BundleContext getBundleContext() { // TODO Auto-generated method stub return this.mcontext; } public void setBundleContext(BundleContext arg0) { // TODO Auto-generated method stub this.mcontext = arg0; } }
TBSurfaceView.java 一个SurfaceView 用于演示View
myLayout.java 继承RelativeLayout,通过它插件myBundle就可以获取插件myBundle1的布局文件了
public class myLayout extends RelativeLayout{ public myLayout(Context context, AttributeSet attrs) { super(context, attrs); //获取插件启动时得到的Context Context m=BundleContextFactory.getInstance().getBundleContext().getBundleContext(); LayoutInflater mInflater=LayoutInflater.from(context); mInflater = mInflater.cloneInContext(m); mInflater.inflate(R.layout.main11, this, true); } }
布局文件 main11.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:id="@+id/tt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我是插件myBundle1" /> <com.example.mybundle1.TBSurfaceView android:layout_below="@+id/tt" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </RelativeLayout>
最后插件myBundle1文件目录为
二 修改插件myBundle布局文件activity_main.xml添加View com.example.mybundle1.myLayout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:id="@+id/tt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="hello_world 我是myBundle的Activity" /> <com.example.mybundle1.myLayout android:layout_below="@+id/tt" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/myLayout1"/> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:layout_alignBottom="@+id/myLayout1" android:layout_centerHorizontal="true"/> </RelativeLayout>三 将两个编译好的插件添加到主应用的assets文件夹中并在PropertyInstance接口的public String[] AutoStart()中添加两个插件自动启动
public String[] AutoStart() { File f0=null,f1=null; try { InputStream in=context.getAssets().open("myBundle.apk"); f0=new File(context.getFilesDir(),"myBundle.apk"); if(!f0.exists()) copy(in, f0); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { InputStream in=context.getAssets().open("myBundle1.apk"); f1=new File(context.getFilesDir(),"myBundle1.apk"); if(!f1.exists()) copy(in, f1); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return new String[]{"file:"+f0.getAbsolutePath(),"file:"+f1.getAbsolutePath()}; }
最后启动应用查看效果如图
最后给出源码
注意:1.以上需要注意的问题的是需要引出的类都应该在plugin.xml文件中添加Export-Package="com.example.mybundle1" 这样插件间才能找的到(下一章会实现另一种方式插件间交换类)
2.apkplug官网为:www.apkplug.com