Android 实现简单的插件化模块化.

最近需要实现在android上开发插件,下面把一个简单例子分享一下...

首先我们需要创建两个工程,一个是主程序,一个是插件工程

1.首先在主程序中定义一个接口. 

package com.mutour.testplugin;

import android.content.Context;
import android.view.View;

public interface Plugin {

	public void load();
	
	public void create(Context context, View view);
	
	public void create(View view);
	
	public void show();
	
	public void hide();
	
	public View getView();
}

2.接着在主程序中创建一个layout

<LinearLayout 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:orientation="vertical"
    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" >

    <LinearLayout
        android:id="@+id/LinearLayoutContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical" >
    </LinearLayout>

</LinearLayout>

3.然后把主程序中的interface Plugin打包成jar.

   主程序工程右键,Export, 选择Java-JAR file,(注意保存的路径), 一路的next

    只选择Plugin.java.

4.把生成的jar文件放到插件工程中 

5.在插件工程中写一个layout文件R.layout.activity_number_plugin,随便放点什么控件

6.在插件工程中写插件类

package com.mutour.testplugin.plugin;

import com.mutour.testplugin.Plugin;
import com.mutour.testplugin.plugin.R;

import android.content.Context;
import android.view.View;
import android.widget.LinearLayout;

public class NumberPlugin implements Plugin {

	private static final String TAG = "NumberPlugin";
	private Context mContext;
	private View mView;
	private View viewNumber;

	/**
	 * 必须有一个无参构造函数,否则无法用newInstance()获取句柄
	 */
	public NumberPlugin() {
	}

	public void setContext(Context context) {

		mContext = context;
	}

	public NumberPlugin(Context context) {
		this();
		mContext = context;
	}

	@Override
	public void load() {

	}

	@Override
	public void show() {
		((LinearLayout) mView).addView(viewNumber);
	}

	@Override
	public void hide() {
		if (mView != null)
			((LinearLayout) mView).removeAllViews();
	}

	@Override
	public void create(View view) {
		mView = view;
		viewNumber = View.inflate(mContext, R.layout.activity_number_plugin,
				null);
	}

	@Override
	public void create(Context context, View view) {
		mContext = context;
		this.create(view);
	}

	@Override
	public View getView() {
		return viewNumber;
	}

}

 

7.编译工程,把bin目录中的classes.dex文件放入手机的sd卡里.本文中放在sd卡根目录中

8.编写主程序调用插件dex文件

package com.mutour.testplugin;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.mutour.testplugin.plugin.QwertyPlugin;

import dalvik.system.DexClassLoader;
import android.os.Bundle;
import android.os.Environment;
import android.annotation.SuppressLint;
import android.app.ActionBar.LayoutParams;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;

@SuppressLint("NewApi")
public class MainActivity extends Activity {

	Plugin mPlugin;
	private LinearLayout mLinearLayoutContainer;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mLinearLayoutContainer = (LinearLayout) findViewById(R.id.LinearLayoutContainer);

		String filepath = Environment.getExternalStorageDirectory().toString()
				+ File.separator + "classes.dex";
		DexClassLoader cl = new DexClassLoader(filepath, MainActivity.this
				.getDir("dex", 0).getAbsolutePath(), null, getClassLoader());
		Class libProviderClazz = null;
		Plugin plugin = null;
		try {
			Context pluginContext = createPackageContext(
					"com.mutour.testplugin.plugin",
					Context.CONTEXT_IGNORE_SECURITY);
			libProviderClazz = cl.loadClass("com.mutour.testplugin.plugin"
					+ ".NumberPlugin");
			plugin = (Plugin) libProviderClazz.newInstance();
			if (plugin != null) {
				switchPlugin(pluginContext, plugin);
			}
		} catch (Exception exception) {
			exception.printStackTrace();
		}

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	private void switchPlugin(Context context, Plugin plugin) {
		if (mPlugin != null) {
			mPlugin.hide();
		}
		plugin.load();
		plugin.create(context, mLinearLayoutContainer);
		plugin.show();
		mPlugin = plugin;
	}

}

大功告成..............

其中有几个需要注意的地方

1..需要先获取dex的路径,使用DexClassLoader加载这个dex,然后使用包名和类名获取Class,然后使用newInstance获取句柄,把类型转换成Plugin

2.必须使用下面的方法获取插件包的Context,否则无法获取到插件包里的layout或其他资源

Context pluginContext = createPackageContext(
					"com.mutour.testplugin.plugin",
					Context.CONTEXT_IGNORE_SECURITY);

 

 

........................................................................................................................................

下面连接是该主程序和插件程序的代码..TestPlugin.rar是主程序 NumberPlugin.rar是插件程序

本方法是使用的dex方式,也可以使用apk方式安装插件.....

http://pan.baidu.com/s/1td9cO

 

转载于:https://my.oschina.net/mutour/blog/179242

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值