วิธีการรีสตาร์ทกิจกรรมใน Android


381

ฉันจะรีสตาร์ท Android ได้Activityอย่างไร ฉันลองทำสิ่งต่อไปนี้ แต่สิ่งที่Activityเรียบง่าย

public static void restartActivity(Activity act){

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

}

9
กิจกรรมหยุดทำงานเนื่องจากคุณเรียกว่า "act.finish ();" ทันทีหลังจากสร้างกิจกรรม ...
Nikhil Dinesh

1
วิธีการที่ล้าสมัย
pedjjj

คำตอบ:


623

ฉันทำสลับธีมของฉันเช่นนี้:

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

โดยพื้นฐานแล้วฉันกำลังโทรหาfinish()ก่อนและฉันใช้ความตั้งใจเดิมที่กิจกรรมนี้เริ่มต้น ดูเหมือนว่าจะทำเคล็ดลับหรือไม่

UPDATE: ดังที่ Ralf ระบุไว้ด้านล่างActivity.recreate()เป็นวิธีที่จะใช้ใน API 11 และสูงกว่า สิ่งนี้จะดีกว่าถ้าคุณอยู่ในสภาพแวดล้อม API11 + คุณยังคงสามารถตรวจสอบเวอร์ชันปัจจุบันและโทรหาข้อมูลโค้ดด้านบนหากคุณอยู่ใน API 10 หรือต่ำกว่า (โปรดอย่าลืมโหวตคำตอบของ Ralf!)


36
และนั่นคือมูลค่าการลดลง? นั่นไม่ใช่ข้อกำหนดที่ระบุไว้โดย OP ในความเป็นจริงมันอาจเป็นที่ต้องการ
EboMike

9
ถ้าคุณไม่ชอบอนิเมชั่นคุณสามารถปิดมันได้ (ดังที่คุณแสดงในคำตอบ) นั่นไม่ได้ทำให้คำตอบของฉันผิดต่อมันเป็นเพียงแค่ไม่แสดงตัวเลือกเพิ่มเติมบางอย่างที่คุณมีอิสระที่จะเพิ่ม (และนั่นไม่ได้ถามในคำถาม)
EboMike

28
ฉันคิดว่าคุณเข้าใจผิด downvote หมายถึงคำตอบที่ผิด / ไม่ถูกต้องและ upvote หมายถึงคำตอบนั้นยอดเยี่ยม วิธีการเปรียบเทียบคำตอบกับคนอื่นนั้นดีมากเพียงใดโดยระบุจำนวน upvotes ฉันเห็นว่าคุณกำลังพยายามโปรโมตคำตอบของคุณ แต่คุณใช้ระบบไปในทางที่ผิด
EboMike

