398

Tôi đã triển khai một ListViewứng dụng Android của mình. Tôi liên kết với điều này ListViewbằng cách sử dụng một lớp con tùy chỉnh của ArrayAdapterlớp. Bên trong ArrayAdapter.getView(...)phương thức được ghi đè , tôi gán một OnClickListener. Trong onClickphương thức của OnClickListener, tôi muốn khởi chạy một hoạt động mới. Tôi nhận được ngoại lệ:

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

Làm thế nào tôi có thể nhận được Contextrằng ListView(dòng Activitydưới) đang làm việc?

|
  • 1
    Tôi nghĩ rằng câu trả lời của Alex nên là 'chấp nhận' giải pháp cho vấn đề của bạn, vì nó chính càn lỗi mà bạn đề cập một cách chung chung hơn –  07:10:00 15/10/2012
  • 11
    Tôi thích rằng "Đây có thực sự là điều bạn muốn?" ... Tôi đã có một tin nhắn trước đó nói rằng "Bạn có chắc là bạn không quên đăng ký một bộ thu phát sóng ở đâu đó không?" TUYỆT VỜI! Cảm ơn bất cứ ai đưa ra tất cả những thông điệp nhỏ này để giúp chúng tôi góp ý. –  11:23:51 25/05/2016
  • 1
    Tôi đã gặp vấn đề này. khi tôi cập nhật targetSdkVersion đến 28. –  11:50:33 13/04/2019
614

Hoặc

  • lưu vào bộ nhớ cache đối tượng Context thông qua hàm tạo trong bộ điều hợp của bạn hoặc
  • lấy nó từ cái nhìn của bạn.

Hoặc như một phương sách cuối cùng,

  • thêm - cờ FLAG_ACTIVITY_NEW_TASK vào mục đích của bạn:

_

myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Chỉnh sửa - tôi sẽ tránh đặt cờ vì nó sẽ cản trở luồng sự kiện và ngăn xếp lịch sử bình thường.

|
  • 1
    Điều gì về tính năng Tự động liên kết của TextView nơi tôi không thể kiểm soát Intent (và do đó các cờ) được tạo bởi hệ thống? –  07:10:01 30/04/2013
  • 1
    Tôi đã nhận được ngoại lệ này khi tôi đang làm một cái gì đó như thế này context.startActivity(intent);tôi chỉ thay đổi contexttừ loại này ApplicationContextsang Activityloại khác. Điều này đã khắc phục sự cố. –  17:08:56 16/11/2013
  • 1
    @AlexSemeniuk bao giờ tìm ra giải pháp? –  16:28:57 13/03/2014
  • 1
    @AlexSemeniuk - autoLink sẽ hoạt động miễn là bạn chuyển hoạt động dưới dạng ngữ cảnh đến bộ điều hợp –  05:40:34 02/12/2015
  • 1
    Tôi đã truyền đối tượng Context thông qua phương thức khởi tạo nhưng nó không hoạt động. nhưng FLAG_ACTIVITY_NEW_TASK hoạt động rất tốt đối với tôi, cảm ơn. –  11:27:01 16/11/2016
105

Bạn có thể đạt được nó bằng addFlags thay vìsetFlags

myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Theo tài liệu nó có:

Thêm cờ bổ sung vào ý định (hoặc với giá trị cờ hiện có).


BIÊN TẬP

Hãy lưu ý nếu bạn đang sử dụng cờ mà bạn thay đổi ngăn xếp lịch sử như câu trả lời của Alex Volovoy cho biết:

... tránh đặt cờ vì nó sẽ cản trở luồng sự kiện và ngăn xếp lịch sử bình thường.

