A veces, este error puede ocurrir sin una llamada explícita a startActivity(...)
. Por ejemplo, algunos de ustedes pueden haber visto un rastro de pila como este en Crashlytics:
Fatal Exception: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:1597)
at android.app.ContextImpl.startActivity(ContextImpl.java:1584)
at android.content.ContextWrapper.startActivity(ContextWrapper.java:337)
at android.text.style.URLSpan.onClick(URLSpan.java:62)
at android.text.method.LinkMovementMethod.onTouchEvent(LinkMovementMethod.java:217)
at android.widget.TextView.onTouchEvent(TextView.java:9522)
at android.view.View.dispatchTouchEvent(View.java:8968)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.widget.AbsListView.dispatchTouchEvent(AbsListView.java:5303)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2559)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1767)
at android.app.Activity.dispatchTouchEvent(Activity.java:2866)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:67)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:67)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2520)
at android.view.View.dispatchPointerEvent(View.java:9173)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4706)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4544)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4201)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4095)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4258)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4095)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6564)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6454)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6425)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6654)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce(MessageQueue.java)
at android.os.MessageQueue.next(MessageQueue.java:143)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:5942)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
Y es posible que se pregunte qué hizo mal, ya que la traza solo incluye código de marco. Bueno, aquí hay un ejemplo de cómo puede suceder esto. Digamos que estamos en un fragmento.
Activity activity = getActivity();
Context activityContext = activity;
Context appContext = activityContext.getApplicationContext();
LayoutInflater inflater = LayoutInflater.from(appContext); // whoops!
View view = inflater.inflate(R.layout.some_layout, parent, false);
TextView tvWithLinks = (TextView) view.findViewById(R.id.tv_with_links);
tvWithLinks.setMovementMethod(LinkMovementMethod.getInstance()); // whoops!!
Ahora, cuando un usuario hace clic en esa vista de texto, su aplicación se bloqueará con el seguimiento de la pila anterior. Esto se debe a que el inflador de diseño tiene una referencia al contexto de la aplicación y, por lo tanto, su vista de texto tiene un contexto de aplicación. Al hacer clic en esa vista de texto, las llamadas están implícitamenteappContext.startActivity(...)
.
Nota final: probé esto en dispositivos Android 4, 5, 6 y 7. Solo afecta a 4, 5 y 6. Aparentemente, los dispositivos Android 7 no tienen problemas para llamar appContext.startActivity(...)
.
¡Espero que esto ayude a alguien más!