8
+1 - สิ่งนี้ทำงานได้ดีสำหรับฉันและอย่างที่คุณพูดแอนิเมชั่นเป็นสิ่งที่ฉันต้องการดังนั้นผู้ใช้จึงรู้ว่ามันกำลังเริ่มต้นใหม่ FWIW ฉันทำให้เป็นกฎที่จะไม่ลงคะแนนให้ผู้ใช้คนอื่นตอบเมื่อฉันให้คำตอบอื่นกับคำถามแม้ว่าฉันจะลงคะแนนเป็นครั้งคราวเมื่อคำตอบของฉันไม่ได้จัดประเภทไว้ (ไม่ได้บอกว่าเกิดขึ้นที่นี่ .
Michael Bray

4
EboMike และ Ben: โซลูชันทั้งสองของคุณตอบคำถามของ OP หากต้องการโหวตคำตอบของใครบางคนอย่างหมดจดเพราะเหตุผล "สุนทรียะ" ก็ดีไม่ดี ฉันจะไม่สนับสนุนให้ใครทำที่นี่ที่ Stackoverflow ...
ChuongPham

368

ตั้งแต่ระดับ API 11 (Honeycomb) คุณสามารถเรียกวิธีการสร้างใหม่ ()ของกิจกรรม (ขอบคุณคำตอบนี้ )

เมธอด recreate () ทำหน้าที่เหมือนการเปลี่ยนแปลงการกำหนดค่าดังนั้นเมธอด onSaveInstanceState () และ onRestoreInstanceState () ของคุณก็จะถูกเรียกใช้เช่นกันถ้ามี


3
เกิดอะไรขึ้นถ้ากิจกรรมก่อนหน้านี้เรียกกิจกรรมนี้โดยใช้ startActivityForResult
นักพัฒนา android

1
เป็นคำตอบที่ถูกต้องถ้าคุณไม่ต้องการสนับสนุนอะไรที่ต่ำกว่า API 11
Edward Falk

@EdwardFalk มีฟังก์ชั่นใดบ้างที่ทำงานบนห้องสมุดสนับสนุน?
นักพัฒนา android

2
สิ่งนี้ไม่สามารถใช้งานได้ในทุกกรณี หากคุณเปิดลิ้นชักการนำทางในขณะที่เรียกการสร้างใหม่ขึ้นมา () จะยังคงเปิดอยู่เมื่อสร้างขึ้นใหม่ซึ่งหมายความว่าช่วยประหยัดสถานะซึ่งอาจไม่เป็นที่ต้องการ
Chapz

ฉันเป็นคนที่ไม่ต้องการให้รัฐรอดชีวิต บางครั้งผู้คนต้องการเริ่มต้นใหม่แบบสะอาดจากนั้นพวกเขาควรใช้คำตอบของ EboMike
Kimi Chiu

132

ก่อน SDK 11 วิธีทำเช่นนี้:

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

ในภาพเคลื่อนไหว HTC Desire ยังคงอยู่ (อย่างน้อยเมื่อใช้ในวิธีการกำหนดค่าที่เปลี่ยนแปลง) มันไม่ได้เกิดขึ้นเสมอไป แต่การใช้รหัสของ EboMike จะไม่เกิดขึ้นเสมอ
Juozas Kontvainis

8
สิ่งนี้ใช้ไม่ได้กับกิจกรรมหลักที่เริ่มโดยตัวเรียกใช้งาน กิจกรรมของคุณจะถูกซ่อนไว้เนื่องจากธงบางรายการตั้งอยู่บนจุดประสงค์ มิฉะนั้นมันจะทำงานได้ดี
โทมัส Ahle

จุดดี. เหมาะสมเพราะมันเรียกเสร็จสิ้น () จากกิจกรรมฐานในสแต็ก
เบ็

การเรียกสิ่งนี้ในขณะที่เราเปลี่ยนธีมของกิจกรรมดูเหมือนจะทำให้เกิดความเร็ว (โดยไม่มีภาพเคลื่อนไหว)
Ashok Goli

3
+1 ใช้ได้ดีสำหรับฉันแม้แต่กับกิจกรรมหลัก แต่คุณควรจะเรียกoverridePendingTransition(0, 0);หลังfinish()และstartActivity()ตามลำดับไม่ได้ที่คุณเรียกมันว่า ...
กา

115

เพียงเพื่อรวมคำตอบของ Ralf และ Ben (รวมถึงการเปลี่ยนแปลงในความคิดเห็น):

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
คำตอบที่ดีที่สุดของทั้งหมด เชื่อหรือไม่ แต่ฉันยังคงสนับสนุน API 3 อุปกรณ์และความคุ้มค่า VERSION.SDK_INT ต้อง API 4. :)
เอ็ดเวิร์ด Falk

31

ฉันใช้รหัสนี้เพื่อให้ฉันยังสามารถรองรับ Android รุ่นเก่ากว่าและใช้recreate()กับ Android รุ่นใหม่กว่าได้

รหัส:

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

ตัวอย่าง:

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());
        }
    }
}

เป็นงานที่ดีสำหรับฉัน !!
Papo

22

วิธีนี้ใช้ได้ผลสำหรับฉัน

ทำกิจกรรมให้เสร็จก่อนจากนั้นเริ่มอีกครั้ง

รหัสตัวอย่าง:

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

20

นี่เป็นวิธีที่ง่ายที่สุดในการรีสตาร์ทกิจกรรมปัจจุบัน:

finish();
startActivity(getIntent());

19

เรียกวิธีนี้

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

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

ขอบคุณ


1
ฉันคิดว่า OP ต้องการเริ่มกิจกรรมใหม่ไม่ใช่แค่กิจกรรมแรก แต่สิ่งนี้มีประโยชน์สำหรับฉัน
Kristopher Johnson

1
ทั้งสองรู้ดีว่ากรณีของฉันดูเหมือนจะไม่ทำอะไรเลยถ้าไม่มีพวกเขา
โอเว่น B

