android基于插件式开发

之前没有听过app插件式开发今天就做一下学习的笔记。这里的插件式开发通俗的讲就是把一个很大的app分成n多个比较小的app,其中有一个app是主app。网上查了一下采用了这种开发模式的有支付宝客户端、QQ换肤其他的就不得而知了有人说微信也是基于插件的但是微信在更新的时候会下载全部的应用程序把旧的完全覆盖所以猜想应该目前不是吧。

基于插件的开发列举两个比较突出的优点:

1、应用程序非常容易扩招,比如有一个新的领域要加到旧的应用程序中来只需把这个新的领域做为一个插件,只开发这个小的app就可以了旧的应用程序可能会原分不动,就连编译打包都不需要。

2、下载更新特别省流量,假如一个应用程序有10M把它分成两个的话可能每次更新只需要花费5M或者更少的流量就可以更新完。对于我每月只有30M的流量去更新一个10M大的应用却是有些心疼,只要用户不能及时更新我们的应用那么应用中赚钱的项目就不能及时传达到客户的手中,客户是上帝啊我们赚客户钱的同事还要想着为客户节省哈哈哈。

有优点的东西也是有缺点的这是必然,就和人无完人一样,记得有个软件工程的老师给我们说过“追求完美本来就是一种性格缺陷”话的意思是说在做软件方面没有近乎完美。基于插件开发当然不是插件越多越好能掌控好内聚和耦合度就更好了。插件增加了主应用程序中的逻辑难过。

这次学习需要了解以下概念:

1、  进程:

当时学习操作系统的时候就书上是这么解释的,进程就是程序的一次执行过程,进程是操作系统分配资源的基本单位。当然进程还有很多属性这里就不多说了。在android中当某一个组件第一次运行的时候android就启动了一个进程,默认时所有的组件运行在这一个进程中,当然也可以自己指定运行在哪一个进程中。组件运行的进程由manifest file控制。组件的节点 <activity>、<service>、 <receiver>和 <provider> 都包含一个 process 属性。这个属性可以设置组件运行的进程:可以配置组件在一个独立进程运行,或者多个组件在同一个进程运行。甚至可以多个程序在一个进程中运行,如果这些程序共享一个User
ID并给定同样的权限。<application> 节点也包含 process 属性,用来设置程序中所有组件的默认进程。

所有的组件在此进程的主线程中实例化,系统对这些组件的调用从主线程中分离。并非每个对象都会从主线程中分离。一般来说,响应例如View.onKeyDown()用户操作的方法和通知的方法也在主线程中运行。这就表示,组件被系统调用的时候不应该长时间运行或者阻塞操作(如网络操作或者计算大量数据),因为这样会阻塞进程中的其他组件。可以把这类操作从主线程中分离。

当更加常用的进程无法获取足够内存,Android可能会关闭不常用的进程。下次启动程序的时候会重新启动进程。

当决定哪个进程需要被关闭的时候, Android会考虑哪个对用户更加有用。如Android会倾向于关闭一个长期不显示在界面的进程来支持一个经常显示在界面的进程。是否关闭一个进程决定于组件在进程中的状态。

2、  线程

当时学习的时候书上是这么说的线程是进程的基本单元,一个进程可以有多个线程,每个进程至少有一个主线程。在android中即使为组件分配了不同的进程,有时候也需要再分配线程。比如用户界面需要很快对用户进行响应,因此某些费时的操作,如网络连接、下载或者非常占用服务器时间的操作应该放到其他线程。

3、  进程间通信

我们知道,Android系统是基于Linux内核的,在Linux中进程间通信有好多种(管道、信号、消息队列、共享内存、信号量、套接字)。很不幸啊Android系统没有采用上述提到的各种进程间通信机制。关于进程间通信可以看看http://blog.csdn.net/luoshengyang/article/details/6618363博客。

