Android projemde iki activity var. İkisi arasında geçiş yaptığımda her seferinde activitydeki değiştirmiş olduğum bilgiler gidiyor. Yani activityi bir nevi yeniden başlatıyor gibi. Sorunu nasıl çözebilirim?

Sharedprefences tarzı yerlere kaydedip yeniden çağırmak gibi bir çözüm geliyor aklıma ama daha kolay yolu vardır muhtemelen. Her bileşen için veri kaydetmek mantıksız geliyor çünkü.

Teşekkürler.

soruldu: 21 Şub '14, 06:40

kaptan's gravatar image

kaptan
445334244
cevap kabul oranı: 0%

değiştirildi: 23 Şub '14, 08:14

rahmanyazgan's gravatar image

rahmanyazgan ♦
4.4k83559


Merhaba

Activity nesnelerini AndroidManifest.xml dosyası üzerinden yapacağınız değişiklikle single instance olarak çalışmasını sağlayabiliyorsunuz.

<activity
  android:name="com.x.x.Activityx"
  android:label="@string/title_activity_x" 
  android:launchMode="singleInstance">
</activity>

Yine Activity sınıfının onCreate,onStart,onDestroy methodlarını override edip bir log kaydı atarak yaşam döngüsünü inceleyebilirsiniz.

Her ne kadar Activity'leri xml single instance olarak çalışmasını sağlasanızda telefonun geri tuşuna bastığınızda activity null olacaktır.

Geri tuşuna bastığınızda single instance olarak çalışan activity'nizin null duruma düşmemesi için aşağıdaki gibi onBackPressed methodunu boş olarak override etmeniz yeterli olacaktır.

@Override
public void onBackPressed() {
  //super.onBackPressed();
}

Kolay gelsin.

permanent link

cevaplandı: 21 Şub '14, 17:56

ismailkocacan's gravatar image

ismailkocacan
2.4k31733
cevap kabul oranı: 13%

değiştirildi: 28 Şub '15, 05:46

1

Teşekkürler. Ben de böyle kolay bir yolu vardır diye düşünüyordum ;)

(25 Şub '14, 05:14) kaptan kaptan's gravatar image

Her işlemin (process) olduğu gibi activity yapılarının da bir yaşam döngüsü vardır. Bir activity'den diğerine geçişte olduğu gibi, ekran yönünü (orientation) değiştirme işlemi de çalışma zamanında ki activity'nin sonlandırılması, hafızadan silinmesi ve sonrasında yeni ekran yönü ile yeniden oluşturulmasına sebep olur.

Activity yaşam-döngüsü

Değişen nesne bilgisini (sizde textView) activity'ler arası geçiş sonrasında tutmak istiyorsanız, onSaveInstanceState() fonksiyonunu aşağıdaki gibi uygulamalısınız:

@Override
protected void onSaveInstanceState(Bundle state) 
{
    super.onSaveInstanceState(state);
    state.putSerializable("mystate", <textView nesnenizin ismi>);
}

Böylece textView içerisinde ki veri mystate anahtarı ile bundle içerisinde tutulur. Bu fonksiyon Android tarafından yaşam-döngüsünde onStop() fonksiyonundan önce yürütülür.

Esasında, bir activity'nin bundle'ına bir state koyup, diğer bir activity'nin bu state'i çalıştırıp, birinci activity'nin state'i içerisinde kine sahip olmayı bekleyemezsiniz.

activity içerisinde kayıtlı kalmasını istediğiniz veri, bundle içerisinde string türünde saklanır. Bu saklanan verinin state'ine programlama tekniği ile erişmek mümkün. Aşağıdaki fonksiyon ikinci activity'ye aittir ve birinci activity'nin kayıtlı durumuna erişmek için kullanılır.

@Override
protected void onCreate(Bundle bundle) 
{
    super.onCreate(bundle);
    setContentView(R.layout.activity_data_entry);

    mytextView = (TextView) findViewById(R.id.text_id);

    if ((bundle != null) && (bundle.getSerializable("mystate") != null)) 
    {
       <textView nesnenizin ismi> = (TextView) bundle.getSerializable("mystate");
    }
}

activity'nizin durumunu saklamanın diğer bir yolu ise onRestoreInstanceState() fonksiyonu kullanmaktır:

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) 
{
   super.onRestoreInstanceState(savedInstanceState);
   <textView nesnenizin ismi> = (TextView) savedInstanceState.getSerializable("mystate);
}
permanent link

cevaplandı: 21 Şub '14, 10:24

cagcak's gravatar image

cagcak
16271320
cevap kabul oranı: 25%

Activityler arasında veri göndermede sorun yok. Bundle kullanıyorum. Sorun şu. Activity1 de bir textviewi değiştirdim diyelim. Daha sonra butona tıklayıp activity2 ye geçiş yaptırdım. Activity2 den de geri düğmesine tıklayınca activity1 e geldiğinde değiştirmiş olduğum textview eski haline geliyor. onSaveInstanceState ve onRestoreInstanceState fonksiyonlarını kullandım sonrasında. Ama yine düzelmedi. Kodları paylaşırım.

(21 Şub '14, 08:13) kaptan kaptan's gravatar image

logcat kayıtlarını da paylaşabilir misiniz?

(21 Şub '14, 10:25) cagcak cagcak's gravatar image

Cevaplayanlara teşekkürler.
cagcak sizin verdiğiniz koda göre düzenledim. Aynı şekilde yapıyordum ama getString putString metodlarını kullanarak yapıyordum. Tabi activity create bölümünde veri aktarmayı yapmıyordum onRestore... metodunda otomatik yapar diye.

Sizinkine göre düzenleyeyim dedim ama hata verdi.

outState.putSerializable("mystate", tv1);

satırında hata verdi. Öneriyi yaptım ama bu sefer de programda hata verdi. Şu anki kodlar aşağıda. Butona tıklandığında tv1i settext ile deneme yapıyorum. ikinci activitye yönlendiriyorum. 2. activityden 1. ye dönüşte deneme yazısı kayboluyor yine hello worlde dönüşüyor tv1... Tabi şu anki kodlarla hata veriyor program duruyor.


package com.ceylan.actionbar;
import java.io.Serializable;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
    Button ikiyegit;
    TextView tv1;
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onRestoreInstanceState(savedInstanceState);
        tv1 = (TextView) savedInstanceState.getSerializable("mystate");
    }
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        super.onSaveInstanceState(outState);
        outState.putSerializable("mystate",(Serializable) tv1);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ikiyegit=(Button)findViewById(R.id.ikiyegit);
        tv1=(TextView)findViewById(R.id.textView1);
        if ((savedInstanceState != null) && (savedInstanceState.getSerializable("mystate") != null)) 
        {
           tv1 = (TextView) savedInstanceState.getSerializable("mystate");
        }
        ikiyegit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                tv1.setText("deneme");
                Intent intent = new Intent(MainActivity.this, IkiActivity.class);
                startActivity(intent);
            }
        });
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}
Kodlar bunlar. Şu anki logcat;

