Cách khởi động lại Hoạt động trong Android


381

Làm cách nào để khởi động lại Android Activity? Tôi đã thử sau đây, nhưng Activityđơn giản là thoát.

public static void restartActivity(Activity act){

        Intent intent=new Intent();
        intent.setClass(act, act.getClass());
        act.startActivity(intent);
        act.finish();

}

9
hoạt động thoát vì bạn gọi là "act.finish ();" ngay sau khi tạo ra hoạt động ...
Nikhil Dinesh

1
phương pháp lỗi thời
pedjjj

Câu trả lời:


623

Tôi đã làm công cụ chuyển đổi chủ đề của mình như thế này:

Intent intent = getIntent();
finish();
startActivity(intent);

Về cơ bản, tôi đang gọi finish()trước và tôi đang sử dụng chính xác mục đích mà hoạt động này đã được bắt đầu. Điều đó dường như để làm các mẹo?

CẬP NHẬT: Như được chỉ ra bởi Ralf bên dưới, Activity.recreate()là cách để đi trong API 11 và hơn thế nữa. Điều này tốt hơn nếu bạn ở trong môi trường API11 +. Bạn vẫn có thể kiểm tra phiên bản hiện tại và gọi đoạn mã ở trên nếu bạn đang ở API 10 trở xuống. (Xin đừng quên nâng cấp câu trả lời của Ralf!)


36
Và đó là giá trị hạ thấp? Đó không phải là một yêu cầu được đề cập bởi OP. Trong thực tế, nó có thể được mong muốn.
EboMike

9
Chà, nếu bạn không thích hoạt hình, bạn có thể tắt nó đi (như bạn đã thể hiện trong câu trả lời của mình). Điều đó không làm cho câu trả lời của tôi sai mỗi lần, nó chỉ không hiển thị một số tùy chọn bổ sung mà bạn có thể tự do thêm vào (và điều đó không được yêu cầu trong câu hỏi).
EboMike

28
Tôi nghĩ rằng bạn đã sai. Một downvote có nghĩa là câu trả lời sai / xấu và upvote có nghĩa là một câu trả lời là tuyệt vời. Làm thế nào tuyệt vời một câu trả lời được so sánh với những người khác được chỉ định bởi số lượng upvote. Tôi có thể thấy rằng bạn đang cố gắng quảng bá câu trả lời của mình, nhưng bạn đang sử dụng sai hệ thống cho mục đích đó.
EboMike

8
+1 - điều này rất tốt cho tôi và như bạn nói, hoạt hình là thứ tôi muốn, vì vậy người dùng biết nó đang khởi động lại. FWIW, tôi đặt ra một quy tắc không bao giờ bỏ phiếu cho người dùng khác trả lời khi tôi cung cấp câu trả lời thay thế cho câu hỏi, mặc dù tôi thỉnh thoảng bỏ phiếu khi câu trả lời của tôi bị bỏ qua (không nói rằng điều đó xảy ra ở đây, chỉ là tôi làm điều đó) .
Michael Bray

4
EboMike và Ben: Cả hai giải pháp của bạn đều trả lời câu hỏi của OP. Bỏ phiếu cho câu trả lời của ai đó hoàn toàn vì lý do "thẩm mỹ", tốt, không tuyệt vời. Tôi sẽ không khuyến khích bất cứ ai làm điều đó ở đây tại Stackoverflow ...
ChuongPham

368

Vì API cấp 11 (Honeycomb), bạn có thể gọi phương thức tái tạo () của hoạt động (nhờ câu trả lời này ).

Phương thức tái tạo () hoạt động giống như thay đổi cấu hình, do đó, các phương thức onSaveInstanceState () và onRestoreInstanceState () của bạn cũng được gọi, nếu có.


3
Điều gì xảy ra nếu hoạt động trước đó gọi hoạt động này bằng startActivityForResult?
nhà phát triển Android

1
Chà, đó là câu trả lời chính xác nếu bạn không cần hỗ trợ bất cứ thứ gì thấp hơn API 11.
Edward Falk

@EdwardFalk có chức năng nào thực hiện trên thư viện hỗ trợ không?
nhà phát triển Android

