ArcGIS map crashes under android ViewPager2

1313
3
06-08-2020 07:48 AM
RSOEFejlesztes
New Contributor

Dear Esri Community!

My question might be a rookie one, I feel like I'm missing something very basic. I tried to make an ArcGIS map work under an android ViewPager2 structure. The map diplays nicely but when I navigate away to another fragment in the view pager, then back to the map, the app crashes with the following exception.

com.esri.arcgisruntime.ArcGISRuntimeException: vector: 
/home/jenkins/100.7.0/dev_android_java_RTCA_release/runtimecore/c_api/src/mapping/map_view/geo_view.cpp(701) : error : Exception caught in __FUNCTION__
    at com.esri.arcgisruntime.internal.jni.CoreGeoView.nativeDraw(Native Method)
    at com.esri.arcgisruntime.internal.jni.CoreGeoView.a(SourceFile:346)
    at com.esri.arcgisruntime.internal.h.b.o.a(SourceFile:132)
    at com.esri.arcgisruntime.mapping.view.MapView.onDrawFrame(SourceFile:156)
    at com.esri.arcgisruntime.mapping.view.GeoView$b.onDrawFrame(SourceFile:1363)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1573)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1272)


This seems to happen every time when the onResume() method of the Fragment containing the MapView is called. In this function (ie. the onResume()) I manually call onResume() on the MapView instance as indicated in this walkthrough:

https://developers.arcgis.com/labs/android/create-a-starter-app/

I extracted the problematic part of the code to a test app, I removed all layers, now it's just an empty basemap in an empty app (under the view pager structure) and the crash persists.

The reason why I think this problem could be connected with the ViewPager2 is because in a previous version of the app, I used a different navigation structure without the view pager and the map was working fine.

The difference between my actual code and the above walkthrough is that it puts the MapView directly under the MainActivity while I put it in a fragment as I'm working with a view pager.

It was not absolutely clear to me if I still have to put the appropriate onPause(), onResume(), onDestroy() calls under the fragment class or under the main activity so I tried both (you can see the former in the code below) and I also tried removing those override functions completely. The exception was the same in each case.

Here is the test app MainActivity class building the view pager.

class MainActivity : AppCompatActivity() {

    private lateinit var adapter: ViewPagerFragmentAdapter
    private lateinit var viewPager: ViewPager2

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        adapter = ViewPagerFragmentAdapter(supportFragmentManager, lifecycle)
        viewPager = findViewById(R.id.view_pager)
        viewPager.adapter = adapter
    }
}

And the MapFragment class.

class MapFragment: Fragment() {

    lateinit var mMapView: MapView

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_map, container, false)

        ArcGISRuntimeEnvironment.setLicense(resources.getString(R.string.arcgis_license_key))
        mMapView = view.findViewById(R.id.map_view)

        val basemapType = Basemap.Type.IMAGERY_WITH_LABELS
        val latitude = 48.0166175
        val longitude = 19.0339708
        val levelOfDetail = 2
        mMapView.map = ArcGISMap(basemapType, latitude, longitude, levelOfDetail)

        return view
    }

    override fun onPause() {
        if (mMapView != null) {
            mMapView.pause()
        }
        super.onPause()
    }

    override fun onResume() {
        super.onResume()
        if (mMapView != null) {
            mMapView.resume()
        }
    }

    override fun onDestroy() {
        if (mMapView != null) {
            mMapView.dispose()
        }
        super.onDestroy()
    }
}


Could you please give me any indicaton on where I could go wrong?

Thank you very much for any help in advance!

Mark

0 Kudos
3 Replies
GuntherHeppner
Esri Contributor

Hi Mark,

I think you are doing everything right with regard to calling onResume/onPause/onDestroy. Have you tried if you can reproduce this issue with version 100.8.0 of the Runtime SDK?

Gunther 

MarkSzente
New Contributor

Hi Gunther,

thank you very much for getting back to me. I managed to figure it out, indeed the SDK version change did the trick. Strangely however, when using the new SDK version (ie. 100.8.0) I also needed to remove the manual mMapView.dispose() call from MapFragment.onDestroy() as the ArcGIS API now does it automatically and the double call to dispose() results in further error. Now the app is stable, I hope I was doing the right thing. I'm just writing it all down in case anyone else bumps into the same issue.

Best regards,

Mark

0 Kudos
GuntherHeppner
Esri Contributor

Hi Mark,

I'm glad the issue has been fixed for you in 100.8.0.

You shouldn't see any issue with calling MapView.dispose(), calling it multiple times shouldn't cause any issues. Make sure you don't call into this MapView instance anymore after the MapView has been destroyed. If that's not the case, can you share a call stack of the error you are getting?

Thanks, Gunther

0 Kudos