02-21 15:57:44.352: I/Choreographer(1145): Skipped 59 frames!  The application may be doing too much work on its main thread.
02-21 15:57:44.442: D/gralloc_goldfish(1145): Emulator without GPU emulation detected.
02-21 15:57:46.812: I/Choreographer(1145): Skipped 56 frames!  The application may be doing too much work on its main thread.
02-21 15:57:47.472: I/Choreographer(1145): Skipped 41 frames!  The application may be doing too much work on its main thread.
02-21 15:57:47.812: I/Choreographer(1145): Skipped 124 frames!  The application may be doing too much work on its main thread.
02-21 15:57:48.204: I/Choreographer(1145): Skipped 32 frames!  The application may be doing too much work on its main thread.
02-21 15:57:48.753: D/AndroidRuntime(1145): Shutting down VM
02-21 15:57:48.753: W/dalvikvm(1145): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
02-21 15:57:48.833: E/AndroidRuntime(1145): FATAL EXCEPTION: main
02-21 15:57:48.833: E/AndroidRuntime(1145): java.lang.ClassCastException: android.widget.TextView cannot be cast to java.io.Serializable
02-21 15:57:48.833: E/AndroidRuntime(1145):     at com.ceylan.actionbar.MainActivity.onSaveInstanceState(MainActivity.java:29)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at android.app.Activity.performSaveInstanceState(Activity.java:1147)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1216)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3129)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3188)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at android.app.ActivityThread.access$900(ActivityThread.java:141)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1261)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at android.os.Looper.loop(Looper.java:137)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at android.app.ActivityThread.main(ActivityThread.java:5041)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at java.lang.reflect.Method.invokeNative(Native Method)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at java.lang.reflect.Method.invoke(Method.java:511)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-21 15:57:48.833: E/AndroidRuntime(1145):     at dalvik.system.NativeStart.main(Native Method)
(21 Şub '14, 10:54) kaptan kaptan's gravatar image

burada bizi ilgilendiren hata:

java.lang.ClassCastException: android.widget.TextView cannot be cast to java.io.Serializable

Yani TextView nesnesinin Serializable olarak davranamadığını haber veriyor. Bu hatayı onarmanın birkaç yolu var. Lütfen tümünü deneyiniz:

  • R.java sınıfının yeniden oluşturulması gerekli; kullandığınız platforma (eclipse, android studio,..) bağlı olarak, fix project - clean - rebuilt adımlarını izleyin.
  • Büyük bir ihtimalle fark olmayacaktır. Bu durumda TextView id'lerini değiştirip tekrar deneyin.
  • outState.putSerializable("mystate",(Serializable) tv1); satırında (TextView) cast'ını da ekleyin: outState.putSerializable("mystate",(Serializable) (TextView) tv1); Ama bu sonuçtan emin değilim
  • Aşağıdaki kod blokunu adapte edin:
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) 
{
   <textView nesnenizin ismi> = (TextView) savedInstanceState.getSerializable("mystate");
   Bundle mybundle = savedInstanceState.getBundle("mystate");

super.onRestoreInstanceState(savedInstanceState);      
}
(21 Şub '14, 11:51) cagcak cagcak's gravatar image

@cagcak onerin cozum degil cast hatası alman cok normal, cunku TextView sınıf Serializable interface'ini implemente etmez. TextView kısmen pahalı(cok üyedegiskeni vs var) bir nesnedir serilize edilmesi de mantıklı degildir. belirttiginiz probleme cozum olarak sadece textview'in text'ini(string) yedeklemeniz(save-restore) ihtiyacınızı karsılıyacaktır.

(22 Şub '14, 09:17) gturedi gturedi's gravatar image

bir activity'den diğerine bilgi göndermek istiyorsanız intent'e putExtra methodlarıyla veri eklemeniz yeni açılan activity de bu verileri getIntExtra gibi methodlarla intent'ten almanız gerekiyor(kendi nesnelerinizi intent ile taşımak isterseniz serializable arayüzü uygulanmış bir sınıftan oluşturulmuş olmaları gerekiyor). bulunan activity'nin verileri kayboluyorsa onSaveInstanceState ve onRestoreInstanceState fonksiyonlarını incelemenizde fayda var. ayrıca arayüzdeki viewler'in id'lerinin de bulunması gerekiyor.

permanent link

cevaplandı: 21 Şub '14, 07:08

baran's gravatar image

baran
2.1k81939
cevap kabul oranı: 30%

2 activity arasında veri alışverişi için Bundle 'ları kullanabilirsiniz.

permanent link

cevaplandı: 21 Şub '14, 08:10

tamercan's gravatar image

tamercan
3945
cevap kabul oranı: 4%

kaptan selamlar eklediğin logcat ekranında thread hatası var gibi .Bu konuya da bakabılırmısın arayuz processi ile actvity processlerini ayıran bir thread başlatırmısın.

Su satır : at android.app.ActivityThread.main(ActivityThread.java:5041)

Kolay gelsin

permanent link

cevaplandı: 26 Şub '14, 10:49

Numan's gravatar image

Numan
673101422
cevap kabul oranı: 6%

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("textView1", newText);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//bu activity recreate edilmiş mi?
if( savedInstanceState != null ) {
String newText = savedInstanceState .getString("textView1")
tv1.setText(newText);   }
}
//Eger bu activity recreate etmediyse newText = NULL olur 
@Override
public void onRestoreInstanceState (Bundle savedInstanceState) {
if( savedInstanceState != null ) {
String newText = savedInstanceState .getString("textView1")
tv1.setText(newText);   }
}
//Activity kapanırken, yani onPause callback metodu çağrıldığında
//TextView'in text kısmına yazdığımı newText stringine atıyorum
String newText;
@Override
public void onPause() {
super.onPause();
newText = tv1.getText().toString();
}
permanent link

cevaplandı: 24 Şub '15, 10:13

altan_518's gravatar image

altan_518
444127
cevap kabul oranı: 15%

değiştirildi: 26 Şub '15, 07:25

Butona bastığında, diğer activity'ye geçerken ilk activity'nin onPause() metodu çalışır. Sen bu metodun içine TextView'e yazılan son yazıyı string olarak kaydedersen, ikinci activity'den de tekrar ilk activity'ye dönersen; eğer ilk activity recreate olursa (Bu demektir ki ilk activity back stack'de değil, background'da saklanıyor), ilk activity'nin çalışak ilk fonksiyonu onRestoreInstanceState(Bundle) olacaktır. Bu metodun içine newText stringini Bundle ile atarız. En son olarak da tv1 textview'inin text'ini newText'i set edersen sorun çözülür

(24 Şub '15, 10:28) altan_518 altan_518's gravatar image
Cevabınız
toggle preview

Bu soruyu takip et

E-Posta üzerinden:

Üyelik girişi yaptıktan sonra abonelik işlemlerini yapabilirsiniz

RSS üzerinden:

Cevaplar

Cevaplar ve Yorumlar

Yazı Formatlama

  • *italic* ya da _italic_
  • **bold** ya da __bold__
  • link:[text](http://url.com/ "başlık")
  • resim?![alt text](/path/img.jpg "başlık")
  • liste: 1. Foo 2. Bar
  • temel HTML etiketleri de kullanılabilir

Bu sorunun etiketleri:

×819
×8
×2
×1

Soruldu: 21 Şub '14, 06:40

Görüntüleme: 2,587 kez

Son güncelleme: 28 Şub '15, 05:46

powered by BitNami OSQA