2
Điều này không hoạt động trong mọi trường hợp. Nếu bạn có một ngăn kéo điều hướng mở trong khi gọi tái tạo () nó sẽ vẫn mở khi được tạo lại, điều đó có nghĩa là nó sẽ lưu trạng thái, điều này có thể không được mong muốn.
Chapz

Tôi là người không muốn nhà nước được cứu. Đôi khi mọi người chỉ muốn khởi động lại sạch sẽ, sau đó họ nên sử dụng câu trả lời của EboMike.
Kimi Chiu

132

Trước SDK 11, một cách để làm điều này là như vậy:

public void reload() {
    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);
    startActivity(intent);
}

Trên hình ảnh động HTC Desire vẫn còn (ít nhất là khi được sử dụng trong phương thức onConfigurationChanged). Chúng không xảy ra luôn, nhưng sử dụng mã của EboMike, chúng cũng không xảy ra luôn.
Juozas Kontvainis

8
Điều này không hoạt động trên các hoạt động chính được bắt đầu bởi launcher. Hoạt động của bạn sẽ bị ẩn vì một số cờ được đặt trên mục đích. Nếu không, nó hoạt động độc đáo.
Thomas Ahle

Điểm tốt. có ý nghĩa bởi vì nó gọi kết thúc () từ hoạt động cơ bản trong ngăn xếp.
Ben

Gọi điều này trong khi chúng tôi thay đổi chủ đề của Hoạt động dường như mang lại tốc độ (không có hoạt hình)
Ashok Goli

3
+1 Hoạt động tốt, đối với tôi ngay cả với Hoạt động chính. Tuy nhiên, bạn nên gọi overridePendingTransition(0, 0);sau finish()startActivity(), tương ứng, không phải nơi bạn gọi nó ...
caw

115

Chỉ để kết hợp câu trả lời của Ralf và Ben (bao gồm cả những thay đổi được đưa ra trong nhận xét):

if (Build.VERSION.SDK_INT >= 11) {
    recreate();
} else {
    Intent intent = getIntent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);

    startActivity(intent);
    overridePendingTransition(0, 0);
}

8
Câu trả lời hay nhất trong tất cả. Dù bạn có tin hay không, tôi vẫn hỗ trợ các thiết bị API 3 và giá trị VERSION.SDK_INT yêu cầu API 4. :)
Edward Falk

31

Tôi đã sử dụng mã này để tôi vẫn có thể hỗ trợ các phiên bản Android cũ hơn và sử dụng recreate()trên các phiên bản Android mới hơn.

Mã số:

public static void restartActivity(Activity activity){
    if (Build.VERSION.SDK_INT >= 11) {
        activity.recreate();
    } else {
        activity.finish();
        activity.startActivity(activity.getIntent());
    }
}

Mẫu vật:

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    private Activity mActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mActivity = MainActivity.this;

        Button button = (Button) findViewById(R.id.restart_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                restartActivity(mActivity);
            }
        });
    }

    public static void restartActivity(Activity activity) {
        if (Build.VERSION.SDK_INT >= 11) {
            activity.recreate();
        } else {
            activity.finish();
            activity.startActivity(activity.getIntent());
        }
    }
}

là công việc tuyệt vời cho tôi !!
papo

22

Giải pháp này đã làm việc cho tôi.

Đầu tiên kết thúc hoạt động và sau đó bắt đầu lại.

Mã mẫu:

public void restartActivity(){
    Intent mIntent = getIntent();
    finish();
    startActivity(mIntent);
}

20

Đây là cách dễ nhất để khởi động lại hoạt động hiện tại:

finish();
startActivity(getIntent());

19

Gọi phương thức này

private void restartFirstActivity()
 {
 Intent i = getApplicationContext().getPackageManager()
 .getLaunchIntentForPackage(getApplicationContext().getPackageName() );

 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
 startActivity(i);
 }

Cảm ơn,


1
Tôi nghĩ rằng OP muốn khởi động lại bất kỳ hoạt động nào, không chỉ hoạt động đầu tiên, nhưng điều này rất hữu ích với tôi.
Kristopher Johnson

