AdaptySDK-React-Native
AdaptySDK-React-Native copied to clipboard
Functionalities not working in release mode
Description
Hi, We can subscribe to products and see paywalls in debug mode, But when we are on release mode the paywalls and functionalities are not working.
It gives the following error.
{"adaptyCode": 2006, "localized Description": "Failed to decode native...}
I have added the following configurations in proguard as well. But it doesn't seem to help
-keep class com.adapty.** { *; }
Adapty versions
"@adapty/react-native-ui": "^2.0.0",
"react-native-adapty": "^2.7.0"
Version
2.7.0
What platforms are you seeing the problem on?
Android
System info
System:
OS: macOS 14.1.1
CPU: (8) x64 Apple M1
Memory: 267.18 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.12.1 - /usr/local/bin/node
Yarn: 1.22.10 - /usr/local/bin/yarn
npm: 9.6.6 - /usr/local/bin/npm
Watchman: 2023.05.22.00 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.13.0 - /Users/ttn/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms: DriverKit 23.2, iOS 17.2, macOS 14.2, tvOS 17.2, watchOS 10.2
Android SDK: Not Found
IDEs:
Android Studio: 2022.3 AI-223.8836.35.2231.11090377
Xcode: 15.1/15C65 - /usr/bin/xcodebuild
Languages:
Java: 14.0.2 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.2.0 => 18.2.0
react-native: ^0.71.4 => 0.71.4
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
hi @ttnisal, I believe it's an obfuscation issue as well, could you please try adding the rules from here?
Hi @vladd-g I have pasted the whole code from that file to my proguard-rules.pro file. But it still has this issue.
This is the full error.
{"adaptyCode":2006,"localized Description":"Failed to decode native response. JSON.parse raised an error: JSON Parse error: Unexpected token: C"}
@ttnisal could you please also add some Adapty verbose logs around the error?
but anyway, it totally looks like an obfuscation problem, not the SDK bug
Hi @vladd-g ,
Here are the verbose logs
[21:43:48] D | ReactNativeJS ▶︎ '[2024-01-06T04:43:48.131Z] [[email protected]] "setLogLevel": <HOLD> Calling method', {}
[21:43:48] D | ReactNativeJS ▶︎ '[2024-01-06T04:43:48.267Z] [[email protected]] "parse": Decoding string...', { input: '{"data":{},"type":"null"}' }
│ '[2024-01-06T04:43:48.268Z] [[email protected]] "fetch/activate": Calling bridge function: OK', { response: '{"data":{},"type":"null"}' }
│ '[2024-01-06T04:43:48.269Z] [[email protected]] "activate": Calling method: OK', undefined
│ '[2024-01-06T04:43:48.269Z] [[email protected]] "setLogLevel": <UNLOCKED> Calling method', {}
└ '[2024-01-06T04:43:48.270Z] [[email protected]] "fetch/set_log_level": Calling bridge function...', { method: 'set_log_level', params: {} }
[21:43:48] D | ReactNativeJS ▶︎ '[2024-01-06T04:43:48.383Z] [[email protected]] "parse": Decoding string...', { input: '{"data":{},"type":"null"}' }
└ '[2024-01-06T04:43:48.383Z] [[email protected]] "fetch/set_log_level": Calling bridge function: OK', { response: '{"data":{},"type":"null"}' }
[21:43:48] D | ReactNativeJS ▶︎ '[2024-01-06T04:43:48.383Z] [[email protected]] "setLogLevel": Calling method: OK', undefined
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.254Z] [[email protected]] "getProfile": Calling method...', {}
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.256Z] [[email protected]] "fetch/get_profile": Calling bridge function...', { method: 'get_profile', params: {} }
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.424Z] [[email protected]] "parse": Decoding string...', { input: '{"data":{"paid_access_levels":{"premium":{"activated_at":"2024-01-05T18:10:01.305000+0000","cancellation_reason":"unknown","expires_at":"2024-01-05T18:44:43.497000+0000","id":"premium","is_active":false,"is_in_grace_period":false,"is_lifetime":false,"is_refund":false,"renewed_at":"2024-01-05T18:39:41.130000+0000","store":"play_store","unsubscribed_at":"2024-01-05T18:44:43.497000+0000","vendor_product_id":"my_doc_said_subscription_group:p1m","will_renew":false}},"custom_attributes":{},"non_subscriptions":{},"profile_id":"2b212ad5-2f96-4d80-b082-a68e10bb1c0d","subscriptions":{"my_doc_said_subscription_group:p1m":{"activated_at":"2024-01-05T18:10:01.305000+0000","cancellation_reason":"unknown","expires_at":"2024-01-05T18:44:43.497000+0000","is_active":false,"is_in_grace_period":false,"is_lifetime":false,"is_refund":false,"is_sandbox":true,"renewed_at":"2024-01-05T18:39:41.130000+0000","store":"play_store","unsubscribed_at":"2024-01-05T18:44:43.497000+0000","vendor_original_transaction_id":"GPA.3314-XXXX-5429-XXXXX","vendor_product_id":"my_doc_said_subscription_group:p1m","vendor_transaction_id":"GPA.3314-XXXX-5429-XXXXX..5","will_renew":false}}},"type":"AdaptyProfile"}' }
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.425Z] [[email protected]] "fetch/get_profile": Calling bridge function: OK', { response: '{"data":{"paid_access_levels":{"premium":{"activated_at":"2024-01-05T18:10:01.305000+0000","cancellation_reason":"unknown","expires_at":"2024-01-05T18:44:43.497000+0000","id":"premium","is_active":false,"is_in_grace_period":false,"is_lifetime":false,"is_refund":false,"renewed_at":"2024-01-05T18:39:41.130000+0000","store":"play_store","unsubscribed_at":"2024-01-05T18:44:43.497000+0000","vendor_product_id":"my_doc_said_subscription_group:p1m","will_renew":false}},"custom_attributes":{},"non_subscriptions":{},"profile_id":"2b212ad5-2f96-4d80-b082-a68e10bb1c0d","subscriptions":{"my_doc_said_subscription_group:p1m":{"activated_at":"2024-01-05T18:10:01.305000+0000","cancellation_reason":"unknown","expires_at":"2024-01-05T18:44:43.497000+0000","is_active":false,"is_in_grace_period":false,"is_lifetime":false,"is_refund":false,"is_sandbox":true,"renewed_at":"2024-01-05T18:39:41.130000+0000","store":"play_store","unsubscribed_at":"2024-01-05T18:44:43.497000+0000","vendor_original_transaction_id":"GPA.3314-XXXX-5429-XXXXX","vendor_product_id":"my_doc_said_subscription_group:p1m","vendor_transaction_id":"GPA.3314-XXXX-5429-XXXXX..5","will_renew":false}}},"type":"AdaptyProfile"}' }
│ '[2024-01-06T04:45:00.425Z] [[email protected]] "getProfile": Calling method: OK', { accessLevels:
│ { premium:
│ { activatedAt: Fri Jan 05 2024 11:10:01 GMT-0700,
│ cancellationReason: 'unknown',
│ expiresAt: Fri Jan 05 2024 11:44:43 GMT-0700,
│ id: 'premium',
│ isActive: false,
│ isInGracePeriod: false,
│ isLifetime: false,
│ isRefund: false,
│ renewedAt: Fri Jan 05 2024 11:39:41 GMT-0700,
│ store: 'play_store',
│ unsubscribedAt: Fri Jan 05 2024 11:44:43 GMT-0700,
│ vendorProductId: 'my_doc_said_subscription_group:p1m',
│ willRenew: false,
│ android: {} } },
│ customAttributes: {},
│ nonSubscriptions: {},
│ profileId: '2b212ad5-2f96-4d80-b082-a68e10bb1c0d',
│ subscriptions:
│ { 'my_doc_said_subscription_group:p1m':
│ { isActive: false,
│ isLifetime: false,
│ vendorProductId: 'my_doc_said_subscription_group:p1m',
│ store: 'play_store',
│ vendorTransactionId: 'GPA.3314-XXXX-5429-XXXXX..5',
│ vendorOriginalTransactionId: 'GPA.3314-XXXX-5429-XXXXX',
│ activatedAt: Fri Jan 05 2024 11:10:01 GMT-0700,
│ willRenew: false,
│ isInGracePeriod: false,
│ isRefund: false,
│ isSandbox: true,
│ renewedAt: Fri Jan 05 2024 11:39:41 GMT-0700,
│ expiresAt: Fri Jan 05 2024 11:44:43 GMT-0700,
│ unsubscribedAt: Fri Jan 05 2024 11:44:43 GMT-0700,
│ cancellationReason: 'unknown' } } }
│ '[2024-01-06T04:45:00.426Z] [[email protected]] "getPaywall": Calling method...', { id: 'home_placement', locale: undefined }
└ '[2024-01-06T04:45:00.426Z] [[email protected]] "fetch/get_paywall": Calling bridge function...', { method: 'get_paywall', params: {} }
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.579Z] [[email protected]] "parse": Decoding string...', { input: '{"data":{"ab_test_name":"Monthly Subscription Paywall","use_paywall_builder":true,"developer_id":"home_placement","paywall_name":"Monthly Subscription Paywall","products":[{"timestamp":1704516302862,"vendor_product_id":"my_doc_said_subscription_group","base_plan_id":"p1m"}],"revision":1,"paywall_updated_at":1702450412899,"variation_id":"7d1a157a-2ea1-44e7-83f3-b157d84cc4d8","remote_config":{"lang":"en"}},"type":"AdaptyPaywall"}' }
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.580Z] [[email protected]] "fetch/get_paywall": Calling bridge function: OK', { response: '{"data":{"ab_test_name":"Monthly Subscription Paywall","use_paywall_builder":true,"developer_id":"home_placement","paywall_name":"Monthly Subscription Paywall","products":[{"timestamp":1704516302862,"vendor_product_id":"my_doc_said_subscription_group","base_plan_id":"p1m"}],"revision":1,"paywall_updated_at":1702450412899,"variation_id":"7d1a157a-2ea1-44e7-83f3-b157d84cc4d8","remote_config":{"lang":"en"}},"type":"AdaptyPaywall"}' }
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.580Z] [[email protected]] "getPaywall": Calling method: OK', { abTestName: 'Monthly Subscription Paywall',
│ hasViewConfiguration: true,
│ id: 'home_placement',
│ locale: 'en',
│ name: 'Monthly Subscription Paywall',
│ products:
│ [ { vendorId: 'my_doc_said_subscription_group',
│ ios: {},
│ android: { basePlanId: 'p1m' } } ],
│ revision: 1,
│ variationId: '7d1a157a-2ea1-44e7-83f3-b157d84cc4d8',
└ version: 1702450412899 }
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.581Z] [[email protected]] "createController": Calling method...', { paywall:
│ { abTestName: 'Monthly Subscription Paywall',
│ hasViewConfiguration: true,
│ id: 'home_placement',
│ locale: 'en',
│ name: 'Monthly Subscription Paywall',
│ products:
│ [ { vendorId: 'my_doc_said_subscription_group',
│ ios: {},
│ android: { basePlanId: 'p1m' } } ],
│ revision: 1,
│ variationId: '7d1a157a-2ea1-44e7-83f3-b157d84cc4d8',
│ version: 1702450412899 },
└ params: {} }
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.582Z] [[email protected]] "fetch/create_view": Calling bridge function...', { method: 'create_view', params: {} }
[21:45:00] I | ReactNativeJS ▶︎ synchronized data
[21:45:00] I | ReactNativeJS ▶︎ 'updateFCMToken', { message: 'Tasks completed successfully' }
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.742Z] [[email protected]] "parse": Decoding string...', { input: '{"a":"abe22e1e-77f9-468b-bc40-4783032b673d","b":"String","c":""}' }
└ '[2024-01-06T04:45:00.742Z] [[email protected]] "fetch/create_view": Calling bridge function: OK', { error: [TypeError: Cannot create property '__stack__' on string '#2006 (decodingFailed): Failed to decode native response. Response does not have expected "type" property'] }
[21:45:00] D | ReactNativeJS ▶︎ '[2024-01-06T04:45:00.742Z] [[email protected]] "createController": Calling method: OK', { error:
│ { [Error: #2006 (decodingFailed): Failed to decode native response. JSON.parse raised an error: JSON Parse error: Unexpected token: C]
│ adaptyCode: 2006,
│ localizedDescription: 'Failed to decode native response. JSON.parse raised an error: JSON Parse error: Unexpected token: C',
└ detail: undefined } }
[21:45:00] I | ReactNativeJS ▶︎ 'adapty paywall error', { [Error: #2006 (decodingFailed): Failed to decode native response. JSON.parse raised an error: JSON Parse error: Unexpected token: C]
│ adaptyCode: 2006,
│ localizedDescription: 'Failed to decode native response. JSON.parse raised an error: JSON Parse error: Unexpected token: C',
└ detail: undefined }
Hi @ttnisal,
do you have something like proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
on the same level as minifyEnabled true
?
Hi @vladd-g , yes I have like this
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
@ttnisal are those proguard rules above in the right proguard-rules.pro
file? it should be on the same level as the build.gradle
file that contains the lines from the above comment
Hi @vladd-g , I didn't quite get what you meant as same level.
All the proguard rules mentioned here was place inside the proguard-rules.pro
file in the android/app
folder.
And in the build.gradle
, the configs are placed in the same buildType
like below
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
Could you explain a little bit more? Thanks
@ttnisal by "same level" I meant same level in the project hierarchy, that would mean that you've chosen the right proguard-rules.pro
'{"a":"abe22e1e-77f9-468b-bc40-4783032b673d","b":"String","c":""}'
shows that this model have been obfuscated, but I wonder why as the relevant proguard rules have been added
Hi @vladd-g, yes they are on the same level in the project hierarchy. Are there any other library that can cause the obfuscation?
Hi @vladd-g , by any chance does the package @adapty/react-native-ui
need any proguard rules?
Hi @ttnisal
Are there any other library that can cause the obfuscation?
I think no, it looks like only these two.
does the package @adapty/react-native-ui need any proguard rules
Again, it doesn’t look so, as the json from your snippet is from a model that shares the same package com.adapty
as in the proguard rule.
Can you perform Build -> Analyze APK in Android Studio to inspect what exactly got obfuscated?
Hi @vladd-g, I have analysed the APK in release mode. I think as the following image the adapty and gson classes are not obfuscated.
However the other source code seems to be obfuscated.
Do you have any thoughts on this?
@ttnisal could you please expand com/adapty/internal/crossplatform/ui? this is the package of that model from json you provided with obfuscated keys
@vladd-g, This is the expanded view for the package.
But I can see something like this
@ttnisal suppose AdaptyUiView
is not obfuscated, right?
HI @vladd-g, seems like it's not
@ttnisal can you also try adding this?
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
Hi @vladd-g , No luck in adding that also.
To make sure the proguard-rules.pro file is working fine. I have added the following config to exclude all classes from being obfuscated. And it opens up the paywall.
-keep class ** { *; }
@ttnisal could you please send the obfuscated apk to [email protected]? Please also add the link to the issue in your email so that we know the context
Hi @vladd-g, I have sent the email.
Thanks
@ttnisal thanks!
Hey. I have the same issue on android react native project.
I noted the conversation went into email, any update on this for someone who is facing the same issues ? @vladd-g @ttnisal
Thank you in advance.
@HermenegildoMI investigating
@ttnisal @HermenegildoMI could you please also add the following line to the config? -keep class io.adapty.** { *; }
Hi @vladd-g . Thank you for the prompt response.
I added -keep class io.adapty.** { *; }
and got a new error in release mode.
When opening a Paywall view, the app crashes with the following logs:
In code:
const paywall = await adapty.getPaywall(paywallId);
if(paywall.hasViewConfiguration){
viewController = await createPaywallView(paywall);
await viewController.present();
}
Adapty Logs before crashing:
Note: actual id's were removed
'[AdapterPaywall]: ', { abTestName: 'Android Test Paywall',
hasViewConfiguration: true,
id: 'default-settings',
locale: 'en',
name: 'Android Test Paywall',
products:
[ { vendorId: '<insert valid id>',
ios: {},
android: { basePlanId: 'p3m', offerId: 'freetrial' } } ],
revision: 1,
variationId: '<insert valid id>',
version: 1704953916220 }
2024-01-15 20:23:19.665 26807-26909 ReactNativeJS pid-26807 D '[2024-01-15T20:23:19.663Z] [[email protected]] "createController": Calling method...', { paywall:
{ abTestName: 'Android Test Paywall',
hasViewConfiguration: true,
id: 'default-settings',
locale: 'en',
name: 'Android Test Paywall',
products:
[ { vendorId: '<insert valid id>',
ios: {},
android: { basePlanId: 'p3m', offerId: 'freetrial' } } ],
revision: 1,
variationId: '<insert id>',
version: 1704953916220 },
params: {} }
'[2024-01-15T20:23:19.670Z] [[email protected]] "fetch/create_view": Calling bridge function...', { method: 'create_view', params: {} }
2024-01-15 20:23:20.635 26807-26909 ReactNativeJS pid-26807 D '[2024-01-15T20:23:20.634Z] [[email protected]] "parse": Decoding string...', { input: '{"data":"19a6fcf4-b0da-4c59-8168-8e2a91fdea8c","type":"String","view":""}' }
2024-01-15 20:23:20.636 26807-26909 ReactNativeJS pid-26807 D '[2024-01-15T20:23:20.635Z] [[email protected]] "fetch/create_view": Calling bridge function: OK', { response: '{"data":"19a6fcf4-b0da-4c59-8168-8e2a91fdea8c","type":"String","view":""}' }
2024-01-15 20:23:20.637 26807-26909 ReactNativeJS pid-26807 D '[2024-01-15T20:23:20.637Z] [[email protected]] "createController": Calling method: OK', '19a6fcf4-b0da-4c59-8168-8e2a91fdea8c'
2024-01-15 20:23:20.643 26807-26909 ReactNativeJS pid-26807 D '[2024-01-15T20:23:20.639Z] [[email protected]] "registerEventHandlers": Calling method...', { _id: '19a6fcf4-b0da-4c59-8168-8e2a91fdea8c' }
2024-01-15 20:23:20.655 26807-26909 ReactNativeJS pid-26807 D '[2024-01-15T20:23:20.653Z] [[email protected]] "present": Calling method...', { _id: '19a6fcf4-b0da-4c59-8168-8e2a91fdea8c' }
2024-01-15 20:23:20.657 26807-26909 ReactNativeJS pid-26807 D '[2024-01-15T20:23:20.656Z] [[email protected]] "fetch/present_view": Calling bridge function...', { method: 'present_view', params: {} }
2024-01-15 20:23:20.722 26807-26909 ReactNativeJS pid-26807 D '[2024-01-15T20:23:20.722Z] [[email protected]] "parse": Decoding string...', { input: '{"data":{},"type":"null","view":"19a6fcf4-b0da-4c59-8168-8e2a91fdea8c"}' }
2024-01-15 20:23:20.723 26807-26909 ReactNativeJS pid-26807 D '[2024-01-15T20:23:20.722Z] [[email protected]] "fetch/present_view": Calling bridge function: OK', { response: '{"data":{},"type":"null","view":"19a6fcf4-b0da-4c59-8168-8e2a91fdea8c"}' }
2024-01-15 20:23:20.723 26807-26909 ReactNativeJS pid-26807 D '[2024-01-15T20:23:20.723Z] [[email protected]] "present": Calling method: OK', undefined
App Crash Error:
java.lang.NoSuchMethodError • AdaptyUiActivityNo static method create(Landroid/content/Context;Landroid/graphics/Typeface;IZ)Landroid/graphics/Typeface; in class Lc/h/f/d; or its super classes (declaration of 'c.h.f.d' appears in base.apk)
--
I got this weird issue where I only get the paywall pop up only in the first time I open up the app. If I close the app and open it I won't get it. I'm getting it only after reinstalling the app. This is on debug mode btw
@ttnisal working on it
@HermenegildoMI could you please provide full stacktrace of the crash itself?
@HermenegildoMI could you please provide full stacktrace of the crash itself?
Here you go @vladd-g
java.lang.NoSuchMethodError: No static method create(Landroid/content/Context;Landroid/graphics/Typeface;IZ)Landroid/graphics/Typeface; in class Lc/h/f/d; or its super classes (declaration of 'c.h.f.d' appears in base.apk)
at com.adapty.ui.internal.TypefaceHolder.getOrPut(TypefaceHolder.kt:20)
at com.adapty.ui.internal.TextComponentHelper.processTextItem(TextComponentHelper.kt:251)
at com.adapty.ui.internal.TextComponentHelper.processTextComponent(TextComponentHelper.kt:78)
at com.adapty.ui.internal.TextComponentHelper.processTextComponent$default(TextComponentHelper.kt:28)
at com.adapty.ui.internal.ViewHelper.createView(ViewHelper.kt:37)
at com.adapty.ui.internal.FlatPaywallRenderer.render(PaywallRenderer.kt:575)
at com.adapty.ui.internal.PaywallUiManager.buildLayout(PaywallUiManager.kt:61)
at com.adapty.ui.internal.PaywallPresenter.showPaywall(PaywallPresenter.kt:84)
at com.adapty.ui.AdaptyPaywallView.showPaywall(AdaptyPaywallView.kt:95)
at com.adapty.internal.crossplatform.ui.AdaptyUiActivity$onCreate$1$1.invoke(AdaptyUiActivity.kt:49)
at com.adapty.internal.crossplatform.ui.AdaptyUiActivity$onCreate$1$1.invoke(AdaptyUiActivity.kt:41)
at com.adapty.internal.crossplatform.ui.AdaptyUiActivity.onReceiveSystemBarsInsets$lambda-3(AdaptyUiActivity.kt:95)
at com.adapty.internal.crossplatform.ui.AdaptyUiActivity.lambda$-prMK8seUuop9fZBuAKSnG_jMOs(AdaptyUiActivity)
at com.adapty.internal.crossplatform.ui.a.a(Unknown:4)
at androidx.core.view.ViewCompat$Api21Impl$1.onApplyWindowInsets(ViewCompat.java:4858)
at android.view.View.dispatchApplyWindowInsets(View.java:12010)
at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7715)
at android.view.ViewGroup.newDispatchApplyWindowInsets(ViewGroup.java:7740)
at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7722)
at android.view.ViewGroup.newDispatchApplyWindowInsets(ViewGroup.java:7740)
at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7722)
at android.view.ViewGroup.newDispatchApplyWindowInsets(ViewGroup.java:7740)
at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7722)
at android.view.ViewRootImpl.dispatchApplyInsets(ViewRootImpl.java:3527)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3671)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3116)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10885)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1301)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1309)
at android.view.Choreographer.doCallbacks(Choreographer.java:923)
at android.view.Choreographer.doFrame(Choreographer.java:852)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1283)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Method.java:-2)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)