Gọi startActivity () từ bên ngoài Hoạt động?


196

Tôi đang sử dụng AlarmManagerđể kích hoạt ý định phát tín hiệu. Sau đây là mã của tôi:

AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(this, Wakeup.class);
try
{
    PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
    Long elapsed +=  // sleep time;
    mgr.set(AlarmManager.RTC_WAKEUP, elapsed, pi);
}
catch(Exception r)
{
    Log.v(TAG, "RunTimeException: " + r);
}

Tôi đang gọi mã này từ một Activity, vì vậy tôi không biết làm thế nào tôi có thể gặp phải lỗi sau ...

ERROR/AndroidRuntime(7557): java.lang.RuntimeException: Unable to start receiver com.wcc.Wakeup: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

Câu trả lời:


494

nếu phiên bản Android của bạn thấp hơn Android - 6 thì bạn cần thêm dòng này nếu không nó sẽ hoạt động trên Android - 6.

...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...

8
vâng điều này hoạt động. nhưng nếu bạn muốn bắt đầu nhiều phiên bản của cùng một Hoạt động thì điều này không hoạt động. Vì FLAG_ACTIVITY_NEW_TASK sẽ tiếp tục Hoạt động tương tự hiện tại
Ovidiu Latcu

7
Thêm cờ FLAG_ACTIVITY_Mult Môn_TASKS để giải quyết vấn đề của bạn
Pavankumar Vijapur

Coi chừng, bạn cũng cần điều này trên Android 9+, hãy xem câu trả lời này để được làm rõ
Vadim Kotov

55

Đối với nhiều trường hợp của cùng một hoạt động, hãy sử dụng đoạn mã sau,

Lưu ý : Đoạn mã này, tôi đang sử dụng bên ngoài của tôi Activity. Hãy chắc chắn rằng AndroidManifesttập tin của bạn không chứa android:launchMode="singleTop|singleInstance". nếu cần, bạn có thể thay đổi nó thành android:launchMode="standard".

Intent i = new Intent().setClass(mActivity.getApplication(), TestUserProfileScreenActivity.class);  
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);

// Launch the new activity and add the additional flags to the intent
mActivity.getApplication().startActivity(i);

Cái này làm việc tốt cho tôi. Hy vọng, điều này tiết kiệm thời gian cho một ai đó. Nếu bất cứ ai tìm thấy một cách tốt hơn, xin vui lòng chia sẻ với chúng tôi.


5
Vui lòng hiểu sự khác biệt giữa các phương thức setFlags () và addFlag (). Tất cả những gì bạn đang làm bây giờ là khởi chạy một hoạt động với FLAG_ACTIVITY_NEW_TASK. Như trong mã được đăng bởi Cristian dưới đây.
JehandadK

-------------------------------------------------- ----------------- i.addFlag (Ý định.FLAG_ACTIVITY_MULTIPLE_TASK); i.addFlag (Ý định.FLAG_ACTIVITY_NEW_TASK); -------------------------------------------------- ----------------- i.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
JehandadK

42

Android Doc nói -

Yêu cầu FLAG_ACTIVITY_NEW_TASK hiện được thi hành

Với Android 9, bạn không thể bắt đầu một hoạt động từ bối cảnh không hoạt động trừ khi bạn vượt qua cờ mục đích FLAG_ACTIVITY_NEW_TASK. Nếu bạn cố bắt đầu một hoạt động mà không vượt qua cờ này, hoạt động đó không bắt đầu và hệ thống sẽ in một thông báo tới nhật ký.

Lưu ý: Yêu cầu cờ luôn là hành vi dự định và được thi hành trên các phiên bản thấp hơn Android 7.0 (API cấp 24). Một lỗi trong Android 7.0 đã ngăn không cho yêu cầu cờ được thi hành.