以上说了一大堆就想说明插件app和主程序要解决通信的问题,这个看起来很难但是很幸运android可以把好几个app合并到同一个dalvik虚拟机中这样实质上是将很多个app放在同一个进程中运行了(每一个android应用程序都在自己的进程中运行,都拥有一个dalivk虚拟机实例。而每一个dalivk都是在linux的一个进程。所以说android dalivk和linux 进程可以认为是同一个概念)。直观的反应给我们程序开发人员就更简单了只需要将所有的app manifest的android:sharedUserId="com.liu.plugintest"配置成一致就可以了。

主程序manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.liu.zhen"
    android:sharedUserId="com.liu.plugintest"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />
    <application
        android:icon="@drawable/ic_launcher"
        android:process="com.liu.plugintest"
        android:label="@string/app_name" >
        <activity
            android:name="com.liu.zhen.MainActivity"
            android:process="com.liu.plugintest"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

插件manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.liu.zhen.plugin1"
    android:versionCode="1"
    android:sharedUserId="com.liu.plugintest"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />
    <application
        android:icon="@drawable/ic_launcher"
        android:process="com.liu.plugintest"
        android:label="@string/app_name">
        <activity
            android:name="com.liu.zhen.plugin1.MainActivity"
            android:process="com.liu.plugintest"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="com.liu.zhen.plugin1" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

可以看出来插件app是没有启动的activity的。

主程序定义插件的实体:

public class PluginBean {
	public String pakageName;
	public String label;
}

主程序获取插件信息:

	/**
	 * 查找插件
	* @return
	 */
	private List<PluginBean> findPlugins(){
	List<PluginBean> plugins=new ArrayList<PluginBean>();
	//遍历包名,来获取插件
	PackageManager pm=getPackageManager();
	List<PackageInfo> pkgs=pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
		for(PackageInfo pkg	:pkgs){
			//包名
			String packageName=pkg.packageName;
			String sharedUserId= pkg.sharedUserId;
			//sharedUserId是开发时约定好的,这样判断是否为自己人
			if(!"com.liu.plugintest".equals(sharedUserId)||"com.liu.zhen".equals(packageName))
				continue;
			//进程名
			String prcessName=pkg.applicationInfo.processName;
			//label,也就是appName了
			String label=pm.getApplicationLabel(pkg.applicationInfo).toString();
			PluginBean plug=new PluginBean();
			plug.label=label;
			plug.pakageName = packageName;
			plugins.add(plug);
		}
		return plugins;
	}

主程序添加插件导航到主程序的activity中:

	/**
	 * 加载插件列表
	 * @param plugins
	 */
	private void attachPlugin(final List<PluginBean> plugins){
		Log.e("liu", "----- 列出插件");
		this.plugins=plugins;
		for(final PluginBean plugin:plugins){
			System.out.println(plugin.pakageName);
			Button btn=new Button(this);
			btn.setTextColor(Color.RED);
			btn.setText(plugin.label);
			llMainLayout.addView(btn);
			//添加事件
			btn.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					Intent it=new Intent();
					it.setAction(plugin.pakageName);
					startActivity(it);
				}
			});
		}
	}

这里新建了三个android项目,其中一个作为主程序,其它两个为插件程序。

    

  

点击下载demo

时间: 2024-08-25 21:14:43

android基于插件式开发的相关文章

Android应用插件式开发解决方法

Android应用插件式开发解决方法 一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来越多,APK安装包也越来越大,用户在使用过程中也没有办法选择性的加载自己需要的功能模块.此时可能就需要考虑如何分拆整个应用了. 二.解决方案提出 一般有两种方式,一种是将应用按照功能分拆成多个应用,用户需要哪个就下载哪个,都需要就都下载.应用之间,可以在代码层面做一定的关联,以共享部分信息.另一种方式,类似于其他平台插件的方式,用户可以在主应用中可以选择性的下载需要的插件

Android应用插件式开发解决方法[转]

