JNI Error on Scene Transition Animation - Layer exceeds max
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:
in
FragmentB
mView
position is calculated dynamically usingViewTreeObserver.OnGlobalLayoutListener
mView
extendsImageView
in order to create Oval effect in both of the Fragments.- the root
ViewGroup
is aScrollView
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:
- Why i'm even getting
LayerExceeds max
error? my sharedView
is no bigger than 1080x1080. - how can i handle this kind of error on API < 21 where both
TransitionListener
andtransitionGroup
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@[email protected] (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
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.