1
มันทำงานได้ขอบคุณคุณ! ขอให้พระเจ้าคุ้มครอง .
Vivek

16

แม้ว่าจะได้รับคำตอบหลายครั้ง

หากเริ่มกิจกรรมใหม่จากส่วนฉันจะทำเช่นนั้น:

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

ดังนั้นคุณอาจคิดว่านี่มันเกินความจริงไปหน่อย แต่การHandlerโพสต์ช่วยให้คุณสามารถเรียกสิ่งนี้ในวิธีวงจรชีวิต ฉันใช้สิ่งนี้ในonRestart/ onResumeวิธีเมื่อตรวจสอบว่ามีการเปลี่ยนแปลงสถานะระหว่างผู้ใช้กลับมาที่แอปหรือไม่ (ติดตั้งบางสิ่ง)

หากไม่มีHandlerคุณเรียกมันในที่แปลก ๆ มันจะฆ่ากิจกรรมและไม่เริ่มต้นใหม่

อย่าลังเลที่จะถามคำถามใด ๆ

ไชโยคริส


2
ทางออกที่ดีและการใช้เหตุผล / คำอธิบายที่ดีมากสำหรับผู้จัดการ
JRomero

1
ทำไมคุณโทรถึงสองครั้งเพื่อ "overridePendingTransition"
นักพัฒนา android

1
@androiddeveloper ฉันจำไม่ได้ฉันคิดว่ามันเป็นงานที่ต้องแก้ไขข้อบกพร่อง คุณสามารถเรียกมันหนึ่งครั้งก่อน startActivity () และมันจะทำตามที่บอก
Chris.Jenkins

หลังจากใช้สิ่งนี้ในฟังก์ชั่น onResume ของฉันเกมจะหยุดที่วิธี onStop ของฉันและมีหน้าจอสีดำ ... ไม่แน่ใจว่าทำไม
Scumble373

1
สวัสดีคริสคุณช่วยอธิบายเรื่องนี้ให้ไกลหน่อยได้ไหม "โดยไม่ต้องใช้ตัวจัดการถ้าคุณเรียกมันในที่แปลก ๆ มันจะฆ่ากิจกรรมและไม่ต้องเริ่มต้นใหม่" ?
parvez rafi

15

อย่างนี้ไม่ได้อยู่ในรายการ แต่คอมโบของบางอย่างที่โพสต์แล้ว:

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

มันใช้งานได้สำหรับฉัน .. ขอบคุณ .. แต่ฉันต้องการถามคุณ: ทำไมเมื่อฉันลบส่วนแรกของรหัส (ส่วนที่ตรวจสอบ SDK_INT) แอปของฉันทำงานค่อนข้างช้า? !! .. เมื่อฉันแนบรหัสอีกครั้งมันทำงานได้ค่อนข้างเร็วกว่า !!!
McLan

2
ไม่แน่ใจในเรื่องนั้น ถ้าคุณใช้ SDK ที่เป็น> = 11 ให้สร้างใหม่ () ควรเร็วกว่าการตั้งใจให้เสร็จแล้วเริ่มใหม่อีกครั้ง เสร็จสิ้นการเรียกรหัสที่วิ่งไปที่ onStop และสร้างรหัสที่เรียกใช้ใหม่เช่นการเปลี่ยนการวางแนว ... ดังนั้นจึงไม่น่าทำมากนัก
Codeversed

4

ร่วมกับพฤติกรรมวงจร SurfaceView แปลกกับกล้อง ฉันพบว่าการสร้างใหม่ () ทำงานได้ไม่ดีกับวงจรชีวิตของ SurfaceViews surfaceDestroyed ไม่เคยถูกเรียกในระหว่างรอบการพักผ่อนหย่อนใจ มันถูกเรียกใช้หลังจาก onResume (แปลก) ตรงจุดที่ SurfaceView ของฉันถูกทำลาย

วิธีดั้งเดิมของการสร้างกิจกรรมใหม่ทำงานได้ดี

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

ฉันไม่สามารถเข้าใจได้อย่างชัดเจนว่าทำไมถึงเป็นเช่นนี้ แต่เป็นเพียงการสังเกตที่หวังว่าจะสามารถให้คำแนะนำผู้อื่นได้ในอนาคตเพราะมันช่วยแก้ไขปัญหาของฉันที่ฉันมีกับ SurfaceViews


4

