从Activity上下文外部调用startActivity()

问题描述 投票:318回答:22

我在Android应用程序中实现了ListView。我使用ListView类的自定义子类绑定到此ArrayAdapter。在被覆盖的ArrayAdapter.getView(...)方法中,我指定了一个OnClickListener。在onClickOnClickListener方法中,我想发起一项新的活动。我得到了例外:

Calling startActivity() from outside of an Activity  context requires the  
FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

我怎样才能得到Context(现在的ListView)正在使用的Activity

android android-activity android-context
22个回答
519
投票

  • 通过适配器中的构造函数缓存Context对象,或
  • 从你的角度来看。

或作为最后的手段,

  • 添加 - FLAG_ACTIVITY_NEW_TASK标记到您的意图:

_

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

编辑 - 我会避免设置标志,因为它会干扰正常的事件流和历史堆栈。


3
投票

当startactivity不知道他的活动是什么时,会出现此错误。所以你必须在startActivity()之前添加活动

你必须设置

activity.startActivity(yourIntent);

2
投票

在我看来,最好在你的startActivity()代码中使用Activity.class的方法。如果你在Adapter或其他类中使用它,它将导致。


2
投票

详细阐述Alex Volovoy的答案 -

如果您通过片段获得此问题,getActivity()可以正常工作以获取上下文

在其他情况下:

如果你不想使用 -

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//not recommend

然后在你的OutsideClass中创建一个这样的函数 -

public void gettingContext(Context context){
    real_context = context;//where real_context is a global variable of type Context
}

现在,在你的主要活动中,当你定义外部类,并将活动的上下文作为参数时,你立即调用上面的方法。在你的主要活动中也有一个功能 -

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

现在回到你的OutsideClass,并开始新的活动做这样的事情 -

@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()函数中也是如此。


2
投票

我也有同样的问题。检查您已通过的所有上下文。对于“链接”,它需要Activity Context而不是Application context。

这是您应该检查的地方:

1.)如果您使用了LayoutInflater,那么请检查您传递的上下文。

2.)如果您使用任何适配器,请检查您已通过的上下文。


2
投票

我有同样的问题。问题在于背景。如果要打开任何链接(例如,通过选择器共享任何链接),请传递活动上下文,而不是应用程序上下文。

如果您不在活动中,请不要忘记添加myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)


2
投票

在Adapter_Activity中使用此代码并使用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);

有用....


1
投票
Intent viewIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);    
viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    
startActivity(viewIntent);   

我希望这会奏效。


1
投票

面对同样的问题,然后实施

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

并解决了这个问题。

可能存在与列表视图适配器相关的另一个原因。 你可以看到This blog,描述得很好。


1
投票

使用此代码。对我来说很好。从活动外部分享一些东西:

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);

1
投票

由于添加标志会影响event_flowstack_history,因此最好将“应用程序上下文”传递给非活动,您需要通过以下方式调用活动类:

“ActivityClassName.this”(当您以这种方式传递上下文时,它将包含从非活动场景调用活动所需的所有详细信息和信息)

所以不需要设置或添加标志,这在每种情况下都可以正常工作。


89
投票

你可以用addFlags代替setFlags来实现它

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

根据documentation,它确实:

向intent添加其他标志(或使用现有标志值)。


编辑

请注意,如果您使用的是更改历史堆栈的标志,请参阅Alex Volovoy's answer说:

...避免设置标志,因为它会与事件和历史堆栈的正常流动造成干扰。


0
投票
Intent i= new Intent(context, NextActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);

0
投票

如果您在Cordova插件中调用共享Intent,设置Flag将无济于事。而是使用这个 -

cordova.getActivity().startActivity(Intent.createChooser(shareIntent, "title"));

0
投票

我的情况有点不同,我正在使用Espresso测试我的应用程序,我不得不从仪器ActivityTestRule(不是来自Context的那个)启动Activity的Activity。

fun intent(context: Context) = 
    Intent(context, HomeActivity::class.java)
        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

我不得不改变标志并用or添加一个|按位(Java中的Intent.FLAG_ACTIVITY_NEW_TASK

因此它导致:

fun intent(context: Context) = 
    Intent(context, HomeActivity::class.java)
        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)

0
投票

Kotlin version

val intent = Intent(Intent.ACTION_EDIT, ContactsContract.Profile.CONTENT_URI)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
this.startActivity(intent)

54
投票

而不是使用(getApplicationContext)使用YourActivity.this


29
投票

如果由于使用如下创建选择器而出现错误:

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);

13
投票

我想也许你正在错误的地方实现OnClickListener - 通常你应该在你的Activity中实现一个OnItemClickListener并将它设置在ListView上,否则你的事件就会出现问题......


11
投票

另外:如果您在片段视图中显示链接,请不要像这样创建它

adapter = new ListAdapter(getActivity().getApplicationContext(),mStrings);

而是打电话

adapter = new ListAdapter(getActivity(),mStrings);

适配器在两种情况下都能正常工作,但链接仅适用于最后一个。


7
投票
CustomAdapter mAdapter = new CustomAdapter( getApplicationContext(), yourlist);

要么

Context mContext = getAppliactionContext();
CustomAdapter mAdapter = new CustomAdapter( mContext, yourlist);

改为以下

CustomAdapter mAdapter = new CustomAdapter( this, yourlist);

5
投票

如果您在某个方法中在侦听器中创建意图,请参阅

override onClick (View v).

然后通过这个视图调用上下文:

v.getContext ()

甚至不需要SetFlags ......


3
投票

对于任何人在Xamarin.Android(MonoDroid)上获取此功能,即使从活动中调用StartActivity - 这实际上是新的ART运行时的Xamarin错误,请参阅https://bugzilla.xamarin.com/show_bug.cgi?id=17630

© www.soinside.com 2019 - 2024. All rights reserved.