Android'de Etkinlik nasıl yeniden başlatılır?


381

Bir Android'i nasıl yeniden başlatırım Activity? Aşağıdaki denedim, ama Activitybasitçe çıkar.

public static void restartActivity(Activity act){

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

}

9
u "act.finish ();" olarak adlandırıldığından etkinlik sonlandırılır etkinliği oluşturduktan hemen sonra ...
Nikhil Dinesh

1
eski yöntem
pedjjj

Yanıtlar:


623

Tema değiştiricimi şöyle yaptım:

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

Temel olarak, önce arıyorum finish()ve bu etkinliğin başladığı aynı amacı kullanıyorum. Hile yapıyor gibi görünüyor mu?

GÜNCELLEME: Aşağıda Ralf tarafından belirtildiği gibi, Activity.recreate()API 11 ve ötesine geçmenin yolu. API11 + ortamındaysanız bu tercih edilir. Mevcut sürümü kontrol edebilir ve API 10 veya daha düşük bir sürümdeyseniz yukarıdaki kod snippet'ini arayabilirsiniz. (Lütfen Ralf'in cevabını oylamayı unutma!)


36
Ve bu aşağıya oy vermeye değer mi? Bu OP tarafından belirtilen bir gereklilik değildi. Aslında, istenebilir.
EboMike

9
Animasyonu sevmiyorsanız, kapatabilirsiniz (cevabınızda gösterildiği gibi). Bu benim cevabımı yanlış yapmıyor, sadece ekleyebileceğiniz bazı ek seçenekler göstermiyor (ve bu soruda sorulmadı).
EboMike

28
Bence yanlış anladın. Downvote yanlış / kötü cevap anlamına gelir ve upvote bir cevabın harika olduğu anlamına gelir. Bir cevabın diğerlerine kıyasla ne kadar büyük olduğu upvotes ile gösterilir. Cevabınızı yükseltmeye çalıştığınızı görebiliyorum, ancak sistemi bu amaçla kötüye kullanıyorsunuz.
EboMike

8
+1 - bu benim için harika çalıştı ve dediğiniz gibi animasyon istediğim bir şey, bu yüzden kullanıcı yeniden başlatıldığını biliyor. FWIW, soruya alternatif bir cevap verdiğimde diğer kullanıcıların cevaplarını asla aşağı oy etmemeyi bir kural haline getiriyorum, ancak cevabım sınıf dışı olduğunda zaman zaman yukarı oy kullanıyorum (burada olduğunu söylemiyorum, sadece bunu yaptığımı söylemiyorum) .
Michael Bray

4
EboMike ve Ben: Her iki çözümünüz de OP'nin sorusunu yanıtladı. Birisinin cevabını yalnızca "estetik" bir nedenden ötürü oylamak iyi değildir. Ben Stackoverflow de burada yapmaktan kimse cesaret ...
ChuongPham

368

API düzey 11'den (Honeycomb) beri , etkinliğin rekreasyon () yöntemini çağırabilirsiniz ( bu yanıt sayesinde ).

Rekme () yöntemi bir yapılandırma değişikliği gibi davranır, bu nedenle onSaveInstanceState () ve onRestoreInstanceState () yöntemleriniz de varsa çağrılır.


3
önceki etkinlik bunu startActivityForResult kullanarak çağırırsa ne olur?
android geliştirici

1
API 11'den daha düşük bir şeyi desteklemeniz gerekmiyorsa doğru yanıt budur.
Edward Falk

@EdwardFalk destek kitaplığında bunu yapan herhangi bir işlev var mı?
android geliştirici

2
Bu her durumda çalışmaz. Eğer rekreasyon () çağrılırken bir navigasyon çekmeceniz açıksa, yeniden yaratıldığında açık kalacaktır, bu da durumu kaydetmeyeceği anlamına gelir, bu da istenmeyebilir.
Chapz

Devletin kurtarılmasını istemeyen benim. Bazen insanlar sadece temiz bir yeniden başlatma isterler, o zaman EboMike'ın cevabını kullanmalıdırlar.
Kimi Chiu

132

SDK 11'den önce bunu yapmanın bir yolu şöyledir:

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

HTC Desire'da animasyonlar hala kalır (en azından onConfigurationChanged yönteminde kullanıldığında). Her zaman gerçekleşmezler, ancak EboMike kodunu kullanarak her zaman gerçekleşmezler.
Juozas Kontvainis

