New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TabView with ScrollView and MapView crashes #3960

Closed
ludcila opened this Issue Apr 7, 2017 · 17 comments

Comments

Projects
None yet
@ludcila
Copy link

ludcila commented Apr 7, 2017

Which platform(s) does your issue occur on?

Only tested on Android.

Please provide the following version numbers that your issue occurs with:

Please tell us how to recreate the issue in as much detail as possible.

I have a TabView with three tabs: the first one with a ScrollView, the second one with a MapView, and the third one empty. When the application is first launched it works fine, but if I minimize it and then resume, it crashes as soon as I switch between the tabs.

Sample code: https://github.com/ludcila/tabview-scrollview-mapview
(set API key in app/App_Resources/Android/values/nativescript_google_maps_api.xml)

D/AndroidRuntime(15596): Shutting down VM
W/dalvikvm(15596): threadid=1: thread exiting with uncaught exception (group=0x41f35700)
D/dalvikvm(15596): GC_FOR_ALLOC freed 1595K, 23% free 14306K/18456K, paused 22ms, total 22ms
W/System.err(15596): com.tns.NativeScriptException:
W/System.err(15596): Calling js method instantiateItem failed
W/System.err(15596): Error: java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to org.nativescript.widgets.HorizontalScrollView$SavedState
W/System.err(15596): org.nativescript.widgets.VerticalScrollView.onRestoreInstanceState(VerticalScrollView.java:166)
W/System.err(15596): android.view.View.dispatchRestoreInstanceState(View.java:13188)
W/System.err(15596): android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2850)
W/System.err(15596): android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2856)
W/System.err(15596): android.view.View.restoreHierarchyState(View.java:13166)
W/System.err(15596): com.tns.Runtime.callJSMethodNative(Native Method)
W/System.err(15596): com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1197)
W/System.err(15596): com.tns.Runtime.callJSMethodImpl(Runtime.java:1061)
W/System.err(15596): com.tns.Runtime.callJSMethod(Runtime.java:1047)
W/System.err(15596): com.tns.Runtime.callJSMethod(Runtime.java:1028)
W/System.err(15596): com.tns.Runtime.callJSMethod(Runtime.java:1018)
W/System.err(15596): com.tns.gen.android.support.v4.view.PagerAdapter_frnal_ts_helpers_l58_c38__PagerAdapterClassInner.instantiateItem(android.support.v4.view.PagerAdapter.java)
W/System.err(15596): android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1001)
W/System.err(15596): android.support.v4.view.ViewPager.populate(ViewPager.java:1183)
W/System.err(15596): android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:666)
W/System.err(15596): android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:628)
W/System.err(15596): android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:609)
W/System.err(15596): org.nativescript.widgets.TabLayout$TabClickListener.onClick(TabLayout.java:406)
W/System.err(15596): android.view.View.performClick(View.java:4475)
W/System.err(15596): android.view.View$PerformClick.run(View.java:18786)
W/System.err(15596): android.os.Handler.handleCallback(Handler.java:730)
W/System.err(15596): android.os.Handler.dispatchMessage(Handler.java:92)
W/System.err(15596): android.os.Looper.loop(Looper.java:137)
W/System.err(15596): android.app.ActivityThread.main(ActivityThread.java:5419)
W/System.err(15596): java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(15596): java.lang.reflect.Method.invoke(Method.java:525)
W/System.err(15596): com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
W/System.err(15596): com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
W/System.err(15596): dalvik.system.NativeStart.main(Native Method)
W/System.err(15596): File: "file:///data/data/org.nativescript.tabs/files/app/tns_modules/tns-core-modules/ui/tab-view/tab-view.js, line: 64, column: 38
W/System.err(15596): StackTrace:
W/System.err(15596): Frame: function:'PagerAdapterClassInner.instantiateItem', file:'file:///data/data/org.nativescript.tabs/files/app/tns_modules/tns-core-modules/ui/tab-view/tab-view.js', line: 64, column: 39
W/System.err(15596): at com.tns.Runtime.callJSMethodNative(Native Method)
W/System.err(15596): at com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1197)
W/System.err(15596): at com.tns.Runtime.callJSMethodImpl(Runtime.java:1061)
W/System.err(15596): at com.tns.Runtime.callJSMethod(Runtime.java:1047)
W/System.err(15596): at com.tns.Runtime.callJSMethod(Runtime.java:1028)
W/System.err(15596): at com.tns.Runtime.callJSMethod(Runtime.java:1018)
W/System.err(15596): at com.tns.gen.android.support.v4.view.PagerAdapter_frnal_ts_helpers_l58_c38__PagerAdapterClassInner.instantiateItem(android.support.v4.view.PagerAdapter.java)
W/System.err(15596): at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1001)
W/System.err(15596): at android.support.v4.view.ViewPager.populate(ViewPager.java:1183)
W/System.err(15596): at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:666)
W/System.err(15596): at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:628)
W/System.err(15596): at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:609)
W/System.err(15596): at org.nativescript.widgets.TabLayout$TabClickListener.onClick(TabLayout.java:406)
W/System.err(15596): at android.view.View.performClick(View.java:4475)
W/System.err(15596): at android.view.View$PerformClick.run(View.java:18786)
W/System.err(15596): at android.os.Handler.handleCallback(Handler.java:730)
W/System.err(15596): at android.os.Handler.dispatchMessage(Handler.java:92)
W/System.err(15596): at android.os.Looper.loop(Looper.java:137)
W/System.err(15596): at android.app.ActivityThread.main(ActivityThread.java:5419)
W/System.err(15596): at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(15596): at java.lang.reflect.Method.invoke(Method.java:525)
W/System.err(15596): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
W/System.err(15596): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
W/System.err(15596): at dalvik.system.NativeStart.main(Native Method)
W/System.err(15596): Caused by: java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to org.nativescript.widgets.HorizontalScrollView$SavedState
W/System.err(15596): at org.nativescript.widgets.VerticalScrollView.onRestoreInstanceState(VerticalScrollView.java:166)
W/System.err(15596): at android.view.View.dispatchRestoreInstanceState(View.java:13188)
W/System.err(15596): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2850)
W/System.err(15596): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2856)
W/System.err(15596): at android.view.View.restoreHierarchyState(View.java:13166)
W/System.err(15596): ... 24 more
I/Process (15596): Sending signal. PID: 15596 SIG: 9

