0%

小程序实现

整体逻辑

  1. 通过提供的接口调用方法,打算启动
  2. 判断AppId是否为空,空则return;否则继续进入
  3. 启动跨进程的Service(如果之前没有启动的话)
  4. 根据AppId获取小程序配置(可能会在内存中有缓存,通过map存储起来,key为appId,value为配置的Bean),如果有缓存,则先直接使用缓存进入下一步,同时网络拉取配置供下次启动使用
  5. 根据配置判断小程序url是否合法、是否需要登录态,需要强制登录,则判断当前登录态(通过startActivityForResult 登录,在 onActivityResult 中跨进程更新登录态信息);否则拉取js信息。
  6. 正式进入小程序打开小程序

细节问题

  • 整个小程序体系包含:小程序 Loading 页的 Activity 以及 正式的小程序展示页面的 Activity

  • 对于单个小程序,会由 mainFragment 和 newFragment 来展示,其中 mainFragment 用于展示小程序主页面,打开新的子页面使用 newFragment 来承载

  • 跨进程用的服务 AIDLService 在主进程中

  • 小程序 Loading 页与小程序 Activity 在 :miniapp 进程中

  • 为了加快用户进入App就进入小程序这种应用场景,我们创建了一个空的 MiniAppPreService (这是一个 IntentService) ,并且这个 Service 在 :miniapp 进程中,在闪屏页就启动这个 Service。

  • 当小程序需要用户信息时,会有授权流程

  • 判断是否还是当前用户(比如需要涉及到支付的时候,需要做这一步)

  • 提供外部浏览器打开某个链接方式

  • 提供打开本地页面的接口

  • 提供向本地向小程序反馈结果的方法

可能的问题

1、为什么要跨进程?多进程带来的问题?

数据安全(获取用户信息必须得通过接口提供)、小程序崩溃不影响主程序、降低主程序的内存占用

多进程的问题:

  • 谨慎使用多进程,新进程会带有一些公共资源,是会消耗内存的
  • Application 会执行多次
  • SharedPreference 不可靠
  • 静态成员失效
  • 断点调试问题,在实际开发中,调试的时候先去除多进程

2、为什么要降低主程序内存占用,或者说内存占用过大会怎么样?

内存占用过大容易引起gc

3、为什么要用 mainFragment 和 newFragment 来承载小程序?

方便小程序内部页面跳转,以及小程序内部回退。

自己覆写了 onBackPressed 重写按返回键的行为,按返回键会移除新打开的页面

4、怎样启动newFragment?

创建新的 newFragment 对象,将 url 穿进去。之后,通过 FragmentTransaction 的 add 方法,将 newFragment 添加进去,在移除的时候,使用 FragmentTransaction 的 remove 方法移除。

5、fragment的 commit 和 commitAllowLoss 的理解?

6、AIDLService里面做了什么?

创建Binder 对象,用以从主进程获取数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class AIDLService : Service() {


private val binder: Binder = object : IUserInfoAidlInterface.Stub() {

override fun getAidlUserInfo(): AidlUserInfo {
val info = AidlUserInfo()
info.ck = UserInfoInstance.getInstance().ck
info.userName = UserInfoInstance.getInstance().username
info.latitude = CommonUtil.getLatitude()
info.longitude = CommonUtil.getLongitude()
info.encryptNetTime = TimerUtil.encryptNetTime
return info
}

}

override fun onBind(intent: Intent?): IBinder? {

return binder
}
}

7、js 用来干什么

为小程序提供调用 Native 方法的接口,比如调用获取用户信息,比如调用打开 App 中的页面

8、aidl 怎么使用,支持哪些数据格式

自己编写 aidl 文件即可,Android Studio 会自动生成 Java 文件,关于这块的知识可以参考以前的博客 ,aidl 文件类似下面的格式:

1
2
3
4
5
6
7
8
9
10
文件:IUserInfoAidlInterface.aidl

//一定要记得手动加这个import
import com.xxx.userinfoprovider.model.AidlUserInfo;

interface IUserInfoAidlInterface {

AidlUserInfo getAidlUserInfo();

}

支持基本的类型,int、long、boolean、float、double、String, 我们项目中需要支持对象,所以我们还需要再定义个 aidl 文件(这个Bean就这一行代码):

1
2
3
4
文件:AidlUserInfo.aidl


parcelable AidlUserInfo;

所以我们写 AIDL,如果需要传输 bean 的话,需要写 n+1 个 aidl 文件,这个 n 就是需要传输的 Bean 的个数。

9、怎么为小程序 Activity 设置进程

在 AndroidManifest.xml 中设置 android:process=”:miniapp”

10、MiniAppPreService 中做了什么?为什么是 IntentService ? IntentService 的作用 ?

里面啥也没做,使用它主要是因为 IntentService 在没有任务的时候自己会结束,不需要手工干预。

11、授权流程怎样的

  1. 与主进程同步数据
  2. 检查是否登录了,未登录先登录
  3. 与后台请求以前是否有授权过,如果授权过,直接将数据返回(json 形式,通过 webview.loadUrl(“javascript:” ) 形式返回)
  4. 未授权过,弹窗,让用户选择是否授权

12、如何检测是否还是当前用户?

因为在小程序里面支付的时候需要,所以支付之前需要检测是否是当前用户

检测方式: 将小程序自己持有的信息以参数形式传过来,之后传给后台,让后台判断

13、如何反馈信息给小程序?

通过使用 webview.loadUrl ,url 为 javascript: 开头的信息:

webview.loadUrl(“javascript:” )

14、不是会内存裁剪?提前启动 Service 会有作用吗?

谢谢你的鼓励