flutter_boost中uniqueId在Flutter侧是如何获得的?

以下分析基于flutter_boost分支feature/flutter_1.9_androidx_upgrade

uniqueId标志着flutter侧的一个页面。可以通过uniqueId来关闭指定页面。那么该如何获取呢?

1:Android侧创建

ContainerRecord中提供了创建uniqueId方法

public static String genUniqueId(Object obj) {
    return System.currentTimeMillis() + "-" + obj.hashCode();
}

(1):当Android侧接收到来自Flutter侧的”openPage"请求时,调用了FlutterViewContainerManager.openContainer()方法中。生成了uniqueId。

void openContainer(String url, Map urlParams, Map exts,OnResult onResult) {
  ……
    final String uniqueId = ContainerRecord.genUniqueId(url);
    urlParams.put(IContainerRecord.UNIQ_KEY,uniqueId);
    if(onResult != null) {
        mOnResults.put(uniqueId,onResult);
    }

    NewFlutterBoost.instance().platform().openContainer(context,url,urlParams,requestCode,exts);
  }

生成的uniqueId,被放到了urlParams这个Map中。随后被传入到了Platform.openContainer()方法中。Platform的实例是在NewFlutterBoost中创建的。而platform.openContainer()方法调用的则是我们在Application中自定义的route类中的方法。

public void openContainer(Context context, String url, Map urlParams, int requestCode, Map exts) {
    router.openContainer(context, url, urlParams, requestCode, exts);
}

在Application中,实际上调用的有时PageRoute的openPageByUrl()

 INativeRouter router = new INativeRouter() {
            @Override
            public void openContainer(Context context, String url, Map urlParams, int requestCode, Map exts) {
                String assembleUrl = Utils.assembleUrl(url, urlParams);
                PageRouter.openPageByUrl(context, assembleUrl, urlParams);
            }
        };

进入PageRoute就可以看到最终开始创建了NewBoostFlutterActivity,用来承载flutterView。

Intent intent = NewBoostFlutterActivity.withNewEngine().url(pageName.get(path)).params(params)
        .backgroundMode(NewBoostFlutterActivity.BackgroundMode.opaque).build(context);
context.startActivity(intent);

此时我们来到NewBoostFlutterActivity的onCreate()中,其中与uniqueId相关的只有

setContentView(createFlutterView());

在创建FlutterView时,其实还是交给了委托类FlutterActivityAndFragmentDelegate

@NonNull
private View createFlutterView() {
    return delegate.onCreateView(
            null /* inflater */,
            null /* container */,
            null /* savedInstanceState */);
}

委托类在调用onCreateView进行flutterView的创建时,调用了IOperateSyncer接口的onCreate()。该接口的具体实现是ContainerRecord。

mSyncer.onCreate();

最终进入的是ContainerRecord的onCreate()实现。

@Override
public void onCreate() {
    Utils.assertCallOnMainThread();
    if (mState != STATE_UNKNOW) {
        Debuger.exception("state error");
    }
    mState = STATE_CREATED;
    mProxy.create();
}

在代理mProxy.create()中,开始进行methodChannel的native侧到flutter侧的通信。寻找“didInitPageContainer”该名字的方法。

private void create() {
    if (mState == STATE_UNKNOW) {
        invokeChannelUnsafe("didInitPageContainer",
                mContainer.getContainerUrl(),
                mContainer.getContainerUrlParams(),
                mUniqueId
        );
        //Debuger.log("didInitPageContainer");
        mState = STATE_CREATED;
    }
}
……
public void invokeChannelUnsafe(String method, String url, Map params, String uniqueId) {
    HashMap args = new HashMap<>();
    args.put("pageName", url);
    args.put("params", params);
    args.put("uniqueId", uniqueId);
    NewFlutterBoost.instance().channel().invokeMethodUnsafe(method, args);
}

最终就调到了FlutterBoostPlugin中的invokeMethod()

public void invokeMethod(final String name, Serializable args, MethodChannel.Result result) {
    if ("__event__".equals(name)) {
        Debuger.exception("method name should not be __event__");
    }
    mMethodChannel.invokeMethod(name, args, result);
}

2:Flutter侧接收

在ContainerCoordinator中,可以找到flutter被调用的方法“didInitPageContainer”

case "didInitPageContainer":
    {
      String pageName = call.arguments["pageName"];
      Map params = call.arguments["params"];
      String uniqueId = call.arguments["uniqueId"];
      _nativeContainerDidInit(pageName, params, uniqueId);
    }
    break;

在_nativeContainerDidInit()中开始创建ContainerSettings

  bool _nativeContainerDidInit(String name, Map params, String pageId) {
    performContainerLifeCycle(_createContainerSettings(name, params, pageId),
        ContainerLifeCycle.Init);
    return true;
  }

uniqueId于是就传入了Flutter侧。在flutter侧可以通过

String uniqueId=BoostContainer.of(context).uniqueId;

获得当前页面的uniqueId。

你可能感兴趣的:(flutter_boost中uniqueId在Flutter侧是如何获得的?)