App最简易的插件化思想开发—隐式跳转无图标应用

  • 前言

做久了App就知道一锅熟大杂烩不好受,所以就探索了一下最简易稳固的方式,将内容剥离主程序。

  • 问题

  • 疑问:现在的插件化框架那么多为什么还要存在利用无图标App这种低级方式?
    这个都明白插件化框架干的什么,好像插件化技术分几个方向:代理,占坑,钩子具体没了解,但是我知道这些毕竟犹如入侵技术不是一个万全之策,而且其稳定性、各家的使用规则性、安全性都不可控,还经常受谷歌政策的影响,如果要做一款稳定多的、安全性可控的、开发方式遵循谷歌爸爸的,那就这种非常实用,譬如公家的项目,最近也发现鲁大师的VR检测模块貌似也是这个路子。
  • 疑问:主App死亡,模块App在快照内存中运行存在,万一点击内存快照会不会直接唤起模块App?
    解:原计划模块App监测主App是否运行,不运行则弹窗拒绝开启并自杀,清理快照,后来发现清理快照不可为;但是惊喜的是主App死亡后,隐式打开的模块App并不会存在于快照中,很哈皮,估计是共享一个进程。
  • 疑问:主App卸载后,模块App如何卸载?
    解:原计划每个模块App实现一个静态Service,每个Service监听主App是否卸载,若收到卸载广播则排队卸载,卸载完后Service直接自杀.若Service被不小心清理掉那就GG,不卸载了;后来发现无法这样操作,主App卸载后无法卸载模块App,今日鲁大师的VR检测模块也无法卸载,说明真的无法卸载,主要在应用中进行业务提醒与引导,但是如果是使用代码进行卸载则可以进行广播与代码操作(代码所做的系统卸载操不会影响卸载代码后面的操作,现象好似多线程并行运行)。
  • 疑问:如何控制模块的版本更新?
    获取某个特定模块App的版本号
//获取版本号代码
try {
         PackageManager manager = this.getPackageManager();
         PackageInfo info = manager.getPackageInfo("jsnj33.com.sonlauncher1", 0);
         String versionName = info.versionName;
          int versionCode = info.versionCode;
      } catch (Exception e) {
          e.printStackTrace();
      }

在主App上增加子模块管理并添加检测,如果子模块版本增加则下载子模块,此时会需要用户安装,需要在下载前进行业务引导,用户可能会没有安装并退出App,所以在第二次进入检测后,发现还是旧版本,但是从用户角度来说再下载一遍,有点烦躁,所以对模块App的名字要进行规则命名严格管控,下载前通过子模块apk包名判断是否该下载。

  • 疑问:如何进行模块间传值?
    原计划模块间传值,将模块使用与主App一样的签名并sharedUserId,使其在共享同一进程(并不一定要在同一进程),据说这样可以共享数据data目录下的数据或是通过获取目标context访问目标app的一些资源,所有的bean类传值皆以json形式,一App不可以直接访问另一个App内存值,但是这些传值方式其实都是够了的,只需要写一个调度管理工具类,sharedUserId本质上与process属性开多进程其实是效果相同。
    这个博客写的sharedUserId总结不错:https://www.cnblogs.com/mythou/p/3258715.html

猜想总结:
  • 猜想模块App监测主App是否运行不运行则弹窗拒绝开启并自杀(实际运行来看暂时不需要,可以忽略)
  • 每个子模块需要记录各自版本用于更新

所遇弊端:

1.跳转时貌似遇到“冷启动慢的问题”,在第一次跳转时会遇到白屏,状态栏都是白的,看起来挺奇怪的,但是第二次打开后应该属于“热启动”没有这些问题,正常如初,这个暂时没有好的解决方式,只能设置一个模块加载中的windowBackground图片背景,不知道有没有预加载这个东西。
2.由于是几乎完全隔离的两个App,那么第三方包之类的不会进行共用,各个组件包重复率高。
3.通信不便,老生常谈,不作解释。
(这些弊端都可以想办法解决)


  • 具体做法:

1.宿主App所做:

//跳转到模块APP
Intent intent = new Intent();
//EaseConstant.PAGENAME:子模块包名;
//"jsnj33.com.pigapp.MainActivity":子模块具体Activity(完整路径)  EaseConstant.PAGENAME为子模块包名
 ComponentName cn = new ComponentName(EaseConstant.PAGENAME,"jsnj33.com.pigapp.MainActivity");
 intent.setComponent(cn);
 intent.setAction("android.intent.action.MAIN");
 intent.putExtra("exe","启动了");
 try {
     startActivityForResult(intent, RESULT_OK);
  } catch (Exception e) {
     ToastUtil.showToast(context,"暂无该子模块,请下载安装!");
 }

2.模块App所做
a.若在宿主Activty里面点击按钮跳转模块App 则模块设置为:





      
          
          
          
     

b.若在宿主fragment里面点击按钮跳转到模块App, 则模块App设置为


    
      
      
      
      
   

你可能感兴趣的:(App最简易的插件化思想开发—隐式跳转无图标应用)