8
Bu, başlatıcı tarafından başlatılan ana etkinlik üzerinde çalışmaz. Faaliyetiniz, niyette ayarlanan bazı bayraklar nedeniyle gizlenecektir. Aksi takdirde güzel çalışıyor.
Thomas Ahle

İyi bir nokta. mantıklıdır çünkü yığındaki temel etkinlikten finish () öğesini çağırır.
Ben

Faaliyetin temasını değiştirirken bunu çağırmak hızı (animasyonlar olmadan) ortaya çıkarıyor gibi görünüyor
Ashok Goli

3
+1 Ana Faaliyette bile benim için iyi çalışıyor. Ancak, çağırmalıdır overridePendingTransition(0, 0);sonra finish()ve startActivity()bunu denilen yerde ... sırasıyla değil
gak

115

Sadece Ralf ve Ben'in cevaplarını birleştirmek için (yorumlarda yapılan değişiklikler dahil):

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
En iyi cevap. İster inanın ister inanmayın, hala API 3 cihazlarını destekliyorum ve VERSION.SDK_INT değeri API 4 gerektiriyor. :)
Edward Falk

31

Eski Android sürümlerini destekleyebilmem ve recreate()yeni Android sürümlerinde kullanabilmem için bu kodu kullandım .

Kod:

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

Örneklem:

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

benim için harika bir iş!
papo

22

Bu çözüm benim için çalıştı.

İlk önce aktiviteyi bitirin ve ardından tekrar başlatın.

Basit kod:

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

20

Bu, şu anki etkinliği yeniden başlatmanın en kolay yoludur:

finish();
startActivity(getIntent());

19

Bu yöntemi ara

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

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

Teşekkürler,


1
Bence OP sadece birincisi değil, herhangi bir aktiviteyi yeniden başlatmak istiyor, ama bu bana yardımcı oldu.
Kristopher Johnson

1
İki bayrağı bilmek güzel, davam onlarsız hiçbir şey yapmıyor gibiydi.
Owen B

1
sana teşekkür etti! çok yaşa .
Vivek

16

Bu defalarca cevaplanmış olmasına rağmen.

Bir etkinliği bir parçadan yeniden başlatırsanız, bunu şöyle yaparım:

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

Yani bunun biraz abartılı olduğunu mu düşünüyorsun? Ancak Handlergönderme, bunu bir yaşam döngüsü yönteminde çağırmanıza izin verir. Ben app geri gelen kullanıcı arasında durum değişip değişmediğini kontrol ederken onRestart/ onResumeyöntemlerinde kullandım. (bir şey yükledi).

Olmadan Handlerbir tek yerde ararsanız sadece aktiviteyi öldürmek ve yeniden başlatın olmaz.

Soru sormaktan çekinmeyin.

Şerefe Chris


2
Büyük çözüm ve Handler için çok iyi bir muhakeme / açıklama.
JRomero

1
Neden iki kez "overridePendingTransition" çağrıyorsunuz?
android geliştirici

1
@androiddeveloper Hatırlayamıyorum, sanırım bu bir hata için bir işti. StartActivity () 'den önce bir kez çağırabilirsiniz ve söylendiği gibi çalışacaktır.
Chris.Jenkins

Bunu onResume fonksiyonumda uyguladıktan sonra, oyun onStop metodumda duruyor ve siyah bir ekranı var ... neden olduğundan emin değilim
Scumble373

1
Merhaba chris, bunu biraz daha açıklayabilir misin "İşleyici olmadan tuhaf bir yerde çağırırsan, sadece aktiviteyi öldürecek ve yeniden başlatmayacaksın." ?
parvez rafi

15

Peki bu listelenmemiş ama zaten yayınlanan bazı birleşik:

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

Benim için çalışıyor .. teşekkürler .. ama size sormak istiyorum: neden kodun ilk kısmını (SDK_INT kontrol eden) kaldırdığımda benim app çalışır, nispeten yavaş? .. tekrar kodu yeniden eklediğinizde, nispeten daha açık ve çok daha hızlı çalışır !!!
McLan