一.现实需求描述 一般的,一个Android应用在开发到了一定阶段以后,功能模块将会越来越多,APK安装包也越来越大,用户在使用过程中也没有办法选择性的加载自己需要的功能模块.此时可能就需要考虑如何分拆整个应用了. 二.解决方案提出 一般有两种方式,一种是将应用按照功能分拆成多个应用,用户需要哪个就下载哪个,都需要就都下载.应用之间,可以在代码层面做一定的关联,以共享部分信息.另一种方式,类似于其他平台插件的方式,用户可以在主应用中可以选择性的下载需要的插件,不需要该功能,则不需要下载. 第一种

基于AppDomain的&quot;插件式&quot;开发

很多时候,我们都想使用(开发)USB式(热插拔)的应用,例如,开发一个WinForm应用,并且这个WinForm应用能允许开发人员定制扩展插件,又例如,我们可能维护着一个WinService管理系统,这个WinService系统管理的形形色色各种各样的服务,这些服务也是各个"插件式"的类库,例如: public interface IJob { void Run(DateTime time); } public class CollectUserInfo : IJob { public

C#学习笔记-----基于AppDomain的&quot;插件式&quot;开发

很多时候,我们都想使用(开发)USB式(热插拔)的应用,例如,开发一个WinForm应用,并且这个WinForm应用能允许开发人员定制扩展插件,又例如,我们可能维护着一个WinService管理系统,这个WinService系统管理的形形色色各种各样的服务,这些服务也是各个"插件式"的类库,例如: public interface IJob { void Run(DateTime time); } public class CollectUserInfo : IJob { public

MVC 插件式开发

在开发一个OA系统是,我们可能遇到 A模块. B模块 .C模块,这也模块组成一个完整的系统,买给客服.现在又有一个客服要我们做一个OA系统,唉我们发现,跟上一个OA系统差不多,但没有C模块.怎么办? 修改源码,系统简单还好,但是一系统复杂到一定程度,修改源码改这改这就像重写了! 怎么办,MVC插件式开发帮你解决问题,先看演示,再看代码.CCAV.WebSite 是主站,引用 CCAV.Modules.Category CCAV.Modules.Category 就像当于一个模块,具体看演示. 通

关于安卓插件式开发

网上找了很多关于插件式开发的资料  最值得研究意义的两种开源开发插件框架http://www.oschina.net/p/cjframeforandroid 与http://www.oschina.net/p/xcombine    另外还有一种非常简单的通过sharedUserId方式去实现.接下来讲的就是最方便的通过sharedUserId去实现. 思路:在主app中与次app中设置同样的sharedUserId,在主app中通过这个id 找到其他次app的包名,通过包名开启其他次app.

关于dynamic-load插件式开发

dynamic-load插件式开发可以访问没有安装的APK中的类,也就是APK无需安装就可以被打开.具体原理有相关文档参考  http://blog.csdn.net/singwhatiwanna/article/details/22597587 其中有一些缺陷,插件中无法调用系统相册或者相机等,只要是用到intent调用系统acitivity都是行不通的. dynamic-load有三种开发模式,第一种是主程序与插件没有交互完全独立开发的,第二种是插件可以调用主程序提供的接口(因为插件中不支持

从零开始实现ASP.NET Core MVC的插件式开发(五) - 插件的删除和升级

标题:从零开始实现ASP.NET Core MVC的插件式开发(五) - 使用AssemblyLoadContext实现插件的升级和删除作者:Lamond Lu地址:https://www.cnblogs.com/lwqlun/p/11395828.html源代码:https://github.com/lamondlu/Mystique 前景回顾: 从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用Application Part动态加载控制器和视图 从零开始实现ASP.N

也来学学插件式开发

上一家公司有用到插件式开发来做一个工具箱,类似于QQ电脑管家,有很多工具列表,点一下工具下载后就可以开始使用了.可惜在那家公司待的时候有点短,没有好好研究一下.现在有空,自己在网上找了些资料,也来试试. 主要思路:公开一个插件接口,如果.DLL或.EXE的代码中有继承这个接口就将其示为插件,并将这些插件放在同一目录.运行程序的时候扫描目录并通过反射判断.DLL或.EXE中是否存在该接口,若存在,则当作插件加载进来. 我们来做一个示例看看.例子也是在园子里找的,自己改了一下,详见:http://w