• DroidPlugin知识整合


    一、DroidPlugin的优点

    •   宿主和插件完全隔离,插件不依赖宿主,可以独立安装运行
    •   低入侵设计,插件不需要集成任何类,和正常的app是一样的
    •   宿主程序集成DroidPlugin框架简单
    •   支持四大组件,完全使用Android的API

    二、DroidPlugin的缺点

    •   插件启动速度慢
    •   宿主只能调用插件为Launcher的Activity,宿主不能和插件中其他的Activity交互,也就是说插件是一个单独的模块,只能单一入口

    三、集成DroidPlugin

    1. 下载DroidPlugin

                下载地址:https://github.com/DroidPluginTeam/DroidPlugin

         

      2. 创建一个新功能,新建一个plugin模块。(假设app为宿主工程,plugin为插件工程)

      

      

      3. 导入DroidPlugin库

      找到下载的DroidPlugin,将projectLibrariesDroidPlugin导入到工程中

      

      

      4. 修改DroidPlugin中的build.gradle 文件

      

                (原build.gradle文件)

      

                 (修改后build.gradle文件)

      5. 修改DroidPlugin的AndroidManifest.xml文件,将所有的provide对应的authorities修改为自己的包名

      因为AndroidManifest.xml文件中,provide对应的authorities使用的是变量,所以修改build.gradle文件即可,请参考tip2

      

      6. 在宿主工程中添加DroidPlugin库。

    四、集成中报错总结

    错误一:

      

      解决方案:

      修改DroidPlugin中build.gradle文件的comileSdkVersion属性值,因为我app使用的28,所以也改为28

      =================================

    错误二:

    解决方案:

    修改DroidPlugin中build.gradle文件的buildToolsVersion 属性值,与app保持一致即可

    =================================

    错误三:

    解决方案:

    修改DroidPlugin中build.gradle文件,将“instrumentTest”属性改为“androidTest”

    =================================

    错误四:

    解决方案:

    将DroidPlugin中的AndroidManifext.xml中的minSDKVersion 去掉即可

    =================================

    错误五:

    定位到DroidPlugin中build.gradle文件,删除一下语句:

    =================================

    错误六:

      

    将compile关键字替换为implementation

      =================================

      错误七:

    解决方案:

    因为DroidPlugin使用的是lib文件夹,不是libs,所以将libs替换为lib,请参考tip1.

    =================================

    五、使用DroidPlugin插件 

    1. 自定义Application,在onCreate 和attachBaseContext方法中添加如下代码:
     1 public class PluginApplication extends Application {
     2     @Override
     3     public void onCreate() {
     4         super.onCreate();
     5         //must be after super.onCreate()
     6         PluginHelper.getInstance().applicationOnCreate(getBaseContext());
     7     }
     8 
     9     @Override
    10     protected void attachBaseContext(Context base) {
    11         PluginHelper.getInstance().applicationAttachBaseContext(base);
    12         super.attachBaseContext(base);
    13     }
    14 }

      2. 开发宿主工程(app)

     1 /**
     2  * 安装插件的方法
     3  * */
     4 private void installPlugin() {
     5     // 获取插件
     6     String path = Environment.getExternalStorageDirectory().toString() + "/plugins";
     7     File file = new File(path);
     8     if(!file.exists()){
     9         file.mkdirs();
    10     }
    11     plugins = file.listFiles();
    12     if(plugins == null || plugins.length == 0 ){ // 没有插件
    13         Toast.makeText(this,"没有插件",Toast.LENGTH_SHORT).show();
    14         return;
    15     }
    16     // 安装第一个插件
    17     try {
    18         PluginManager.getInstance().installPackage(plugins[0].getAbsolutePath(),
    19                 PackageManagerCompat.INSTALL_REPLACE_EXISTING);
    20     } catch (RemoteException e) {
    21         e.printStackTrace();
    22     }
    23 }
     1 // 调用插件
     2 findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
     3     @Override
     4     public void onClick(View v) {
     5         PackageManager pm = getPackageManager();
     6         Intent intent = pm.getLaunchIntentForPackage("ayinger.plugin");
     7         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    8 startActivityForResult(intent,1); 9 10 } 11 });

      注意:

    •   上述方法为插件工程不安装,将插件工程直接放在了/storage/emulated/0/plugins目录下,调用installPlugin()来安装插件工程。
    •   另外,还有一种是插件工程已经安装成功,直接,可省略installPlugin()步骤,直接调用插件,即可,这里注意一点,getLaunchIntentForPackage()方法  中,传入的参数是插件的applicationId 属性的值。
    •   创建文件夹的时候,要注意检查是否授权,不然文件夹创建不成功。(入过坑)。

    六、 其他

    1. 安装/更新

      PluginManager.getInstance().installPackage(String packageName, int flags)

        安装插件到插件系统中,packageName为插件apk路径,flags可以设置为0,如果要更新插件,则设置为PackageManagerCompat.INSTALL_REPLACE_EXISTING

      2. 删除

      PluginManager.getInstance().deletePackage(String packageName,int flags);

        从插件系统中卸载某个插件,packageName: 需卸载插件包名, flags: 设置为0

      3. 宿主和插件通信

     1 // 宿主和插件如何互通SharedPreferences
     2 try {
     3     Context otherAppsContext = createPackageContext("HostPackageName",
     4             Context.CONTEXT_IGNORE_SECURITY);
     5     SharedPreferences sharedPreferences = otherAppsContext.
     6             getSharedPreferences("test", Context.MODE_WORLD_READABLE);
     7     if (sharedPreferences != null) {
     8         String str1 = sharedPreferences.getString("key",null);
     9         Toast.makeText(getApplicationContext(), "result: " + str,
    10                 Toast.LENGTH_SHORT).show();
    11     }
    12 } catch (PackageManager.NameNotFoundException e) {
    13     e.printStackTrace();
    14 }

    七、 参考博客

      https://blog.csdn.net/chaozhung_no_l/article/details/71439919

      https://blog.csdn.net/wushipan/article/details/51577850

     

     

  • 相关阅读:
    【每日scrum】5.3
    Scrum仪式之Sprint计划会议
    软工结队开发--成员介绍
    java反射保存
    java后台开发传输乱码&&接口post传参失败
    润乾报表之分组
    润乾报表之居中无效(去空格)
    润乾报表之日期格式、小数位数
    润乾报表之序号、固定行数、统计
    润乾报表之条形码
  • 原文地址:https://www.cnblogs.com/Ayinger/p/11023589.html
Copyright © 2020-2023  润新知