1
Hai lá cờ là tốt để biết, trường hợp của tôi dường như không làm gì nếu không có chúng.
Owen B

1
nó làm việc nhờ bạn! Chúa phù hộ bạn .
Vivek

16

Mặc dù điều này đã được trả lời nhiều lần.

Nếu khởi động lại một hoạt động từ một đoạn, tôi sẽ làm như vậy:

new Handler().post(new Runnable() {

         @Override
         public void run()
         {
            Intent intent = getActivity().getIntent();
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
            getActivity().overridePendingTransition(0, 0);
            getActivity().finish();

            getActivity().overridePendingTransition(0, 0);
            startActivity(intent);
        }
    });

Vì vậy, bạn có thể nghĩ rằng đây là một chút quá mức? Nhưng việc Handlerđăng bài cho phép bạn gọi điều này theo phương pháp vòng đời. Tôi đã sử dụng cái này trong onRestart/onResume phương pháp phương pháp khi kiểm tra xem trạng thái đã thay đổi giữa người dùng quay lại ứng dụng hay chưa. (cài đặt một cái gì đó).

Không có Handler nếu bạn gọi nó ở một nơi kỳ lạ, nó sẽ chỉ giết hoạt động và không khởi động lại nó.

Hãy hỏi bất kỳ câu hỏi.

Chúc mừng, Chris


2
Giải pháp tuyệt vời và lý luận / giải thích rất tốt cho Handler.
JRomero

1
Tại sao bạn gọi hai lần để "overridePendingTransition"?
nhà phát triển Android

1
@androiddeveloper Tôi không thể nhớ, tôi nghĩ đó là một lỗi xung quanh. Bạn có thể gọi nó một lần trước khi startActivity () và nó sẽ làm như đã nói.
Chris.Jenkins

Sau khi thực hiện điều này trong chức năng onResume của tôi, trò chơi dừng trên phương thức onStop của tôi và có một màn hình đen ... không biết tại sao
Scumble373

1
Xin chào chris, bạn có thể giải thích điều này thêm một chút "Nếu không có Handler nếu bạn gọi nó ở một nơi kỳ lạ, nó sẽ chỉ giết chết hoạt động và không khởi động lại nó." ?
parve rafi

15

Vâng, điều này không được liệt kê nhưng một số kết hợp đã được đăng:

if (Build.VERSION.SDK_INT >= 11) {
    recreate();   
} else {
    Intent intent = getIntent();
    finish();
    startActivity(intent);
}

Nó hoạt động với tôi .. cảm ơn .. nhưng tôi muốn hỏi bạn: tại sao khi tôi xóa phần đầu tiên của mã (phần kiểm tra SDK_INT) thì ứng dụng của tôi chạy, tương đối, chậm? !! .. khi tôi đính kèm lại mã, nó chạy, tương đối và rõ ràng, nhanh hơn nhiều !!!
McLan

2
Không chắc chắn về điều đó. Chà, nếu bạn đang sử dụng SDK có> = 11 thì việc tạo lại () sẽ nhanh hơn việc lấy ý định, hoàn thiện, sau đó bắt đầu lại. Kết thúc cuộc gọi mã chạy đến onStop và tạo lại chạy mã như thay đổi hướng ... vì vậy nó không hoàn toàn nhiều để làm.
Được mã hóa vào

4

Kết hợp với hành vi vòng đời SurfaceView kỳ lạ với Camera . Tôi đã thấy rằng tái tạo () không hoạt động tốt với vòng đời của SurfaceViews. SurfaceDestroyed không bao giờ được gọi trong chu kỳ giải trí. Nó được gọi sau onResume (lạ), tại đó SurfaceView của tôi bị phá hủy.

Cách ban đầu để tạo lại một hoạt động tốt.

Intent intent = getIntent();
finish();
startActivity(intent);

Tôi không thể hiểu chính xác tại sao lại như vậy, nhưng đó chỉ là một quan sát có thể hy vọng hướng dẫn người khác trong tương lai vì nó đã khắc phục các vấn đề của tôi mà tôi gặp phải với SurfaceViews


4

Tôi tự hỏi tại sao không ai đề cập đến Intent.makeRestartActivityTask()việc làm sạch mục đích chính xác này.

