Prawidłowe użycie zmiennych globalnych w aplikacji na androida

0

W chwili stworzenia aktywności mam wylosować liczbę, a po naciśnięciu przycisku wypisać ją. Zadanie zostało wykonane, jest jednak jeden haczyk (a jak tam, bez haczyka to tak smutno). Podczas obrotu aplikacji, tracę tą liczbę, wiem że jest w takiej chwili niszczona aktywność i do nowa robiona- stąd ten problem. Nie powoduje to jednak że jestem bliżej rozwiązania, a wręcz przeciwnie.

Próbowałam użyć zmiennej globalnej, naprawdę wiele razy. Zawsze coś nie grało ostatnio to cała aplikacja pada.

O to działający kod(Bez implementacji zmiennej globalnej):

package pl.ww.example.android.klikaaktywnosci;


import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class KilkaAktywnosciActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Losuj Losuj_liczbe =new Losuj();
        int wylosowana_liczba = Losuj_liczbe.losuj_liczby();

       SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
       editor.putInt("randomowa_liczba", wylosowana_liczba);
        editor.apply();


    }

    public void onClick(View s)
    {
       SharedPreferences prefs = getPreferences(MODE_PRIVATE);
       int wylosowana_liczba = prefs.getInt("randomowa_liczba", 1);

        final TextView TextViewNumber = (TextView) findViewById(R.id.wylosowana);

        TextViewNumber.setText(""+wylosowana_liczba);
    }
}

A klasa globalna :

package pl.ww.example.android.klikaaktywnosci;

import android.app.Application;
import java.util.Random;
import android.util.Log;

public class GlobalClass extends Application {
    private int number;

    public GlobalClass(){
     number=111;
    }
    public int getNumber() {
        return number;
    }
    public void setNumber(int number) {
        this.number = number;
    }
}

Czy ona jest w porządku? Ja chce tylko wylosować liczbę zapisać ją w zmiennej która przetrwa, a jeśli jest tam coś to biorę a nie losuje. Liczba 111 jest nie możliwa do wylosowania, stąd dałam ją na konstruktor :P.

Co powinnam dodać w kodzie? Aby korzystać z zmiennej globalnej lub w jakiś inny sposób sprawić aby mi ta liczba nie znikała...

dodanie znaczników <code class="java"> - @furious programming

0

Nie znam Javy i mowie Ci na podstawie analogii do innych jezykow programowania:
Czytajac Twoj post jestem w stanie smialo powiedziec ze nie rozumiesz klas i powinienes/nas sie douczyc.

Zmienne globalne sa prawie zawsze zle, a jedyny przypadek kiedy jestem w stanie powiedziec ze sa ok, to gdy nie jest to zmienna tylko stala (PI jest dobrym przykladem).

Jakkolwiek zle by nie byly, prawdpodobnie latwiej bedzie skorzystac Ci ze slowa kluczowego static niz Tworzenie jakis dziwnych klas.

Przykladowo:
private static int staticNumber;

te pole nie nalezy do zadnej instancji klasy i powinno istniec od uruchomienia do zamkniecia programu.

1

Globalne zmienne to zło. Nadpisz metodę

 onSaveInstanceState(Bundle savedInstanceState)

i tam zapisz liczbę w obiekcie Bundle. Następnie wyciągnij ją z obiektu Bundle w metodzie onCreate(Bundle savedInstanceState)

 gdy zostanie ponownie utworzona aktywność (po zmianie orientacji).
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
0
package pl.ww.example.android.klikaaktywnosci;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class KilkaAktywnosciActivity extends Activity {
    int liczba;
    private static String wylosowana_liczba;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main);
       if (savedInstanceState != null) {
           
            liczba = savedInstanceState.getInt(wylosowana_liczba);

        } else {
            // Probably initialize members with default values for a new instance
            Losuj Losuj_liczbe =new Losuj();
            liczba = Losuj_liczbe.losuj_liczby();
           savedInstanceState.putInt(wylosowana_liczba,liczba);
        }


    }
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {

        Losuj Losuj_liczbe =new Losuj();
        liczba = Losuj_liczbe.losuj_liczby();
        savedInstanceState.putInt(wylosowana_liczba, liczba);

        super.onSaveInstanceState(savedInstanceState);
    }
   public void onRestoreInstanceState(Bundle savedInstanceState) {

        super.onRestoreInstanceState(savedInstanceState);

        liczba = savedInstanceState.getInt(wylosowana_liczba);
    }
    public void onClick(View s)
    {
        final TextView TextViewNumber = (TextView) findViewById(R.id.wylosowana);

        TextViewNumber.setText(""+liczba);
    }
}
 

