com.leanplum.actions.internal.ActionDefinition.getName() - NullPointerException
michalkierasinski opened this issue · 6 comments
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.leanplum.actions.internal.ActionDefinition.getName()' on a null object reference
at com.leanplum.actions.internal.ActionManagerDefinitionKt.defineAction(ActionManagerDefinition.kt:87)
at com.leanplum.messagetemplates.MessageTemplates.register(MessageTemplates.java:123)
at com.leanplum.messagetemplates.MessageTemplates.registerTemplate(MessageTemplates.java:82)
Expected Behavior
The application is not crashing
Actual Behavior
Application is crashing
Steps to Reproduce the Problem
- Open the application with some custom action
Specifications
- Version: 6.0.0
- Platform: Android
- Subsystem:
Probably connected with:
Fatal Exception: java.util.ConcurrentModificationException:
at java.util.ArrayList$Itr.next(ArrayList.java:860)
at com.leanplum.actions.internal.ActionManagerDefinitionKt.defineAction(ActionManagerDefinition.kt:130)
at com.leanplum.messagetemplates.MessageTemplates.register(MessageTemplates.java:123)
at com.leanplum.messagetemplates.MessageTemplates.registerTemplate(MessageTemplates.java:82)
@michalkierasinski
Can you share your custom action definition and which thread executes it?
I would suggest using the UI thread when registering the actions to avoid such issues. The action queue mechanism is triggered on the UI thread, which probably is the cause of the crash. The heavy network operations are executed in a background threads.
class OpenAction @Inject constructor() : MessageTemplate {
override fun getName() = ACTION_NAME
override fun createActionArgs(context: Context): ActionArgs = ActionArgs().with(URL, "")
override fun present(actionContext: ActionContext): Boolean {
val url: String = actionContext.stringNamed(URL)
if (!deepLinkManager.isLinkSupported(url)) {
Timber.e("Deep Link is not supported")
return false
}
// TODO: Open deep link
actionContext.actionDismissed()
return true
}
override fun dismiss(context: ActionContext): Boolean = true
private companion object {
const val ACTION_NAME = "Action Name"
const val URL = "URL"
}
}
Actions are registered on a different thread than UI.
Thanks, I will rise a bug about that, meanwhile could you use the UI thread when registering them. The registration is a light operation, that doesn't involve any network requests, and wouldn't freeze the UI thread.
Ok, thanks. Please fix it or update the documentation.
@michalkierasinski
Fixed in #534 and will be included in next release.
Thank you for your feedback!