我在我的Android应用程序中实现了一个ListView。我使用ArrayAdapter类的自定义子类绑定到这个ListView。在重写的ArrayAdapter.getView(...)方法中,我分配一个OnClickListener。在OnClickListener的onClick方法中,我想启动一个新的活动。我得到例外:
Calling startActivity() from outside of an Activity context requires the
FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
我怎样才能得到EDOCX1(当前的Activity)正在使用的Context?
我认为亚历克斯的回答应该是对你的问题的"公认"的解决方案,因为它以更一般的方式纠正了你提到的错误。
我喜欢"这真的是你想要的吗?"…我之前收到过一条消息:"你确定你没有忘记在某个地方注销广播接收器吗?"令人惊叹的!向那些把这些小信息放进去帮助我们的人致敬。
我遇到了这个问题。当我将TargetsDkversion更新为28时。
要么
通过适配器中的构造函数缓存上下文对象,或者
从你的角度来看。
或者作为最后的手段,
将-flag_activity_new_task标志添加到您的意图中:
γ
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
编辑-我将避免设置标志,因为它会干扰事件和历史堆栈的正常流。
在我无法控制系统创建的意图(以及标志)的textview中,自动链接功能如何?
当我做这种事情的时候,我得到了这个例外,我刚把context从ApplicationContext改为Activity型。这解决了问题。
@Alexsemeniuk有没有找到解决方案?
我想必须实现自定义ClickableSpan,我想…
这个很好
@只要将活动作为上下文传递给适配器,自动链接就可以工作。
我通过构造函数传递了上下文对象,但它不起作用。但是旗号活动新任务对我来说非常有效,谢谢。
爱你的答案@sufian
从view.getContext()这样的视角获取上下文对我来说很有用!
完美的回答拯救我的一天,谢谢:)
getApplicationContext()对我不起作用,但使用this起作用。
你可以用addflags而不是setFlags来实现它。
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
根据文件,它可以:
Add additional flags to the intent (or with existing flags value).
编辑
请注意,如果您使用的标志更改了历史堆栈,正如Alex Volovoy的回答所说:
...avoid setting flags as it will interfere with normal flow of event and history stack.
我有一个非常相似的问题。您是否遇到过历史堆栈的任何问题,或者作为以上建议的答案,遇到过其他问题?
我不确定你在寻找什么,但你可以在没有类似历史记录的情况下开始一项活动:意向=新意向(intent.action_view,"http:\www.google.com");意向.addflags(intent.flag_activi‌&8203;ty_no_history);启动活动(intent);
谢谢您。我也在做同样的事情。
为什么不建议在此处添加标志?干扰事件和历史堆栈的正常流有多重要?
@jasonkrs你可以使用addflags。请注意,您可以根据添加的标志更改历史堆栈。在这种情况下,可以使用标记活动新任务。有关更多详细信息,请阅读:developer.android.com/reference/android/content/…
不使用(getApplicationContext),使用YourActivity.this。
对我来说,这是最好的解决办法
工作得很有魅力!
你就是那个人!
这对我很有用,谢谢。
谢谢!没有你的建议很难搞清楚出了什么问题。
你能举个代码例子吗?
欢迎大家:
这是更好的解决方案
如果由于使用如下创建选择器而出错:
Intent sharingIntent = new Intent(Intent.ACTION_VIEW);
sharingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sharingIntent.setData(Uri.parse("http://google.com"));
startActivity(Intent.createChooser(sharingIntent,"Open With"));
设置如下创建选择器的标志:
Intent sharingIntent = new Intent(Intent.ACTION_VIEW);
sharingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sharingIntent.setData(Uri.parse("http://google.com"));
Intent chooserIntent = Intent.createChooser(sharingIntent,"Open With");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(chooserIntent);
完美的解决方案
它非常有用。确切地说,选择者意图应该有这个标志!
这是正确的解释,也正是必须要做的,意图中的新任务。
你应该得到一枚金牌
我认为您可能在错误的地方实现OnClickListener—通常您应该在活动中明确地实现OnTiceClickListener,并将其设置在ListView上,否则您的事件会出现问题…
你引导我找到解决办法。我需要使用一个分配给ListView的OnItemClickListener。以下是其他人的一些链接:developer.android.com/reference/android/widget/…androidpeople.com/…谢谢您的帮助。
请提供一般答案。AlexVolovoy下面的答案以通用的方式解决了这个问题。
对于后代:如果在组件上直接将其定义为setlistener(new listener),则需要一个上下文,您将创建对整个活动的隐式引用,这将像您不相信的那样泄漏内存。如果需要能够处理来自多个来源的输入,可以通过创建静态的内部类侦听器或将侦听器移动到单独的类来规避这一点。
另外:如果在片段中的ListView中显示链接,则不要这样创建链接。
adapter = new ListAdapter(getActivity().getApplicationContext(),mStrings);
代替呼叫
adapter = new ListAdapter(getActivity(),mStrings);
适配器在这两种情况下都可以正常工作,但链接只能在最后一种情况下工作。
@用户2676468:这为我解决了自动链接问题。
这应该是一个可接受的答案,而不是使用标志,这更好!!
CustomAdapter mAdapter = new CustomAdapter( getApplicationContext(), yourlist);
或
Context mContext = getAppliactionContext();
CustomAdapter mAdapter = new CustomAdapter( mContext, yourlist);
改变到下面
CustomAdapter mAdapter = new CustomAdapter( this, yourlist);
看,如果您在某个方法的listiner中创建了一个意图
override onClick (View v).
然后通过这个视图调用上下文:
v.getContext ()
甚至不需要设置标志…
对于任何在xamarin.android(monodroid)上获取此信息的人,即使从activity调用startactivity-这实际上是带有新艺术运行时的xamarin bug,请参见https://bugzilla.xamarin.com/show_bug.cgi?ID=17630
当StartActivity不知道哪个是他的活动时,就会出现此错误。因此,必须在StartActivity()之前添加Activity。
你必须设置
activity.startActivity(yourIntent);
我也有同样的问题。问题在于上下文。如果要打开任何链接(例如通过选择器共享任何链接),请传递活动上下文,而不是应用程序上下文。
如果您不在活动中,请不要忘记添加myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)。
在我看来,最好只在你的Activity.class代码中使用startActivity()的方法。如果在Adapter或其他类中使用它,将导致这种情况。
进一步阐述亚历克斯·沃洛维的回答-
如果您遇到碎片问题,getActivity()可以很好地获取上下文
在其他情况下:
如果你不想使用-
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//not recommend
然后在你的局外人类中做一个这样的函数-
public void gettingContext(Context context){
real_context = context;//where real_context is a global variable of type Context
}
现在,在您的主活动中,当您创建一个新的OutsideClass时,在定义了将活动的上下文作为参数的OutsideClass之后,立即调用上面的方法。也在你的主要活动中发挥作用-
public void startNewActivity(final String activity_to_start) {
if(activity_to_start.equals("ACTIVITY_KEY"));
//ACTIVITY_KEY-is a custom key,just to
//differentiate different activities
Intent i = new Intent(MainActivity.this, ActivityToStartName.class);
activity_context.startActivity(i);
}//you can make a if-else ladder or use switch-case
现在回到你的局外人的课堂上,开始新的活动,像这样做。-
@Override
public void onClick(View v) {
........
case R.id.any_button:
MainActivity mainAct = (MainActivity) real_context;
mainAct.startNewActivity("ACTIVITY_KEY");
break;
}
........
}
这样,您就可以从不同的OutsideClass启动不同的活动,而不会弄乱标志。
注意:不要通过片段的构造函数缓存上下文对象(使用适配器,它很好)。片段应该有一个空的构造函数,否则在某些情况下应用程序会崩溃。
记得打电话
OutsideClass.gettingContext(Context context);
在onresume()函数中。
我也有同样的问题。检查您传递的所有上下文。对于"链接",它需要活动上下文而不是应用程序上下文。
这是您应该检查的地方:
1.)如果您使用了布局膨胀器,那么请检查您已通过的上下文。
2.)如果您使用任何适配器,请检查您传递的上下文。
在适配器活动中使用此代码,并使用context.startActivity(intent_Object)和intent_Object.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);。
这样地:
Intent n_act = new Intent(context, N_Activity.class);
n_act.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(n_act);
它起作用了…
面临同样的问题,然后实施
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
解决了这个问题。
可能还有另一个与列表视图适配器相关的原因。你可以看到这个博客,描述得很好。
有帮助的博客,谢谢。:)
不客气
使用此代码。对我来说很好。从活动外部共享内容:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
// Append Text
String Text ="Your Text Here"
intent.putExtra(Intent.EXTRA_TEXT, Text);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Intent shareIntent = Intent.createChooser(intent,"Share . . .");
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
G.context.getApplicationContext().startActivity(shareIntent);
设置标志会破坏stacktrace历史记录
Intent viewIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(viewIntent);
我希望这能奏效。
Intent i= new Intent(context, NextActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
如果您在cordova插件中调用share intent,那么设置该标志将没有帮助。而是用这个-
cordova.getActivity().startActivity(Intent.createChooser(shareIntent,"title"));
我的情况有点不同,我正在使用Espresso测试我的应用程序,我必须从仪器Context启动我的ActivityTestRule活动(不是来自Activity)。
fun intent(context: Context) =
Intent(context, HomeActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
我必须改变标志,并在EDOCX1×6中添加一个EDOCX1×4位(EDCOX1,5,爪哇)。
因此,结果是:
fun intent(context: Context) =
Intent(context, HomeActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
由于添加标志会影响event_flow和stack_history,因此最好将"应用程序上下文"传递给非活动,从该活动中需要按以下方式调用活动类:
"activityclassname.this"(以这种方式传递上下文时,它将包含从非活动方案调用活动所需的所有详细信息和信息)
所以不需要设置或添加标志,这在任何情况下都可以正常工作。