2010-10-12 113 views
225

我在我的Android應用程序中實現了一個ListView。我使用ArrayAdapter類的自定義子類綁定到此ListView。在重寫的ArrayAdapter.getView(...)方法中,我分配了一個OnClickListener。在OnClickListeneronClick方法中,我想要啓動一個新的活動。我得到異常:從活動環境外部調用startActivity()

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

我怎樣才能獲得ContextListView(當前Activity)下工作?

+1

我認爲亞歷克斯的答案應該是「接受」解決您的問題,因爲它以更通用的方式糾正了您提到的錯誤 – 2012-10-15 07:10:00

+3

我喜歡這個「這真的是你想要的嗎?」 ...我之前收到一條消息說:「你確定你沒有忘記在某處註銷廣播接收器嗎?」真棒!所有這些小小的信息都會幫助我們疏導。 – 2016-05-25 11:23:51

回答

415

無論是

  • 緩存通過構造背景下的對象適配器,或
  • 從您的視圖得到它。

或者作爲最後的手段,

  • 加 - FLAG_ACTIVITY_NEW_TASK標誌你的意圖:

_

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

編輯 - 我會避免設置標誌,因爲它會干擾事件和歷史堆棧的正常流動。

+5

TextView的_autoLink_特性如何控制系統創建的Intent(以及標誌)? – 2013-04-30 07:10:01

+36

當我正在做這樣的'context.startActivity(intent);''我剛剛'將'ContextContext'從'ApplicationContext'改爲'Activity'類型時,我得到了這個異常。這解決了這個問題。 – Sufian 2013-11-16 17:08:56

+0

@AlexSemeniuk曾經找到解決方案? – 2014-03-13 16:28:57

13

我想,也許你正在實施OnClickListener在錯誤的地方 - 通常是你一定要在你的活動實施OnItemClickListener並將其設置在ListView控件來替代,或者你會得到問題與事件......

+2

你讓我找到解決方案。我需要使用分配給ListView的OnItemClickListener。以下是其他人的一些鏈接: http://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener.html http://www.androidpeople.com/android-custom-listview-tutorial-example -part-2/ 感謝您的幫助。 – Sako73 2010-10-12 21:02:05

+0

請提供一般答案。 Alex Volovoy的答案以通用的方式解決了這個問題。 – 2012-10-15 07:08:24

+0

對於後人:如果你直接將它定義爲一個組件上的setListener(new Listener)需要一個Context,那麼你就會創建一個隱式引用來引發整個活動,這會泄漏你不會相信的內存。這可以通過創建靜態內部類監聽器或通過將監聽器移動到單獨的類(如果需要能夠處理來自多個來源的輸入)來繞過。 – 2015-01-28 08:25:01

70

解決它 「addFlags,而不是 「setFlags」

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

按照documentation它:

添加其他標誌的意圖(或與現有的標誌值)。

編輯

請注意,如果你使用的是你改變了歷史堆棧Alex Volovoy's answer國旗說:

...避免設置標誌,因爲它會與正常流動干擾事件和歷史堆棧。

+1

我有一個非常類似的問題。您是否遇到過歷史堆棧的任何問題或其他問題,因爲上面的答案是建議? – 2013-06-20 09:12:38

+0

我不完全確定你在找什麼,但你可以開始一個沒有如此歷史的活動: Intent intent = new Intent(Intent.ACTION_VIEW,「http:\\ www.google.com」)); intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); \t \t \t \t \t startActivity(intent); – 2013-06-20 18:47:18

+0

謝謝。我正在做同樣的事情。 – 2016-05-26 19:35:12

5
CustomAdapter mAdapter = new CustomAdapter(getApplicationContext(), yourlist); 

Context mContext = getAppliactionContext(); 

CustomAdapter mAdapter = new CustomAdapter(mContext, yourlist); 

變化以下

CustomAdapter mAdapter = new CustomAdapter(this, yourlist); 
3

在我看來,最好使用startActivity()的方法只是在你的0代碼中。如果你在Adapter或其他課程中使用它,將導致這種情況。

8

另外:如果你顯示在列表視圖鏈接在片段,不要創建它像這樣

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

改爲調用

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

適配器可以在這兩種情況很好,但環節的工作只在最後一個。

+0

@ user2676468:這解決了我的自動鏈接問題。 – 2014-12-10 17:28:44

3

當startactivity不知道哪個是他的活動時會出現此錯誤。所以,你必須startActivity()之前添加活性

必須設置

activity.startActivity(yourIntent); 
2

詮亞歷克斯Volovoy的答案多一點 -

的情況下,u的得到這個問題的片段,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 
} 

現在,在您的主要活動時,你永遠做一個新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 

現在回到你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

我也有同樣的問題。檢查您已通過的所有上下文。對於'鏈接'它需要活動上下文不是應用程序上下文

這種情況下,你應該檢查的地方:

1)如果你使用LayoutInflater然後檢查你已經通過了環境。

2.)如果您正在使用任何適配器請檢查您已通過的上下文。

2
Intent viewIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);  
viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
startActivity(viewIntent); 

我希望這會奏效。

2

我有同樣的問題。問題與上下文有關。如果你想打開任何鏈接(例如通過選擇器共享任何鏈接)傳遞活動上下文,而不是應用程序上下文。

如果您不在您的活動中,請不要忘記添加myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

4

看,如果你以某種方法創建listiner內的意圖

override onClick (View v). 

然後調用上下文通過這一觀點,以及:

v.getContext() 

有甚至不需要SetFlags .. 。

32

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

+0

對我來說這是最好的解決方案 – Kostya 2017-04-27 13:31:23

+0

就像一個魅力! – VSG24 2017-07-09 19:59:26

+0

你是男人! – 2017-09-30 18:41:36

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

如果因爲使用類似下面創建選配的有錯誤:

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

完美的解決方案 – Beraki 2017-02-05 20:20:21

1

面臨着同樣的問題,那麼實現
意圖.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
並解決了問題。

可能還有另一個與列表視圖適配器有關的原因。
你可以看到This blog,描述得非常好。

+0

有幫助的博客,謝謝。 :) – 2017-08-03 07:20:24

0

使用此代碼。對我來說工作得很好;從活動

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

設置標誌搞砸堆棧跟蹤歷史 – Ezio 2018-01-17 08:53:07

0

如果要調用科爾多瓦插件份額意圖之外,設置標誌將不利於 分享一些東西。相反,使用此 -

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

我的情況有點不同,我測試使用Espresso我的應用程序,我不得不從儀表ContextActivityTestRule啓動我的活動(這是不是一個來自Activity來) 。

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

我不得不改變的標誌和與Intent.FLAG_ACTIVITY_NEW_TASK

添加or按位(|在Java中),所以它導致:

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