代码之家  ›  专栏  ›  技术社区  ›  Sako73

从活动上下文外部调用StartActivity()。

  •  311
  • Sako73  · 技术社区  · 14 年前

    我已经实现了 ListView 在我的Android应用程序中。我与此结合 列表视图 使用的自定义子类 ArrayAdapter 班级。在重写的 ArrayAdapter.getView(...) 方法,我分配一个 OnClickListener . 在 onClick 方法 OnCLICKISTER ,我想启动一个新的活动。我得到例外:

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

    我怎么才能拿到 Context 列表视图 (电流) Activity )是否在工作?

    22 回复  |  直到 6 年前
        1
  •  502
  •   LarsH    9 年前

    要么

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

    或者作为最后的手段,

    • 将-flag_activity_new_task标志添加到您的意图中:

    γ

    myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    

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

        2
  •  88
  •   Bruno Bieri    6 年前

    你可以用 addFlags 而不是 setFlags

    myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    

    根据 documentation 确实如此:

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


    编辑

    如果您使用的标志将历史堆栈更改为 Alex Volovoy's answer 说:

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

        3
  •  54
  •   Jeffrey Nyauke    9 年前

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

        4
  •  28
  •   sanath_p    8 年前

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

    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);
    
        5
  •  13
  •   mreichelt    14 年前

    我认为您可能在错误的地方实现OnClickListener—通常您应该在活动中明确地实现OnTiceClickListener,并将其设置在ListView上,否则您的事件会出现问题…

        6
  •  10
  •   Olcay Ertaş Mohammad Razipour    6 年前

    另外:如果在ListView中显示链接 片段 ,不要这样创建它

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

    代替呼叫

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

    适配器在这两种情况下都可以正常工作,但链接只能在最后一种情况下工作。

        7
  •  7
  •   Olcay Ertaş Mohammad Razipour    6 年前
    CustomAdapter mAdapter = new CustomAdapter( getApplicationContext(), yourlist);
    

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

    改变到下面

    CustomAdapter mAdapter = new CustomAdapter( this, yourlist);
    
        8
  •  5
  •   slfan Narendra    9 年前

    看,如果您在某个方法的listiner中创建了一个意图

    override onClick (View v).
    

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

    v.getContext ()
    

    甚至不需要设置标志…

        9
  •  3
  •   rouen    11 年前

    对于任何一个穿上它的人 xamarin.android(单机器人) 即使从Activity调用StartActivity-这实际上是Xamarin Bug和New Art Runtime,请参见 https://bugzilla.xamarin.com/show_bug.cgi?id=17630

        10
  •  3
  •   Cabezas    10 年前

    当StartActivity不知道哪个是他的活动时,就会出现此错误。因此,必须在StartActivity()之前添加Activity。

    你必须设置

    activity.startActivity(yourIntent);
    
        11
  •  2
  •   rayryeng    11 年前

    在我看来,最好使用 startActivity() 就在你的代码里 Activity.class . 如果你在 Adapter 或者其他类,它将导致这个结果。

        12
  •  2
  •   Flying Monkey    10 年前

    进一步阐述亚历克斯·沃洛维的回答-

    如果您遇到碎片问题,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()函数中。

        13
  •  2
  •   codemaniac    10 年前

    我也有同样的问题。检查您传递的所有上下文。为了 链接 它需要 活动上下文 应用程序上下文 .

    这是您应该检查的地方:

    1)如果你使用 布局填充器 然后检查您传递的上下文。

    2.)如果您正在使用 适配器 检查您传递的上下文。

        14
  •  2
  •   Ori Lentz    9 年前

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

    别忘了添加 myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 如果你不在活动中。

        15
  •  1
  •   Chirag Patel    9 年前
    Intent viewIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);    
    viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    
    startActivity(viewIntent);   
    

    我希望这能奏效。

        16
  •  1
  •   Olcay Ertaş Mohammad Razipour    6 年前

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

    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    

    解决了这个问题。

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

        17
  •  1
  •   Olcay Ertaş Mohammad Razipour    6 年前

    使用此代码。对我来说很好。从活动外部共享内容:

    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);
    
        18
  •  1
  •   Olcay Ertaş Mohammad Razipour    6 年前

    在适配器活动中使用此代码并使用 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);
    

    它起作用了…

        19
  •  0
  •   IntelliJ Amiya    8 年前
    Intent i= new Intent(context, NextActivity.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    
        20
  •  0
  •   Sandeep Kumar    7 年前

    如果您在cordova插件中调用share intent,那么设置该标志将没有帮助。而是用这个-

    cordova.getActivity().startActivity(Intent.createChooser(shareIntent, "title"));
    
        21
  •  0
  •   Olcay Ertaş Mohammad Razipour    6 年前

    我的情况有点不同,我正在用 Espresso 我不得不用 ActivityTestRule 来自仪器 Context (不是来自 Activity )

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

    我必须更改标志并添加 or 按位的 | 在爪哇) 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)
    
        22
  •  0
  •   Olcay Ertaş Mohammad Razipour    6 年前

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

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

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

    推荐文章