@NickIliev

This comment has been minimized.

Copy link
Member

NickIliev commented Apr 10, 2017

Hey, @ludcila thanks for the test project!

The issue is fully reproducible with all API levels using this sample

Steps to reproduce:

  • run the app
  • interact with the tabs (everything is OK!)
  • minimize the application and then go back
  • interact with the tabs and crash occurs immediately or after few tabs
Error: java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to org.nativescript.widgets.HorizontalScrollView$SavedState
@randy-johnson

This comment has been minimized.

Copy link

randy-johnson commented May 7, 2017

I get just about the same error when using the back button on Android when the page going back to is with the mapView and Listview

java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to org.nativescript.widgets.HorizontalScrollView$SavedState
05-07 12:16:06.060  4878  4878 V JS      :      at org.nativescript.widgets.VerticalScrollView.onRestoreInstanceState(VerticalScrollView.java:166)
05-07 12:16:06.060  4878  4878 V JS      :      at android.view.View.dispatchRestoreInstanceState(View.java:15633)
05-07 12:16:06.060  4878  4878 V JS      :      at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3268)
05-07 12:16:06.060  4878  4878 V JS      :      at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3274)
05-07 12:16:06.060  4878  4878 V JS      :      at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3274)
05-07 12:16:06.060  4878  4878 V JS      :      at android.view.View.restoreHierarchyState(View.java:15611)
05-07 12:16:06.060  4878  4878 V JS      :      at android.app.Fragment.restoreViewState(Fragment.java:645)
05-07 12:16:06.060  4878  4878 V JS      :      at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1016)
05-07 12:16:06.060  4878  4878 V JS      :      at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1171)
05-07 12:16:06.060  4878  4878 V JS      :      at android.app.BackStackRecord.popFromBackStack(BackStackRecord.java:1747)
05-07 12:16:06.060  4878  4878 V JS      :      at android.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1691)
05-07 12:16:06.060  4878  4878 V JS      :      at android.app.FragmentManagerImpl$3.run(FragmentManager.java:586)
05-07 12:16:06.060  4878  4878 V JS      :      at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1578)
05-07 12:16:06.060  4878  4878 V JS      :      at android.app.FragmentManagerImpl$1.run(FragmentManager.java:483)
05-07 12:16:06.060  4878  4878 V JS      :      at android.os.Handler.handleCallback(Handler.java:751)
05-07 12:16:06.060  4878  4878 V JS      :      at android.os.Handler.dispatchMessage(Handler.java:95)
05-07 12:16:06.060  4878  4878 V JS      :      at android.os.Looper.loop(Looper.java:154)
05-07 12:16:06.060  4878  4878 V JS      :      at android.app.ActivityThread.main(ActivityThread.java:6077)
05-07 12:16:06.060  4878  4878 V JS      :      at java.lang.reflect.Method.invoke(Native Method)
05-07 12:16:06.060  4878  4878 V JS      :      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
05-07 12:16:06.060  4878  4878 V JS      :      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