Aplikacja mi się aktualnie nie włacza. Co robię źle? on Create patrze czy juz jest instancja jak nie wywołuje funkcje losuj i zapisuje wynik do zmiennej globalnej przez saved instance

1
package pl.ww.example.android.klikaaktywnosci;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class KilkaAktywnosciActivity extends Activity {
    int liczba;
    private static String wylosowana_liczba; // w tym momencie to jest null, jeśli ma to być stała dodaj słowo kluczowe final, zmien nazwe na WYLOSOWANA_LICZBA i zainicjalizuj ją w  miejscu deklaracji np
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main);
       if (savedInstanceState != null) {
           
            // wylosowana_liczba jest nullem
            liczba = savedInstanceState.getInt(wylosowana_liczba);

        } else {
            // Probably initialize members with default values for a new instance
            Losuj Losuj_liczbe =new Losuj();
            liczba = Losuj_liczbe.losuj_liczby();
           savedInstanceState.putInt(wylosowana_liczba,liczba); // nie ma potrzeby zapisywania tutaj liczby do obiektu Bundle
        }


    }
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {

        Losuj Losuj_liczbe =new Losuj(); // złe nazewnictwo, patrz niżej
        liczba = Losuj_liczbe.losuj_liczby(); // liczba została wylosowana juz wczesniej, nie ma potrzeby jej losowac tutaj
        savedInstanceState.putInt(wylosowana_liczba, liczba); 

        super.onSaveInstanceState(savedInstanceState); // powinno byc wywołane jako pierwsze w tej metodzie
    }
   public void onRestoreInstanceState(Bundle savedInstanceState) { // jesli przywracasz stan w onCreate to ta metoda jest zbędna

        super.onRestoreInstanceState(savedInstanceState);

        liczba = savedInstanceState.getInt(wylosowana_liczba);
    }
    public void onClick(View s)
    {
        final TextView TextViewNumber = (TextView) findViewById(R.id.wylosowana);

        TextViewNumber.setText(""+liczba);
    }
}

Dodałem kilka komentarzy..

0

Chodzi teraz, ale nadalpodczaszmiany orientacji nie ma liczby, znika ona...

package pl.ww.example.android.klikaaktywnosci;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.util.Random;

public class KilkaAktywnosciActivity extends Activity {
    /** Called when the activity is first created. */
    int liczba;
    final private static String WYLOSOWANA_LICZBA="";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); // Always call the superclass first
        setContentView(R.layout.main);
       if (savedInstanceState != null) {
            // Restore value of members from saved state
            liczba = savedInstanceState.getInt(WYLOSOWANA_LICZBA);

        } else {
            // Probably initialize members with default values for a new instance
            Losuj Losuj_liczbe =new Losuj();
            liczba = Losuj_liczbe.losuj_liczby();
        }


    }
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {

        super.onSaveInstanceState(savedInstanceState);
        savedInstanceState.putInt(WYLOSOWANA_LICZBA, liczba);

    }
    public void onClick(View s)
    {
        final TextView TextViewNumber = (TextView) findViewById(R.id.wylosowana);

        TextViewNumber.setText(""+liczba);
    }
}
1

TextView ma to do siebie, że nie zapamiętuje wartości podczas zmiany orientacji ekranu, po to zapisujesz ją w zmiennej liczba. Zatem po zmianie orientacji wystarczy ponownie ustawic tekst w TextView, a jak to zrobić pozostawiam już Tobie do rozkminienia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1