|
  • 1
    Tôi có một vấn đề rất tương tự. Bạn có gặp bất kỳ sự cố nào với ngăn xếp lịch sử hoặc bất kỳ điều gì khác như câu trả lời gợi ý ở trên không? –  09:12:38 20/06/2013
  • 1
    Tôi không chắc chính xác bạn đang tìm gì nhưng bạn có thể bắt đầu một hoạt động mà không có lịch sử như vậy: Intent Ý định = new Intent (Intent.ACTION_VIEW, "http: \\ www.google.com")); ý định. addFlags (Intent.FLAG_ACTIVITY_NO_HISTORY); startActivity (ý định); –  18:47:18 20/06/2013
  • 1
    Tại sao không nên addFlags ở đây? Mức độ quan trọng của việc can thiệp vào luồng sự kiện và lịch sử ngăn xếp bình thường như thế nào? –  00:18:10 04/03/2018
  • 1
    @JasonKrs bạn có thể sử dụng addFlags. Chỉ cần lưu ý rằng bạn có thể thay đổi ngăn xếp lịch sử tùy thuộc vào cờ bạn thêm. FLAG_ACTIVITY_NEW_TASK có thể được sử dụng trong trường hợp này. Để biết thêm chi tiết, hãy đọc: developer.android.com/reference/android/content/… –  07:17:47 04/03/2018
67

Thay vì sử (getApplicationContext)dụngYourActivity.this

|
53

Nếu bạn gặp lỗi do sử dụng trình chọn tạo như bên dưới:

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

Đặt cờ để tạo trình chọn như thế này:

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);
|
  • 1
    Nó rất hữu ích. Ý định của người chọn chính xác nên có cờ này! –  13:31:10 20/08/2018
  • 1
    Đây là soluction chính xác, và chính xác những gì phải làm, new_task trong intent.chooser –  00:46:45 27/04/2019
15

Ngoài ra: nếu bạn hiển thị các liên kết trong listview ở dạng phân mảnh , đừng tạo nó như thế này

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

thay vào đó hãy gọi

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

bộ điều hợp hoạt động tốt trong cả hai trường hợp, nhưng các liên kết chỉ hoạt động trong trường hợp cuối cùng.

|
  • 1
    @ user2676468: điều này đã giải quyết được vấn đề tự động liên kết cho tôi. –  17:28:44 10/12/2014
  • 1
    Đây phải là một câu trả lời được chấp nhận, thay vì sử dụng cờ thì tốt hơn !! –  14:01:42 18/11/2018
  • 1
    @ GastónSaillén, tôi không sử dụng getApplicationContext()(ngoại trừ khởi tạo ứng dụng), nhưng đã bắt được ngoại lệ này. Vì vậy, các tình huống có thể khác nhau. –  14:12:01 02/07/2019
  • 1
    Đây là vấn đề của tôi, tôi đã sử dụng getApplicationContext () cho ngữ cảnh. Đặt thislàm ngữ cảnh hoạt động vì nó liên quan đến hoạt động hiện tại. –  16:24:16 03/01/2020
14

Tôi nghĩ rằng có thể bạn đang triển khai OnClickListener không đúng chỗ - thường thì bạn chắc chắn nên triển khai OnItemClickListener trong Activity của mình và đặt nó trên ListView thay thế, nếu không bạn sẽ gặp sự cố với các sự kiện của mình ...

|
  • 1
    Bạn dẫn tôi đến giải pháp. Tôi cần sử dụng OnItemClickListener, được chỉ định cho ListView. Đây là một số liên kết cho bất kỳ ai khác: developer.android.com/reference/android/widget/… androidpeople.com/… Cảm ơn sự giúp đỡ. –  21:02:05 12/10/2010
  • 1
    Vui lòng cung cấp câu trả lời chung chung. Câu trả lời của Alex Volovoy dưới đây giải quyết vấn đề theo cách chung chung. –  07:08:24 15/10/2012
  • 1
    Đối với hậu thế: Nếu bạn trực tiếp xác định nó là setListener (Trình xử lý mới) trên một thành phần yêu cầu Ngữ cảnh, bạn sẽ tạo một tham chiếu ngầm đến toàn bộ hoạt động sẽ làm rò rỉ bộ nhớ như bạn không thể tin được. Điều này có thể được tránh bằng cách tạo một trình nghe lớp bên trong tĩnh hoặc bằng cách chuyển trình nghe sang một lớp riêng biệt nếu nó cần có khả năng xử lý các đầu vào từ nhiều nguồn gốc. –  08:25:01 28/01/2015