Tạo một ý định có thể được sử dụng để khởi chạy lại nhiệm vụ của ứng dụng * ở trạng thái cơ bản.

startActivity(Intent.makeRestartActivityTask(getActivity().getIntent().getComponent()));

Phương pháp này đặt Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASKlàm cờ mặc định.


3

Trên thực tế, mã sau đây hợp lệ cho các cấp API 5 trở lên, vì vậy nếu API mục tiêu của bạn thấp hơn mức này, bạn sẽ kết thúc với một thứ rất giống với mã của EboMike.

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
overridePendingTransition(0, 0);

3

Có một cách hacky nên hoạt động trên mọi hoạt động, bao gồm cả cách chính.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

Khi định hướng thay đổi, Android thường sẽ tạo lại hoạt động của bạn (trừ khi bạn ghi đè lên nó). Phương pháp này hữu ích cho việc xoay 180 độ, khi Android không tạo lại hoạt động của bạn.


3
public void onRestart() {
    super.onRestart();
    Intent intent=new Intent();
    intent.setClass(act, act.getClass());
    finish();
    act.startActivity(intent);
}

cố gắng sử dụng cái này ..


3

Giải pháp cho câu hỏi của bạn là:

public static void restartActivity(Activity act){
    Intent intent=new Intent();
    intent.setClass(act, act.getClass());
    ((Activity)act).startActivity(intent);
    ((Activity)act).finish();
}

Bạn cần chuyển sang bối cảnh hoạt động để bắt đầu hoạt động mới và cũng như kết thúc hoạt động hiện tại.

Hy vọng điều này hữu ích..và làm việc cho tôi.


1

Nếu bạn xóa dòng cuối cùng, bạn sẽ tạo mới act Hoạt động , nhưng phiên bản cũ của bạn vẫn còn tồn tại.

Bạn có cần khởi động lại Hoạt động như khi thay đổi hướng (nghĩa là trạng thái của bạn được lưu và được chuyển đến onCreate(Bundle) ) không?

Nếu bạn không, một cách giải quyết khác có thể là sử dụng thêm một Hoạt động giả, sẽ được bắt đầu từ Hoạt động đầu tiên và công việc nào là bắt đầu phiên bản mới của nó. Hoặc chỉ trì hoãn cuộc gọi đếnact.finish() , sau khi mới được bắt đầu.

Nếu bạn cần lưu hầu hết trạng thái, bạn đang ở trong vùng nước khá sâu, bởi vì việc vượt qua tất cả các thuộc tính của trạng thái của bạn, đặc biệt là không làm rò rỉ Bối cảnh / Hoạt động cũ của bạn, bằng cách chuyển nó sang trường hợp mới.

Xin vui lòng, xác định những gì bạn đang cố gắng để làm.


1
Tôi có một nút áp dụng các chủ đề khác nhau cho ứng dụng, sau khi chủ đề được áp dụng, nó được lưu trong tùy chọn, hoạt động gốc khởi động lại, đọc chủ đề từ tùy chọn, áp dụng chủ đề trong onCreate (). Nó chỉ ra rằng đoạn mã trên hoạt động tốt nếu hoạt động không phải là Single_instance. Không chắc chắn nếu đó là thực hành tốt nhất.

Hiện tại, không có cách nào được dọn sạch SDK để khởi động lại Activity của bạn, AFAIK - nếu bạn không rò rỉ bất cứ điều gì, bạn có thể sẽ tốt hơn :)
Dimitar Dimitrov

0

Đây là cách tôi làm.

        val i = Intent(context!!, MainActivity::class.java)
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        startActivity(i)

-1

Nếu bạn đang gọi từ một số đoạn, do đó, dưới đây mã.

Intent intent = getActivity().getIntent();
getActivity().finish();
startActivity(intent);

-4

bạn chỉ có thể sử dụng

onRestart ()

phương pháp như sau

 @Override
    protected void onRestart() {
        super.onRestart();
        setContentView(R.layout.add_entry);
    }

gọi onRestart () nơi bạn muốn khởi động lại Hoạt động hiện tại


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.