Điều đó có nghĩa (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)là bắt buộc phải thêm Intent.FLAG_ACTIVITY_NEW_TASKtrong khi gọi startActivity()từ bên ngoài Activityngữ cảnh.

Vì vậy, tốt hơn là thêm cờ cho tất cả các phiên bản -

...
Intent i = new Intent(this, Wakeup.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
...

12

Bạn đã không dán phần mà bạn gọi startActivity, đó là phần thú vị.

Bạn có thể đang gọi startActivitytrong một Servicebối cảnh, hoặc trong một Applicationbối cảnh.

In "này" để ghi nhật ký mèo trước khi thực hiện startActivitycuộc gọi và xem nó đề cập đến điều gì, đôi khi đó là một trường hợp vô tình sử dụng "cái này" bên trong.


1
Đây có thể là vấn đề OP đang gặp phải. Tôi đã gặp phải như vậy. Khởi chạy một hoạt động với getApplicationContext () thay vì một hoạt động hiện có sẽ gây ra lỗi này.
Phần mềm Hazen Hills

NICE :) Tôi khá chắc chắn đây là lỗi tôi cố gắng phát hiện cả buổi tối. Cảm ơn ngài.
Martin Pfeffer

9

Đôi khi lỗi này có thể xảy ra mà không có một cuộc gọi rõ ràng đến startActivity(...). Ví dụ: một số bạn có thể đã thấy dấu vết ngăn xếp như thế này trong Crashlytics:

Fatal Exception: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
       at android.app.ContextImpl.startActivity(ContextImpl.java:1597)
       at android.app.ContextImpl.startActivity(ContextImpl.java:1584)
       at android.content.ContextWrapper.startActivity(ContextWrapper.java:337)
       at android.text.style.URLSpan.onClick(URLSpan.java:62)
       at android.text.method.LinkMovementMethod.onTouchEvent(LinkMovementMethod.java:217)
       at android.widget.TextView.onTouchEvent(TextView.java:9522)
       at android.view.View.dispatchTouchEvent(View.java:8968)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.widget.AbsListView.dispatchTouchEvent(AbsListView.java:5303)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2709)
       at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2425)
       at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2559)
       at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1767)
       at android.app.Activity.dispatchTouchEvent(Activity.java:2866)
       at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:67)
       at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:67)
       at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2520)
       at android.view.View.dispatchPointerEvent(View.java:9173)
       at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4706)
       at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4544)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
       at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4201)
       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4095)
       at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4258)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
       at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4121)
       at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4087)
       at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4095)
       at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4068)
       at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6564)
       at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6454)
       at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6425)
       at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6654)
       at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
       at android.os.MessageQueue.nativePollOnce(MessageQueue.java)
       at android.os.MessageQueue.next(MessageQueue.java:143)
       at android.os.Looper.loop(Looper.java:130)
       at android.app.ActivityThread.main(ActivityThread.java:5942)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)

Và bạn có thể tự hỏi những gì bạn đã làm sai, vì dấu vết chỉ bao gồm mã khung. Chà, đây là một ví dụ về cách điều này có thể xảy ra. Hãy nói rằng chúng ta đang ở trong một mảnh.

Activity activity = getActivity();
Context activityContext = activity;
Context appContext = activityContext.getApplicationContext();
LayoutInflater inflater = LayoutInflater.from(appContext); // whoops!
View view = inflater.inflate(R.layout.some_layout, parent, false);
TextView tvWithLinks = (TextView) view.findViewById(R.id.tv_with_links);

tvWithLinks.setMovementMethod(LinkMovementMethod.getInstance()); // whoops!!

Bây giờ, khi người dùng nhấp vào chế độ xem văn bản đó, ứng dụng của bạn sẽ gặp sự cố với dấu vết ngăn xếp ở trên. Điều này là do bộ tạo bố cục có tham chiếu đến ngữ cảnh ứng dụng và do đó, chế độ xem văn bản của bạn có bối cảnh ứng dụng. Nhấp vào xem văn bản đó gọi ngầmappContext.startActivity(...) .