@NickIliev

This comment has been minimized.

Copy link
Member

NickIliev commented May 9, 2017

This issue is fixed in NativeScript 3.0.0
Test application with modules 3.0.0 here

@SvetoslavTsenov SvetoslavTsenov self-assigned this May 9, 2017

@NickIliev NickIliev removed their assignment May 11, 2017

@hshristov hshristov added this to the 3.1 TBD milestone May 16, 2017

@SvetoslavTsenov SvetoslavTsenov added done and removed ready for test labels May 17, 2017

@dtopuzov dtopuzov modified the milestones: 3.0.1, 3.1 May 22, 2017

@randy-johnson

This comment has been minimized.

Copy link

randy-johnson commented Jul 23, 2017

I am seeing the error mentioned above in NS 3.1.2 . when using the android back button when the page going back to is a mapview / scrollview.

Here is the error again for clarification: android.view.AbsSavedState$1 cannot be cast to org.nativescript.widgets.HorizontalScrollView$SavedState

@manojdcoder

This comment has been minimized.

Copy link

manojdcoder commented Jul 30, 2017

@NickIliev App still crashes if I have a map view as descendant of scrollview, with tns android runtime 3.1.1 and nativescript-google-maps-sdk 2.1.3 Any workaround?

@isaacfi

This comment has been minimized.

Copy link

isaacfi commented Aug 2, 2017

The issue mut be reopened, please fix it.

Regards

@manojdcoder

This comment has been minimized.

Copy link

manojdcoder commented Aug 2, 2017

Having a map view inside a scroll view still crashes with android runtime v3.1.1. I ended up moving the map view to a popup in my app.

@isaacfi

This comment has been minimized.

Copy link

isaacfi commented Aug 2, 2017

I have no a MapView Inside ScrollView

@tsonevn

This comment has been minimized.

Copy link
Contributor

tsonevn commented Aug 3, 2017

Hi @manojdcoder @isaacfi,
I tested this case while using the nativescritp-google-maps-sdk plugin and latest tns-core-modules 3.1.0 and the app seems to work as expected. I am attaching a sample project. it would help if you could review the project and to make the needed changes, which will allow us to investigate this problem.
Archive.zip

@manojdcoder

This comment has been minimized.

Copy link

manojdcoder commented Aug 3, 2017

@tsonevn It doesn't crash as soon map is loaded inside scrollview. But does when a new page / activity is opened and you come back to the previous map activity. I will work on a sample where you can reproduce this and revert to you shortly.

@manojdcoder

This comment has been minimized.

Copy link

manojdcoder commented Aug 4, 2017

@tsonevn Please find the attached sample project where you can easily reproduce the crash.

