mPaas容器跳到原生页面使用popWindow返回后获取不到返回数据问题分析

 

第一个页面:H5-1

第二个页面:H5-2

第三个页面:原生-1

 

H5-1 -> H5-2  -> 原生-1  

 

当 原生-1  返回到 H5-2  再返回到 H5-1时 数据丢失

 

思路:

1.hopper一下JsApiHandler4PopWindow源代码发现kNBSessionPopData  这个就是携带的返回数据

void -[JsApiHandler4PopWindow handler:context:callback:](void * self, void * _cmd, void * arg2, void * arg3, void * arg4) {
    stack[2048] = arg4;
    r31 = r31 - 0x170;
    *(r31 + 0x110) = r28;
    *(0x120 + r31) = r27;
    *(r31 + 0x120) = r26;
    *(0x130 + r31) = r25;
    *(r31 + 0x130) = r24;
    *(0x140 + r31) = r23;
    *(r31 + 0x140) = r22;
    *(0x150 + r31) = r21;
    *(r31 + 0x150) = r20;
    *(0x160 + r31) = r19;
    *(r31 + 0x160) = r29;
    *(0x170 + r31) = r30;
    r29 = r31 + 0x160;
    *(r29 + 0xffffffffffffffa0) = *___stack_chk_guard;
    r27 = [arg2 retain];
    r28 = [arg3 retain];
    *(r31 + 0x70) = self;
    *(0x80 + r31) = _OBJC_CLASS_$_JsApiHandler4PopWindow;
    [[r31 + 0x70 super] handler:r27 context:r28 callback:stack[2048]];
    if ([r27 isKindOfClass:[NSDictionary class]] != 0x0) {
            r0 = [r27 objectForKeyedSubscript:@"data"];
            r29 = r29;
            r0 = [r0 retain];
            [r0 release];
            if (r0 != 0x0) {
                    r21 = [[r28 currentSession] retain];
                    r0 = [r27 objectForKeyedSubscript:@"data"];
                    r29 = r29;
                    r19 = [r0 retain];
                    [r21 setExpando:@"kNBSessionPopData" withValue:r19];
                    [r19 release];
                    [r21 release];
            }
    }
    r25 = @selector(currentViewController);
    r0 = objc_msgSend(r28, r25);
    r0 = [r0 retain];
    r19 = r0;
    r0 = [r0 session];
    r0 = [r0 retain];
    r21 = r0;
    *r31 = @selector(subObjects);
    r0 = [r0 subObjects];
    r0 = [r0 retain];
    r23 = [r0 mutableCopy];
    [r0 release];
    [r21 release];
    [r19 release];
    r0 = [NSMutableArray array];
    r29 = r29;
    *(r31 + 0x28) = [r0 retain];
    *(r31 + 0x50) = q0;
    *(0x60 + r31) = q0;
    *(r31 + 0x30) = q0;
    *(0x40 + r31) = q0;
    r0 = [r23 retain];
    r23 = r0;
    *(r31 + 0x20) = @selector(countByEnumeratingWithState:objects:count:);
    r0 = [r0 countByEnumeratingWithState:r31 + 0x30 objects:r31 + 0x80 count:stack[2048]];
    if (r0 != 0x0) {
            r26 = r0;
            *(r31 + 0x8) = @selector(currentViewController);
            *(0x18 + r31) = r28;
            *(r31 + 0x18) = r27;
            r19 = zero_extend_64(0x0);
            r25 = **(r31 + 0x40);
            do {
                    r22 = zero_extend_64(0x0);
                    do {
                            if (**(r31 + 0x40) != r25) {
                                    objc_enumerationMutation(r23);
                            }
                            r21 = [*(*(r31 + 0x38) + r22 * 0x8) retain];
                            [r19 release];
                            r0 = [r21 viewController];
                            r29 = r29;
                            r0 = [r0 retain];
                            r20 = [r0 isTagEvicted];
                            [r0 release];
                            if (r20 != 0x0) {
                                    [*(r31 + 0x28) addObject:r21];
                            }
                            r22 = r22 + 0x1;
                            r19 = r21;
                    } while (r22 < r26);
                    r0 = objc_msgSend(r23, *(r31 + 0x20));
                    r26 = r0;
                    r19 = r21;
            } while (r0 != 0x0);
            [r21 release];
            r28 = *(r31 + 0x10);
            r27 = *(0x20 + r31);
            r25 = *(r31 + 0x8);
    }
    [r23 release];
    [r23 removeObjectsInArray:*(r31 + 0x28)];
    if ([r23 count] < 0x2) goto loc_101acd4a4;

loc_101acd434:
    r0 = objc_msgSend(r28, r25);
    r29 = r29;
    r0 = [r0 retain];
    r19 = r0;
    if ([r0 isChildTab] == 0x0) goto loc_101acd468;

loc_101acd45c:
    [r19 release];
    goto loc_101acd4a4;

loc_101acd4a4:
    r0 = objc_msgSend(r28, r25);
    r29 = r29;
    r0 = [r0 retain];
    [r0 clearAndBack];
    r0 = r0;
    goto loc_101acd4cc;

loc_101acd4cc:
    [r0 release];
    [*(r31 + 0x28) release];
    [r23 release];
    [r28 release];
    [r27 release];
    if (*___stack_chk_guard != *(r29 + 0xffffffffffffffa0)) {
            __stack_chk_fail();
    }
    return;

loc_101acd468:
    r0 = objc_msgSend(r28, r25);
    r29 = r29;
    r0 = [r0 retain];
    r21 = [r0 hasChildTab];
    [r0 release];
    [r19 release];
    if (r21 != 0x0) {
            r0 = objc_msgSend(r28, r25);
            r29 = r29;
            r0 = [r0 retain];
            [r0 clearAndBack];
            r0 = r0;
    }
    else {
            r0 = [r23 count];
            r22 = r25;
            r25 = r0;
            r0 = [r28 currentSession];
            r0 = [r0 retain];
            r19 = r0;
            r0 = objc_msgSend(r0, *r31);
            r0 = [r0 retain];
            r21 = [[r0 firstObject] retain];
            [r0 release];
            [r19 release];
            r0 = [r21 viewController];
            r29 = r29;
            r0 = [r0 retain];
            r19 = r0;
            r20 = [r0 childTabCount];
            [r19 release];
            if (r25 - 0x2 < r20) {
                    asm { ccmp       x20, #0x0, #0x4 };
            }
            if (CPU_FLAGS & E) {
                    asm { csel       x19, x8, xzr, eq };
            }
            r0 = objc_msgSend(r28, r22);
            r29 = r29;
            r0 = [r0 retain];
            [r0 popToWindowOfIndex:r19];
            [r0 release];
            r0 = r21;
    }
    goto loc_101acd4cc;
}

2.全局搜索kNBSessionPopData

0000000102b199c0         dq         ___CFConstantStringClassReference, 0x7c8, _amf_base64EncodedStringWithWrapWidth:.lookup+141700, 0x11 ; "kNBSessionPopData", DATA XREF=-[NBViewControllerProxy lifecycle_viewDidAppear:]+92, -[JsApiHandler4PopTo handler:context:callback:]+2476, -[JsApiHandler4PopTo handler:context:callback:]+2520, -[JsApiHandler4PopWindow handler:context:callback:]+288

3.可以看到这个就是取值的方法-[NBViewControllerProxy lifecycle_viewDidAppear:]

4.查看其代码主动调用的[r19 callHandler:@"resume" data:r22 responseCallback:stack[2048]];把数据传给了H5

void -[NBViewControllerProxy lifecycle_viewDidAppear:](void * self, void * _cmd, bool arg2) {
    *(r31 + 0xffffffffffffffb0) = r26;
    *(0xffffffffffffffc0 + r31) = r25;
    r31 = r31 + 0xffffffffffffffb0;
    *(r31 + 0x10) = r24;
    *(0x20 + r31) = r23;
    *(r31 + 0x20) = r22;
    *(0x30 + r31) = r21;
    *(r31 + 0x30) = r20;
    *(0x40 + r31) = r19;
    *(r31 + 0x40) = r29;
    *(0x50 + r31) = r30;
    r29 = r31 + 0x40;
    r19 = self;
    if ([*(self + 0x58) isViewReady] != 0x0) {
            r0 = [r19 psdSession];
            r0 = [r0 retain];
            r20 = [objc_msgSend(r0, @selector(getExpando:)) retain];
            [r0 release];
            r0 = [r19 psdSession];
            r0 = [r0 retain];
            [r0 deleteExpando:@"kNBSessionPopData"];
            [r21 release];
            r0 = [r19 psdSession];
            r0 = [r0 retain];
            r21 = [objc_msgSend(r0, @selector(getExpando:)) retain];
            [r0 release];
            r0 = [r19 psdSession];
            r29 = r29;
            r0 = [r0 retain];
            [r0 deleteExpando:@"kNBSessionResumeParams"];
            [r22 release];
            if (r21 != 0x0) {
                    r22 = [[NSMutableDictionary dictionary] retain];
                    [r22 setObject:[@(0x1) retain] forKeyedSubscript:@"__pull__"];
                    [r24 release];
                    [r22 setObject:r21 forKeyedSubscript:@"resumeParams"];
                    if (r20 != 0x0) {
                            [r22 setObject:r20 forKeyedSubscript:@"data"];
                    }
                    r22 = [r22 retain];
                    [r20 release];
                    [r19 callHandler:@"resume" data:r22 responseCallback:stack[2048]];
                    [r19 callHandler:@"pageResume" data:r22 responseCallback:stack[2048]];
                    [r22 release];
                    r20 = r22;
            }
            else {
                    [r19 callHandler:@"resume" data:r20 responseCallback:stack[2048]];
                    [r19 callHandler:@"pageResume" data:r20 responseCallback:stack[2048]];
            }
            [r21 release];
            [r20 release];
    }
    else {
            [*(r19 + 0x58) setIsViewReady:0x1];
    }
    [r19 performSelector:@selector(executeDelayTasks) withObject:zero_extend_64(0x0) afterDelay:stack[2048]];
    return;
}

 

5.对-[PSDJsBridge callHandler:data:responseCallback:]方法进行hook打印

发现  原生-1  返回到 H5-2的 时候返回数据是有的 , H5-2  再返回到 H5-1时数据丢失。

 

6.但是  原生-1  返回到 H5-2 使用的是 [temVC.navigationController popViewControllerAnimated:YES]

为什么这页 返回到 H5-2 打印了数据呢?

因为popViewControllerAnimated:YES 需要时间。

因为由代码可以看出只要页面出现viewDidAppear 就会调用callHandler:data:responseCallback。

 

原生-1  返回到 H5-2 全部代码是下面这两行。

        [tempVC.navigationController popViewControllerAnimated:YES];

        callback(dic);

页面没有完全返回到上一页就调用了callback。callback又调用了popwindow。所以返回数据作用到了H5-2页面。

 

7.这样的问题在蚂蚁mPaas框架了已经不是第1,2次遇到了.......

都是由于这0.25秒的动画导致的。

 

解决办法:

1.原生返回去掉动画

2.h5延迟调用

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值