Android插件开发机制.doc_第1页
Android插件开发机制.doc_第2页
Android插件开发机制.doc_第3页
Android插件开发机制.doc_第4页
Android插件开发机制.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Android插件开发机制插件机制实质上就是由主体程序定义接口,然后由插件去实现这些接口,以达到功能模块化。Android系统是基于Linux内核的,其安全机制也继承了Linux的特性,再加上android framework没有提供插件化编程的接口,使得在android上做插件开发显得很困难。经过与同事的研究和讨论,想到了一种在android上做开发插件的方法。下面直接通过一个demo来说明。Step1:定义主程序中的接口。java view plaincopy1 public interface MyInterface 2 public void test(); 3 java view plaincopy4 public interface MyInterface 5 public void test(); 6 然后将接口打包成.jar包,提供给插件去实现。Step2:建立插件工程,实现接口。将Step1中的jar包放到lib文件夹中,并把它加入build path,但千万记得在order and export项不要勾选,即build的时候不把这个jar包build进去,因为在运行时会把这个接口与主程序的接口当做两个不同的类。如下图:实现接口的代码为:java view plaincopy7 public class PlugAppActivity extends Activity implements MyInterface 8 /* Called when the activity is first created. */ 9 Override 10 public void onCreate(Bundle savedInstanceState) 11 super.onCreate(savedInstanceState); 12 setContentView(R.layout.main); 13 14 15 Override 16 public void test() 17 System.out.println(getApplicationInfo().sourceDir); 18 19 java view plaincopy20 public class PlugAppActivity extends Activity implements MyInterface 21 /* Called when the activity is first created. */ 22 Override 23 public void onCreate(Bundle savedInstanceState) 24 super.onCreate(savedInstanceState); 25 setContentView(R.layout.main); 26 27 28 Override 29 public void test() 30 System.out.println(getApplicationInfo().sourceDir); 31 32 为什么这里要继承Activity呢?这个在下一步说明,这里的Activity可以替代成service、receiver或provider。在AndroidManifest加入这个Activity(其他组件同理)。html view plaincopy33 34 38 39 40 41 44 47 48 49 50 51 52 53 54 html view plaincopy55 56 60 61 62 63 66 69 70 71 72 73 74 75 76 这里的sharedUserId是指插件与主程序共用一个Uid,这样就消除了权限的壁垒。Android系统继承了Linux系统管理文件的方法,为每一个应用程序分配一个独立的用户ID和用户组ID,而由这个应用程序创建出来的数据文件就赋予相应的用户以及用户组读写的权限,其余用户则无权对该文件进行读写。例如,如果我们进入到Android系统日历应用程序数据目录viders.calendar下的databases文件中,会看到一个用来保存日历数据的数据库文件calendar.db,它的权限设置如下所示:html view plaincopy77 rootandroid:/data/data/viders.calendar/databases # ls -l 78 -rw-rw- app_17 app_17 33792 2011-11-07 15:50 calendar.db html view plaincopy79 rootandroid:/data/data/viders.calendar/databases # ls -l 80 -rw-rw- app_17 app_17 33792 2011-11-07 15:50 calendar.db 这里的app_17就是系统自动分配的Uid。至于给activity添加的intent-filter中的action也会在后面解释。Step3:在主程序中获取插件,并调用接口方法。html view plaincopy81 public class MainActivity extends Activity 82 83 /预定义的action 84 public static final String ACTION_PLUGIN = sig.mainApp.PLUGIN; 85 Override 86 public void onCreate(Bundle savedInstanceState) 87 super.onCreate(savedInstanceState); 88 setContentView(R.layout.main); 89 try 90 /查找符合这个action的所有activity即插件,若插件使用的是其他组件换成对应的方法 91 List infos = getPackageManager().queryIntentActivities( 92 new Intent(ACTION_PLUGIN), PackageManager.MATCH_DEFAULT_ONLY); 93 ActivityInfo pluginInfo; 94 for(ResolveInfo info:infos) 95 pluginInfo = info.activityInfo; 96 /根据插件的安装路径获得ClassLoader 97 ClassLoader cl = new PathClassLoader(pluginInfo.applicationInfo.sourceDir,getClassLoader(); 98 /获得插件类的实例 99 MyInterface plugin = (MyInterface) cl.loadClass(pluginI).newInstance(); 100 plugin.test(); 101 102 catch (Exception e) 103 e.printStackTrace(); 104 105 106 107 html view plaincopy108 public class MainActivity extends Activity 109 110 /预定义的action 111 public static final String ACTION_PLUGIN = sig.mainApp.PLUGIN; 112 Override 113 public void onCreate(Bundle savedInstanceState) 114 super.onCreate(savedInstanceState); 115 setContentView(R.layout.main); 116 try 117 /查找符合这个action的所有activity即插件,若插件使用的是其他组件换成对应的方法 118 List infos = getPackageManager().queryIntentActivities( 119 new Intent(ACTION_PLUGIN), PackageManager.MATCH_DEFAULT_ONLY); 120 ActivityInfo pluginInfo; 121 for(ResolveInfo info:infos) 122 pluginInfo = info.activityInfo; 123 /根据插件的安装路径获得ClassLoader 124 ClassLoader cl = new PathClassLoader(pluginInfo.applicationInfo.sourceDir,getClassLoader(); 125 /获得插件类的实例 126 MyInterface plugin = (MyInterface) cl.loadClass(pluginI).newInstance(); 127 plugin.test(); 128 129 catch (Exception e) 130 e.printStackTrace(); 131 132 133 134 这里通过intent来找到所有符合条件的activity,即我们之前实现的插件,通过动态的加载类来获得插件实例。主程序的AndroidManifest如下:html view plaincopy135 136 140 141 142 143 146 149 150 151 152 153 154 155 156 html view plaincopy157 158 162 163 164 165 168 171 172 173 174 175 176 177 178 插件中的sharedUserId要与这里的保持一致。上面三步描述了用android的四大组件来实现插件,但除此之外还有另一种方式。从上面的demo可以发现所有的插件与主程序的sharedUserId都是一致的,那么就可以通过检索所有安装程序的sharedUserId,只要与主程序的一致便可当做是它的插件。在上面的方法中我们获得了插件的路径以及实现接口类的类名,从而能够动态的加载这个类,而通过检索sharedUserId能够获得到路径却无法获得到类名,那么可以在插件中加入一个xml文件来说明插件中包含的实现类,通过读取这个xml来获取出类名和其他一些可能需要的描述信息,这个就会比第一种要复杂一些。总结一下,当插件的功能比较简单,选择第一种方法比较容易实现;当插件功能较多,逻辑复杂时,可以将插件再细分成模块,同时xml文件可以表现出插件的组织结构,那么第二种方法更好一些。上面所讲的两种方法都是适用于将安装的apk作为插件,实现插件开发还可以通过在sd卡中的指定目录放入插件的jar包或apk文件,原理与上述类似,只是将PathClassL

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论