9

Tại Android 28(Android P)startActivity

if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0
        && (targetSdkVersion < Build.VERSION_CODES.N
                || targetSdkVersion >= Build.VERSION_CODES.P)
        && (options == null
                || ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {
    throw new AndroidRuntimeException(
            "Calling startActivity() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                    + " Is this really what you want?");
}

Vì vậy, cách tốt nhất là thêm FLAG_ACTIVITY_NEW_TASK

Intent intent = new Intent(context, XXXActivity.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
|
9
CustomAdapter mAdapter = new CustomAdapter( getApplicationContext(), yourlist);

hoặc là

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

thay đổi bên dưới

CustomAdapter mAdapter = new CustomAdapter( this, yourlist);
|
8

Hãy xem, nếu bạn đang tạo một ý định trong một listiner trong một số phương pháp

override onClick (View v).

sau đó cũng gọi ngữ cảnh thông qua chế độ xem này:

v.getContext ()

Thậm chí sẽ không cần SetFlags ...

|
4

Đối với bất kỳ ai nhận được điều này trên Xamarin.Android (MonoDroid) ngay cả khi StartActivity được gọi từ hoạt động - đây thực sự là lỗi Xamarin với thời gian chạy ART mới, hãy xem https://bugzilla.xamarin.com/show_bug.cgi?id=17630

|
  • 1
    Vâng, bạn chỉ cần làm như những gì được mô tả ở trên, nhưng từ ngữ đã thay đổi ... Ý định.SetFlags (ActivityFlags.NewTask); –  15:16:47 08/08/2019
  • 1
    Ý định ý định = new Intent (); ý định.AddFlags (ActivityFlags.NewTask); Ý định.SetData (Android.Net.Uri.Parse (baseUrl + @ "name_of_apk")); Android.App.Application.Context.StartActivity (ý định); –  05:35:46 17/03/2021
3

Lỗi này xảy ra khi startactivity không biết đâu là hoạt động của mình. Vì vậy, bạn phải thêm hoạt động trước startActivity ()

bạn phải đặt

context.startActivity(yourIntent);
|
  • 1
    Nếu bạn gọi startActivitytừ Fragment, người gọi thường có thể là một phân đoạn, không phải là một hoạt động. –  14:16:16 02/07/2019
3

Xây dựng câu trả lời của Alex Volovoy một chút nữa -

trong trường hợp bạn gặp phải vấn đề này với các mảnh, getActivity () hoạt động tốt để lấy ngữ cảnh

Trong các trường hợp khác:

Nếu bạn không muốn sử dụng-

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

sau đó tạo một hàm như thế này trong lớp bên ngoài của bạn -

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

Bây giờ, trong hoạt động chính của bạn khi bạn tạo một lớp bên ngoài mới, hãy gọi phương thức ở trên ngay sau khi bạn xác định lớp bên ngoài, đưa ra ngữ cảnh của hoạt động làm đối số. Ngoài ra, trong hoạt động chính của bạn, hãy thực hiện một chức năng-

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

bây giờ hãy quay lại Lớp bên ngoài của bạn và để bắt đầu hoạt động mới, hãy làm như thế này-

@Override
public void onClick(View v) {
........
case R.id.any_button:

            MainActivity mainAct = (MainActivity) real_context;             
            mainAct.startNewActivity("ACTIVITY_KEY");                   

        break;
    }
........
}

Bằng cách này, bạn sẽ có thể bắt đầu các hoạt động khác nhau được gọi từ các lớp Bên ngoài khác nhau mà không làm rối tung các cờ.

Lưu ý-Cố gắng không lưu vào bộ nhớ cache đối tượng ngữ cảnh thông qua phương thức khởi tạo cho phân đoạn (với bộ điều hợp, nó tốt). Một phân đoạn phải có một phương thức khởi tạo trống nếu không ứng dụng sẽ bị treo trong một số trường hợp.

nhớ gọi điện

OutsideClass.gettingContext(Context context);

trong hàm onResume ().

|
2

Sử dụng mã này trong Adapter_Activity của bạn và sử dụng context.startActivity(intent_Object)intent_Object.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Như thế này:

Intent n_act = new Intent(context, N_Activity.class);
n_act.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(n_act);

Nó hoạt động ....

|
2

Tôi đã từng gặp vấn đề tương tự. Vấn đề là với ngữ cảnh. Nếu bạn muốn mở bất kỳ liên kết nào (ví dụ: chia sẻ bất kỳ liên kết nào thông qua trình chọn), hãy chuyển ngữ cảnh hoạt động, không phải ngữ cảnh ứng dụng.

Đừng quên thêm myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)nếu bạn không có trong hoạt động của mình.

|
2

Tôi cũng có cùng một vấn đề. Kiểm tra tất cả các bối cảnh mà bạn đã vượt qua. Đối với ' liên kết ' nó cần Ngữ cảnh hoạt động chứ không phải Ngữ cảnh ứng dụng .

Đây là nơi bạn nên kiểm tra:

1.) Nếu bạn đã sử dụng LayoutInflater thì hãy kiểm tra xem bạn đã vượt qua ngữ cảnh nào.