ฉันสงสัยว่าทำไมไม่มีใครพูดถึงIntent.makeRestartActivityTask()ซึ่งทำสิ่งนี้อย่างแม่นยำ

สร้าง Intent ที่สามารถใช้เรียกภารกิจของแอ็พพลิเคชันอีกครั้งในสถานะพื้นฐาน

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

วิธีนี้ตั้งIntent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASKเป็นค่าเริ่มต้น


3

จริงๆแล้วรหัสต่อไปนี้ใช้ได้กับ API ระดับ 5 ขึ้นไปดังนั้นหาก API เป้าหมายของคุณต่ำกว่านี้คุณจะพบสิ่งที่คล้ายกับรหัสของ EboMike มาก

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

3

มีวิธีแฮ็กหนึ่งที่ควรทำงานกับกิจกรรมใด ๆ รวมถึงวิธีหลัก

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

เมื่อมีการเปลี่ยนแปลงการวางแนวโดยทั่วไป Android จะสร้างกิจกรรมของคุณใหม่ (เว้นแต่คุณจะแทนที่) วิธีนี้มีประโยชน์สำหรับการหมุน 180 องศาเมื่อ Android ไม่สร้างกิจกรรมของคุณใหม่


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

ลองใช้สิ่งนี้ ..


3

ทางออกสำหรับคำถามของคุณคือ:

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

คุณต้องแปลงเป็นบริบทของกิจกรรมเพื่อเริ่มกิจกรรมใหม่และเพื่อให้กิจกรรมปัจจุบันเสร็จสิ้น

หวังว่าสิ่งนี้มีประโยชน์ .. และใช้ได้สำหรับฉัน


1

หากคุณลบบรรทัดสุดท้ายคุณจะสร้างactกิจกรรมใหม่แต่อินสแตนซ์เก่าของคุณจะยังคงอยู่

คุณต้องการเริ่มกิจกรรมใหม่เช่นเมื่อมีการเปลี่ยนทิศทาง (เช่นรัฐของคุณได้รับการบันทึกและส่งผ่านไปยังonCreate(Bundle))?

ถ้าคุณทำไม่ได้วิธีแก้ปัญหาที่เป็นไปได้หนึ่งอย่างก็คือการใช้กิจกรรมหลอกตาเพิ่มเติมซึ่งจะเริ่มจากกิจกรรมแรกและงานใดที่จะเริ่มต้นอินสแตนซ์ใหม่ของมัน หรือเพียงแค่ชะลอการเรียกไปที่act.finish()หลังจากที่มีการเริ่มต้นใหม่

หากคุณต้องการบันทึกส่วนใหญ่ของรัฐคุณจะได้รับในน่านน้ำลึกสวยเพราะมันไม่สำคัญที่จะผ่านคุณสมบัติทั้งหมดของรัฐของคุณโดยเฉพาะอย่างยิ่งโดยไม่ต้องรั่วบริบท / กิจกรรมเก่าของคุณโดยการส่งผ่านไปยังอินสแตนซ์ใหม่

โปรดระบุสิ่งที่คุณพยายามจะทำ


1
ฉันมีปุ่มที่ใช้ชุดรูปแบบที่แตกต่างกับแอพหลังจากใช้ชุดรูปแบบแล้วมันจะถูกบันทึกตามความต้องการกิจกรรมรากจะรีสตาร์ทอ่านชุดรูปแบบจากการตั้งค่าใช้ชุดรูปแบบใน onCreate () ปรากฎว่ารหัสข้างต้นทำงานได้ดีถ้ากิจกรรมไม่ใช่ single_instance ไม่แน่ใจว่าเป็นวิธีปฏิบัติที่ดีที่สุดหรือไม่

ขณะนี้ไม่มีการทำความสะอาดทาง SDK ปูต้องรีสตาร์ทกิจกรรมของคุณ AFAIK - ถ้าคุณจะทำอะไรไม่ได้รั่วไหลของคุณอาจจะดีไป :)
ดิมิทาร์ดิมิทรอฟ

0

นี่คือวิธีที่ฉันทำ

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

-1

หากคุณกำลังโทรจากบางส่วนจึงทำรหัสด้านล่าง

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

-4

คุณสามารถใช้

onRestart ()

วิธีการดังต่อไปนี้

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

และโทร onRestart ()ที่คุณต้องการเริ่มกิจกรรมปัจจุบันใหม่


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.