Lưu ý cuối cùng: Tôi đã thử nghiệm điều này trên các thiết bị Android 4, 5, 6 và 7. Nó chỉ ảnh hưởng đến 4, 5 và 6. Các thiết bị Android 7 dường như không gặp sự cố khi gọi appContext.startActivity(...).

Tôi mong điều này giúp được người nào khác!


2

Lỗi tương tự này tôi đã gặp phải trong trường hợp nhận Thông báo trong các thiết bị Android 9 và 10 mới nhất.

Nó phụ thuộc vào chế độ Launch cách bạn xử lý nó. Sử dụng mã dưới đây: - android: launchMode = "singleTask"

Thêm cờ này với Ý định: - aim.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);


1

Hãy thử thay đổi dòng này:

PendingIntent pendingIntent = PendingIntent.getBroadcast(getContext(), 0, i, 0);

1

Tôi chỉ muốn lưu ý rằng startActivitytừ bên ngoài một hoạt động có giá trị trong một số phiên bản Android (giữa N và O-MR1) và điểm thú vị là đó là một lỗi trong mã nguồn Android!


Đây là nhận xét trên startActivitythực hiện. Xem ở đây .

Việc gọi hoạt động bắt đầu từ bên ngoài một hoạt động không có FLAG_ACTIVITY_NEW_TASK thường không được phép, ngoại trừ nếu người gọi chỉ định id tác vụ thì hoạt động sẽ được khởi chạy. Một lỗi tồn tại giữa N và O-MR1 cho phép hoạt động này .


giải pháp cho điều đó là gì
dominic_torreto

0

Khi bạn muốn mở một hoạt động trong ứng dụng của mình thì bạn có thể gọi phương thức startActivity () với tham số là tham số. Ý định đó sẽ là hoạt động mà bạn muốn mở. Trước tiên, bạn phải tạo một đối tượng của ý định đó với tham số đầu tiên là bối cảnh và tham số thứ hai để trở thành lớp hoạt động được nhắm mục tiêu.

Intent intent = new Intent(this, Activity_a.class);
startActivity(intent);

Hy vọng điều này sẽ giúp.


3
Tôi đang viết như một người đánh giá vì câu trả lời của bạn đã được gắn cờ cho chất lượng thấp. Thiếu sót của câu trả lời này là không có lời giải thích nào về mã của bạn làm gì hoặc tại sao nó giải quyết vấn đề được đặt ra trong câu hỏi. Bạn có vui lòng thêm một số ý kiến ​​giải thích, ghi nhớ rằng nhiều lập trình viên có thể đọc câu trả lời của bạn trong tương lai để được hướng dẫn. Cảm ơn bạn!
Bill Bell

Khi bạn muốn mở một hoạt động trong ứng dụng của mình thì bạn có thể gọi phương thức startActivity () với tham số là tham số. Ý định đó sẽ là hoạt động mà bạn muốn mở. Trước tiên, bạn phải tạo một đối tượng của ý định đó với tham số đầu tiên là bối cảnh và tham số thứ hai để trở thành lớp hoạt động được nhắm mục tiêu. Hy vọng điều này sẽ giúp.
Md. Shafiqur Rahman

ĐỒNG Ý. Nhưng thay vì đưa thông tin đó vào một bình luận, bạn nên chỉnh sửa câu trả lời của mình và đặt nó ở đó. Tôi rất tiếc khi tin vào điểm này nhưng điều quan trọng là phải làm điều này cho mọi câu trả lời. Trân trọng.
Bill Bell

Có, vui lòng bao gồm các giải thích về lý do tại sao câu trả lời của bạn là chính xác. Chúng ta chỉ học để trở thành những lập trình viên giỏi hơn khi chúng ta học TẠI SAO chúng ta làm những việc chúng ta làm.
kiwicomb123
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.