2.) Nếu bạn đang sử dụng bất kỳ Bộ điều hợp nào, hãy kiểm tra xem bạn đã chuyển ngữ cảnh nào chưa.

|
2

Theo ý kiến ​​của tôi, tốt hơn là sử dụng phương pháp startActivity()chỉ trong mã của bạn Activity.class. Nếu bạn sử dụng nó trong lớp Adapterhoặc lớp khác, nó sẽ dẫn đến điều đó.

|
1

Vì việc thêm cờ sẽ ảnh hưởng event_flowstack_historytốt hơn là chuyển 'ngữ cảnh ứng dụng' cho non-activity từ nơi bạn cần gọi một lớp hoạt động theo cách sau:

"ActivityClassName.this" (Trong khi bạn chuyển ngữ cảnh theo cách này, nó sẽ chứa tất cả chi tiết và thông tin mà bạn cần để gọi là Hoạt động từ một kịch bản không hoạt động)

Vì vậy, không cần thiết lập hoặc thêm cờ, điều này sẽ hoạt động tốt trong mọi trường hợp.

|
1

Sử dụng mã này. Làm việc tốt cho tôi. Chia sẻ điều gì đó từ bên ngoài hoạt động:

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

Đối mặt với cùng một vấn đề sau đó được triển khai

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

và đã giải quyết được vấn đề.

Có thể có một lý do khác liên quan đến bộ điều hợp chế độ xem danh sách.
Bạn có thể thấy blog này , đã mô tả nó rất tốt.

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

tôi hy vọng điều này sẽ hiệu quả.

|
0

Trong Hoạt động của bạn (nơi bạn đang gọi bộ điều hợp) chỉ cần thay đổi getActivityContext()bằng YourActivity.this. Đây là một ví dụ:

yourAdapter = new YourAdapter(yourList, YourActivity.this); // Here YourActivity.this is the Context instead of getActivityContext()
recyclerView.setAdapter(yourAdapter);
|
0

Phiên bản Kotlin

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

Tình huống của tôi hơi khác một chút, tôi đang thử nghiệm ứng dụng của mình bằng cách sử dụng Espressovà tôi phải khởi chạy Hoạt động của mình bằng ActivityTestRulethiết bị đo Context(không phải là thiết bị đến từ an Activity).

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

Tôi đã phải thay đổi các cờ và thêm một orbitwise ( |trong Java) vớiIntent.FLAG_ACTIVITY_NEW_TASK

Vì vậy, nó dẫn đến:

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

Nếu bạn đang gọi Ý định chia sẻ trong plugin Cordova, việc đặt Cờ sẽ không hữu ích. Thay vào đó, hãy sử dụng cái này -

cordova.getActivity().startActivity(Intent.createChooser(shareIntent, "title"));
|
0
Intent i= new Intent(context, NextActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.