android 插件化 r.java_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

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" >

android:id="@+id/LinearLayoutContainer"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_weight="1"

android:orientation="vertical" >

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

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

只选择Plugin.java.

4b43b2d765a1fd33c61d78f0344249d7.png

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方式安装插件.....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值