JNI Error on Scene Transition Animation - Layer exceeds max

AndroidAndroid AnimationPicasso

Android Problem Overview


please notice the EDIT in the bottom of the question

I have 2 activities: ActivityA, ActivityB with associated frgments: FragmentA, FragmentB respectively. ImageView v is shared between those two fragments.

some Code: ActivityA

Intent intent = new Intent(this, ActivityB.class);
final ActivityOptionsCompat activityOptionsCompat = ActivityOptionsCompat.
                         makeSceneTransitionAnimation(this, imageView, "photo");   
                             
ActivityCompat.startActivity(this, intent, activityOptionsCompat.toBundle());

ActivityB

FragmentB fragment = new FragmentB();
getFragmentManager().beginTransaction()..replace(R.id.fragment_container, fragment, TAG).addToBackStack(TAG).commit();

FragmentB

mView = (ImageView) view.findViewById(R.id.view);
ViewCompat.setTransitionName(mView, "photo);

4 out of 5 times it's working. but when it's not working i'm getting the Very informative error:

W/OpenGLRenderer﹕ Layer exceeds max. dimensions supported by the GPU (1080x10659, max=4096x4096)
JNI DETECTED ERROR IN APPLICATION: JNI CallVoidMethodV called with pending exception 'java.lang.IllegalStateException' thrown in void android.os.MessageQueue.nativePollOnce(long, int):-2

Call to Picasso

Picasso.with(context).load(url).centerCrop().resize(width, height).noFade().into(mView);

Few things that can cause this:

  1. in FragmentB mView position is calculated dynamically using ViewTreeObserver.OnGlobalLayoutListener

  2. mView extends ImageView in order to create Oval effect in both of the Fragments.

  3. the root ViewGroup is a ScrollView

one last thing: the Theme of both of the activities is a child of

<style name="Theme" parent="Theme.AppCompat.Light"
    <item name="android:windowContentTransitions">true</item>
    <item name="android:windowAllowEnterTransitionOverlap">true</item>
    <item name="android:windowAllowReturnTransitionOverlap">true</item>
    <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
    <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>

--- EDIT ---

Similar question and answer to my problem and another

Answer do solve the issue but only for API 21. I'm using ActivityCompat.startActivity(...). it supports api 16 and above but TransitionListener is only available since API 19 and supports SceneTransition since API 21

Also android:transitionGroup="true" requires API 21 so now i have 2 main questions:

  1. Why i'm even getting LayerExceeds max error? my shared View is no bigger than 1080x1080.
  2. how can i handle this kind of error on API < 21 where both TransitionListener and transitionGroup are unavailable?

ERROR stacktrace

JNI DETECTED ERROR IN APPLICATION: JNI CallVoidMethodV called with pending exception 'java.lang.IllegalStateException' thrown in void android.os.MessageQueue.nativePollOnce(long, int):-2
in call to CallVoidMethodV
art/runtime/check_jni.cc:65] from void android.os.MessageQueue.nativePollOnce(long, int)
art/runtime/check_jni.cc:65] "main" prio=5 tid=1 Runnable
art/runtime/check_jni.cc:65]   | group="main" sCount=0 dsCount=0 obj=0x72fb6000 self=0xb4827800
art/runtime/check_jni.cc:65]   | sysTid=6497 nice=0 cgrp=default sched=0/0 handle=0xb6f83bec
art/runtime/check_jni.cc:65]   | state=R schedstat=( 1181860917 459124594 2277 ) utm=100 stm=18 core=2 HZ=100
art/runtime/check_jni.cc:65]   | stack=0xbe27d000-0xbe27f000 stackSize=8MB
art/runtime/check_jni.cc:65]   | held mutexes= "mutator lock"(shared held)
art/runtime/check_jni.cc:65]   native: #00 pc 00004e64  /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
art/runtime/check_jni.cc:65]   native: #01 pc 00003665  /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
art/runtime/check_jni.cc:65]   native: #02 pc 00256429  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+84)
art/runtime/check_jni.cc:65]   native: #03 pc 00238fe7  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+158)
art/runtime/check_jni.cc:65]   native: #04 pc 000b191b  /system/lib/libart.so (art::JniAbort(char const*, char const*)+610)
art/runtime/check_jni.cc:65]   native: #05 pc 000b2055  /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68)
art/runtime/check_jni.cc:65]   native: #06 pc 000b530f  /system/lib/libart.so (art::ScopedCheck::ScopedCheck(_JNIEnv*, int, char const*)+1346)
art/runtime/check_jni.cc:65]   native: #07 pc 000bd6f7  /system/lib/libart.so (art::CheckJNI::CallVoidMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+42)
art/runtime/check_jni.cc:65]   native: #08 pc 0006244b  /system/lib/libandroid_runtime.so (???)
art/runtime/check_jni.cc:65]   native: #09 pc 000760c5  /system/lib/libandroid_runtime.so (android::NativeDisplayEventReceiver::dispatchVsync(long long, int, unsigned int)+40)
native: #10 pc 0007628d  /system/lib/libandroid_runtime.so (android::NativeDisplayEventReceiver::handleEvent(int, int, void*)+80)
native: #11 pc 00012545  /system/lib/libutils.so (android::Looper::pollInner(int)+484)
native: #12 pc 000125ed  /system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+92)
native: #13 pc 00081709  /system/lib/libandroid_runtime.so (android::NativeMessageQueue::pollOnce(_JNIEnv*, int)+22)
native: #14 pc 000b3863  /data/dalvik-cache/arm/system@framework@boot.oat (Java_android_os_MessageQueue_nativePollOnce__JI+102)
at android.os.MessageQueue.nativePollOnce(Native method)
at android.os.MessageQueue.next(MessageQueue.java:143)
at android.os.Looper.loop(Looper.java:122)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke!(Native method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Fatal signal 11 (SIGSEGV), code 1, fault addr 0xfffffff0 in tid 6497 

Android Solutions


Solution 1 - Android

The accepted answer to the second question you linked discusses the reason this happens: the size limit is on the entire prerendered target Activity, not just the transitioned element(s). Adding android:transitionGroup="true" to the appropriate place in the transitioned layout will fix the crash. You didn't post your layout in the question so it's hard to know where that would go, but if you have a ScrollView or other very long view that would be a good place to start.

For API levels before 21, this is a non-issue. AppCompat.startActivity() will work on API levels below 21, but the shared element transition animation will not run. It will fall back to the default activity transition.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionroyBView Question on Stackoverflow
Solution 1 - AndroidJarett MillardView Answer on Stackoverflow