2
Bundan emin değilim. Peki, = 11 olan bir SDK kullanıyorsanız, createte () niyeti almaktan, bitirmekten ve daha sonra tekrar başlatmaktan daha hızlı olmalıdır. OnStop üzerinde çalışan çağrı kodunu bitir ve yeniden yönlendirme değişikliği gibi kod çalıştırır ... bu yüzden o kadar çok şey yapmaz.
Kasım'da 13

4

Kamera ile garip SurfaceView yaşam döngüsü davranışıyla birlikte . Ben rekreasyon () SurfaceViews yaşam döngüsü ile iyi davranmıyor bulduk. rekreasyon döngüsü sırasında surfaceDestroyed hiç çağrılmaz. OnResume'den (garip) sonra çağrılır, bu noktada SurfaceView'im yok edilir.

Bir aktiviteyi yeniden yaratmanın orijinal yolu işe yarar.

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

Bunun tam olarak neden olduğunu anlayamıyorum, ancak umarım gelecekte başkalarına rehberlik edebilecek bir gözlem çünkü SurfaceViews ile yaşadığım sorunları düzeltti


4

Acaba neden kimsenin Intent.makeRestartActivityTask()bu amacı tam olarak temizlediğinden bahsetmedi .

Bir uygulamanın görevini * temel durumunda yeniden başlatmak için kullanılabilecek bir Niyet yapın.

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

Bu yöntem Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASKvarsayılan bayraklar olarak ayarlanır .


3

Aslında aşağıdaki kod API seviyeleri 5 ve üstü için geçerlidir, bu nedenle hedef API'niz bundan daha düşükse, EboMike koduna çok benzer bir şey elde edersiniz.

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

3

Ana faaliyet de dahil olmak üzere herhangi bir etkinlik üzerinde çalışması gereken tek bir yol var.

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

Yön değiştiğinde, Android genellikle etkinliğinizi yeniden oluşturur (siz geçersiz kılmadıkça). Bu yöntem, Android etkinliğinizi yeniden oluşturmadığında 180 derece dönüşler için kullanışlıdır.


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

bunu kullanmayı dene ..


3

Sorunuzun çözümü:

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

Yeni etkinliği başlatmak ve mevcut etkinliği bitirmek için etkinlik bağlamına yönlendirmeniz gerekir.

Umarım bu yararlı ... ve benim için çalışıyor.


1

Son satırı kaldırırsanız, yeni actEtkinlik oluşturacaksınız , ancak eski örneğiniz hala canlı olacaktır.

Yön değiştirildiği zamanki gibi Etkinliği yeniden başlatmanız mı gerekiyor (örn. Durumunuz kaydedilip bu konuma geçirilir onCreate(Bundle))?

Bunu yapmazsanız, olası bir geçici çözüm, ilk Etkinlik'ten başlatılacak ve yeni bir iş başlatmak için hangi işin başlatılacağı bir ek, sahte Etkinlik kullanmak olacaktır. Veya act.finish()yeni bir çağrı başlatıldıktan sonra çağrıyı erteleyin.

Devletin çoğunu kurtarmanız gerekiyorsa, oldukça derin sulara giriyorsunuz, çünkü eyaletinizin tüm özelliklerini, özellikle eski Bağlam / Faaliyetinizi sızdırmadan, yeni örneğe geçirerek geçirmek önemsiz değil.

Lütfen ne yapmaya çalıştığınızı belirtin.


1
Uygulamaya farklı temalar uygulayan bir düğme var, tema uygulandıktan sonra, tercih olarak kaydedilir, kök etkinlik yeniden başlatılır, temayı tercihten okur, temayı onCreate () 'de uygular. Etkinlik single_instance değilse yukarıdaki kodun iyi çalıştığı ortaya çıkıyor. Bunun en iyi uygulama olup olmadığından emin değilim.

Şu anda, Aktivitenizi yeniden başlatmanın temiz, SDK-döşeli bir yolu yok AFAIK - eğer bir şey sızdırmazsanız, gitmek için iyi olabilir :)
Dimitar Dimitrov

0

Ben böyle yapıyorum.

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

-1

Bazı parçalardan arıyorsanız, aşağıdaki kodu yapın.

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

-4

sadece kullanabilirsin

onRestart ()

yöntemi aşağıdaki gibi

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

ve geçerli Etkinliği yeniden başlatmak istediğiniz onRestart () yöntemini çağırın


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.