插件化DroidPlugin的使用以及简单问题的处理

先上GitHub参考地址:https://github.com/DroidPluginTeam/DroidPlugin/blob/master/readme_cn.md。

下面直接开始使用。

1. 下载:首先在GitHub下载源码。


2. 导入:解压下载的包,打开Android Studio,新建一个项目,然后导入DroidPlugin\DroidPlugin-master\project\Libraries\DroidPlugin这个Module:


3. 添加依赖:在宿主项目中添加对DroidPlugin的依赖:


修改DroidPlugin的build.gradle中的作者,


4. 接下来开始上代码:

   4.1 在自己的Application中初始化插件如下,然后记得在Manifest文件注册:

public class MyApp extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        PluginHelper.getInstance().applicationOnCreate(getBaseContext());
    }

    @Override
    protected void attachBaseContext(Context base) {
        PluginHelper.getInstance().applicationAttachBaseContext(base);
        super.attachBaseContext(base);
    }
}


   4.2 在MainActivity中进行插件App的安装和启动,我是通过两个按钮来调试的:

private TextView tvTest;
private TextView tvResult;
private File[] plugins;
private Button btnInstall;
private Button btnTest;
private int a;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tvTest = (TextView) findViewById(R.id.tv_test);
    tvResult = (TextView) findViewById(R.id.tv_result);
    btnTest = (Button) findViewById(R.id.btn_test);
    btnInstall = (Button) findViewById(R.id.btn_install);


    //安装apk
    btnInstall.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            //获取插件,file是插件apk存放的文件夹,
            File file = new File(Environment.getExternalStorageDirectory(), "/plugin");
            plugins = file.listFiles();
            //没有插件
            if (plugins == null || plugins.length == 0) {
                Log.d("sss", "插件安装失败==没有找到插件");
                return;
            }
            //1.先卸载apk,插件apk的包名是“com.plugin”,不管有没有安装,先卸载了再说
            try {
                PluginManager.getInstance().deletePackage("com.plugin", 0);
            } catch (RemoteException e) {
                Log.d("sss", "插件卸载失败=="+e.getMessage().toString());
                e.printStackTrace();
            }

            for (File apk:plugins ) {
                if (!apk.getAbsolutePath().contains("apk")){
                    Log.d("sss", "不是apk文件啊=="+apk.getName());
                   continue;
                }
		//开始进行插件apk的安装
                try {
                    tvTest.setText(apk.getAbsolutePath());
                    Log.d("sss", "即将安装的apk=="+apk.getAbsolutePath());
                    //a = PluginManager.getInstance().installPackage(plugins[0].getAbsolutePath(), 0);//安装第一个插件
                    a =PluginManager.getInstance().installPackage(apk.getAbsolutePath(), PackageManagerCompat.INSTALL_REPLACE_EXISTING);

                    getResult(a);
                } catch (RemoteException e) {
                    Log.d("sss", "插件安装失败=="+e.getMessage().toString());
                    e.printStackTrace();

                }
            }
        }
    });

    //启动APK插件
    btnTest.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                PackageManager pm = getPackageManager();

                Intent intent = pm.getLaunchIntentForPackage("com.plugin");

                if (intent == null){
                    Log.d("sss","intent是空的,没法使用啊");
                }
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                startActivity(intent);
            } catch (Exception e) {
                e.printStackTrace();
                Log.d("sss", "插件启动失败==" + e.toString());
            }
        }
    });
}

private void getResult(int a) {
    switch (a) {
        case -1:
            tvResult.setText("安装或卸载失败");
            break;
        case 1:
            tvResult.setText("安装或卸载成功");
            break;
        case -110:
            tvResult.setText("安装程序内部错误");
            break;
        case -2:
            tvResult.setText("无效的Apk");
            break;
        case 0x00000002:
            tvResult.setText("安装更新");
            break;
        case -3:
            tvResult.setText("不支持的ABI");
            break;

        default:
            tvResult.setText("老天都不知道这是咋了,a=="+a);
            break;
    }

}

    4.3在activity_main.xml中的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context="com.example.myapplication.MainActivity">

    <TextView
        android:id="@+id/tv_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="无插件"
        android:textColor="@android:color/holo_green_dark"
        android:textSize="22sp"
        />
    <Button
        android:layout_marginTop="10dp"
        android:id="@+id/btn_install"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_test"
        android:text="安装插件"
        android:textColor="@android:color/holo_green_dark"
        android:textSize="18sp"
        />

    <Button
        android:layout_marginTop="10dp"
        android:id="@+id/btn_test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btn_install"
        android:text="启动插件"
        android:textColor="@android:color/holo_green_dark"
        android:textSize="18sp"
        />

    <TextView
        android:layout_marginTop="10dp"
        android:id="@+id/tv_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btn_test"
        android:text="无插件"
        android:textColor="@android:color/holo_green_dark"
        android:textSize="22sp"
        />

</RelativeLayout>
5.当你要运用到自己的项目上的时候,还有麻烦,那就是代码混淆:

-keep class com.morgoo.droidplugin.stub.** { *; }
-keep class android.**{ *; }

6。代码混淆后,有可能会出现的问题:

   6.1.有可能发生三个警告,然后你安装的时候发现宿主程序就是打不开了

   6.2.宿主程序能打开,插件Apk能安装,但是启动的时候找不到Activity了

 解决办法:把DroidPlugin的layoutlib.jar去掉,把里面的抽象类Singleton移植到DroidPlugin的android/util目录下(如下图),保持混淆不变,问题解决。


7.附上我做的Demo的下载链接http://download.csdn.net/detail/sxk874890728/9905614。如果有问题,欢迎大家一起讨论问题。


评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值