MapIssue.zip

@tsonevn

This comment has been minimized.

Copy link
Contributor

tsonevn commented Aug 7, 2017

Hi @manojdcoder,
Thank you for the sample app.
I will review it and will provide more info about the case.

@EricRobertBrewer

This comment has been minimized.

Copy link

EricRobertBrewer commented Aug 14, 2017

Here is a workaround for an Angular2 project, but it can be easily ported to a JavaScript project:

app/App_Resources/Android/values/ids.xml: <- create this file

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="scroll_view" type="id" />
</resources>

my-page.component.html:

<ScrollView (loaded)="onScrollViewLoaded($event)">
    <!-- Other views... -->
</ScrollView>

my-page.component.ts:

import * as utils from 'utils/utils';

@Component({
    moduleId: module.id,
    templateUrl: './my-page.component.html'
})
export class MyPageComponent {

    onScrollViewLoaded(event) {
        const scrollView = event.object;
        if (scrollView.android) {
            const id = utils.ad.resources.getId('scroll_view');
            scrollView.android.setId(id);
        }
    }

    ...
}

I've ran into a similar issue before.

@manojdcoder

This comment has been minimized.

Copy link

manojdcoder commented Aug 14, 2017

@tsonevn Can you please re-open this issue or create new one?

@tsonevn tsonevn removed the done label Aug 21, 2017

@vakrilov vakrilov modified the milestones: 3.3 (TBD), 3.0.1 Aug 21, 2017

@vakrilov vakrilov reopened this Aug 21, 2017

@vakrilov

This comment has been minimized.

Copy link
Member

vakrilov commented Aug 21, 2017

Reopening the issue - repro project in this comment.

@hshristov hshristov modified the milestones: 3.2, 3.3 (TBD) Aug 24, 2017

@hshristov

This comment has been minimized.

Copy link
Member

hshristov commented Aug 24, 2017

It seems that Google MapView internally sets ids that are not unique and collide with id of our widgets. Once widgets save their state in order to later restore it their state get overridden by the internal widgets of MapView. So in order to prevent this crash you should call in createNativeView:

MapView.prototype.createNativeView = function () {
...
    this.nativeView.setSaveFromParentEnabled(false);

This will disable state saving for MapView and will stop this crash. After that another crash will happen but it is caused by the plugin itself - Marker class changes its android property and later when activity is recreated a crash will happen when .addMarker method is called. This needs refactoring inside the plugin code in order to be fixed.

If you want so save/restore map state it will be possible to attach handler to application launch event and get the saveInstanceState bundle from the event args (after this PR is merged #4750).

Then in onActivitySaveInstanceState you can save the map state like that:

this.nativeView.setSaveFromParentEnabled(true);
var mapState = new android.os.Bundle();
this.nativeView.onSaveInstanceState(mapState);
// Put the map bundle in the main outState
args.bundle.putBundle("mapData" + this._domId, mapState);
this.nativeView.setSaveFromParentEnabled(false);

and in application.launch handler to extract the bundle:

function MapView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this._markers = new Array();
        application.on("launch", function (args) {
            var bundle = args.savedInstanceState;
            _this.savedInstanceState = bundle ? bundle.getBundle("mapData" + _this._domId) : null;
        });
        return _this;
    }

and finally in createNativeView you will be able to pass the bundle to create method:

MapView.prototype.createNativeView = function () {
...
this.nativeView = new com.google.android.gms.maps.MapView(this._context, options);
this.nativeView.setSaveFromParentEnabled(false);
this.nativeView.onCreate(this.savedInstanceState);
this.savedInstanceState = null;

And the plugin author should not update camera position always because this will break state restoration.

@shiv19

This comment has been minimized.

Copy link
Contributor

shiv19 commented Sep 15, 2017

Hey!
I have a workaround for people who are facing crashes with the map view
https://shiv19.github.io/how-to-fix-nativescript-google-maps-sdk-map-view-crash-inside-scroll-view/

Hope this helps someone 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment