从Activity外部调用startActivity()?

我正在使用AlarmManager来触发广播信号的意图。 以下是我的代码:

 AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent i = new Intent(this, Wakeup.class); try { PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); Long elapsed += // sleep time; mgr.set(AlarmManager.RTC_WAKEUP, elapsed, pi); } catch(Exception r) { Log.v(TAG, "RunTimeException: " + r); } 

我从一个Activity调用这个代码,所以我不知道我怎么会得到以下错误…

 ERROR/AndroidRuntime(7557): java.lang.RuntimeException: Unable to start receiver com.wcc.Wakeup: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? 

如果你添加这行:

 ... Intent i = new Intent(this, Wakeup.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ... 

对于同一活动的多个实例,请使用以下片段,

注意 :这个片段,我在我的Activity之外使用。 确保你的AndroidManifest文件不包含android:launchMode="singleTop|singleInstance" 。 如果需要,可以将其更改为android:launchMode="standard"

 Intent i = new Intent().setClass(mActivity.getApplication(), TestUserProfileScreenActivity.class); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); // Launch the new activity and add the additional flags to the intent mActivity.getApplication().startActivity(i); 

这对我来说很好。 希望,这节省了一些人的时间。 如果有人find更好的方法,请与我们分享。

你没有粘贴你调用startActivity的部分,这是有趣的部分。

您可能正在Service上下文或Application上下文中调用startActivity

在进行startActivity调用之前打印“this”来loggingcat,看看它是指什么,有时候偶然会使用一个内部的“this”。

有时候,如果没有明确地调用startActivity(...)就会发生这个错误。 例如,你们中的一些人可能在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) 

你可能想知道你做错了什么,因为跟踪只包含框架代码。 那么,这是一个如何发生的例子。 比方说,我们在一个片段。

 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!! 

现在,当用户点击该文本视图时,您的应用程序将崩溃,上面的堆栈跟踪。 这是因为布局inflater有一个对应用程序上下文的引用,所以你的文本视图有一个应用程序上下文。 点击该文本视图隐式调用appContext.startActivity(...)

最后说明:我在Android 4,5,6和7设备上testing了这一点。 它只影响4,5和appContext.startActivity(...) 7设备显然没有麻烦调用appContext.startActivity(...)

我希望这可以帮助别人!

尝试改变这一行:

 PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 0, i, 0); 

当你想在你的应用程序中打开一个活动,那么你可以用一个Intent作为参数来调用startActivity()方法。 那个意图就是你想要打开的活动。 首先,您必须创build一个具有第一个参数的意图对象作为上下文,第二个参数作为目标活动类。

 Intent intent = new Intent(this, Activity_a.class); startActivity(intent); 

希望这会有所帮助。