[Android] Problem z konstruktorem.

[Android] Problem z konstruktorem.
M1
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:16
0

Witam.
Tworze obiekt myBase za pomocą konstruktora przekazujac do niego "12345", nastepnie wywoluje myBase.showIMEI i nie potrafie zrozumiec dlaczego w pierwszym Logu zwraca mi prawidlowo "12345", a w drugim logu zamiast "12345" wychodzi null ?

MainActivity.class:

Kopiuj
public class MainActivity extends AppCompatActivity {

    public static String IMEI = "12345";
    public static Baza myBaza = new Baza(IMEI);

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

       myBaza.showIMEI();

    }

}

Baza.class:

Kopiuj
public class Baza {

    public String myIMEI;
    public String nr = "number: "+myIMEI;


    public Baza(String IMEI){
        myIMEI = IMEI;
    }

    public void showIMEI(){
        Log.d("Test", myIMEI); // <--- Tutaj zwraca prawidlowo "12345"
        Log.d("Test", nr); // <-- tutaj zwraca "number: null" , a powinno "number: 1235"
}
}

edytowany 1x, ostatnio: marines.1
HA
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad rok
  • Postów:115
1

Wyświetla się null z tego powodu ze w momencie inicjalizacji zmiennej "nr" zmienna myIMEI jest równa "null".
Od tego momentu nr to "number: null"
Konstruktor który zmienia myIMEI z "null" na wartość podaną w parametrze konstruktora wykonuje się po inicjalizacji zmiennych składowych, więc trochę za późno.

edytowany 2x, ostatnio: Hagefid
M1
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:16
0

Dzieki za podpowiedz, nie bylem pewny wlasnie w jakiej kolejnosci to idzie, czy konstruktor pierwszy czy inicjalizacje.
A moze zna ktos jakas podpowiedz, aby konstruktor zadzialal jeszcze przed inicjalizacjami , lub moze zastosowac jakies inne rozwiazanie ?

HA
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad rok
  • Postów:115
1

Po prostu ustaw wartość zmiennej nr w konstruktorze:

Kopiuj
   public String myIMEI;
    public String nr;
 
    public Baza(String IMEI){
        myIMEI = IMEI;
         nr = "number: "+myIMEI;
    }
M1
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:16
0

Teoretycznie mozna by to teoretycznie zastosowac w powyzszym przykladzie, ale ja ten powyzszy przyklad tylko przedstawilem teoretycznie, poniewaz rozwiazanie chcialem zastosowac w moim projekcie, a tam juz to nie przejdzie.
Konkretnie chodzi o taki kod w moim projekcie:
...

Kopiuj

public class Baza {

    Context context;
    //Polacz z baza
    FirebaseDatabase database = FirebaseDatabase.getInstance();

    //Firebase Storage
    FirebaseStorage storage = FirebaseStorage.getInstance();
    StorageReference storageReference = storage.getReference();
    public String date;
    //Data
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");


    public String mmIMEI;  // <---Tutaj chcialbym zeby zostal przekazany IMEI urzadzenia podczas tworzenia obiektu tej klasy w MainActivity

        // Tutaj dokladnie lezy moj problem "mmIMEI" tutaj ma sie znajdowac IMEI urzadzenia , wiec gdyby on byl przypisany w zmiennej powyzej to tutaj automatyczie tez by wystepowl, a niestety wychozi, ze jest null. nawet jesli konstruktorem przekaze IMEI do mmIMEI powyzej.
        DatabaseReference fireUzytkownicy = database.getReference("Uzytkownicy/" + mmIMEI + "/Polaczenie");
        DatabaseReference fireOstatniaAkt = database.getReference("Uzytkownicy/" + mmIMEI + "/OstatniaAkt");
        DatabaseReference fireKomendy = database.getReference("Uzytkownicy/" + mmIMEI + "/Komendy");
        DatabaseReference fireGps = database.getReference("Uzytkownicy/" + mmIMEI + "/GPS");
        DatabaseReference fireStan = database.getReference("Uzytkownicy/" + mmIMEI + "/Stan_modulow");
        DatabaseReference fireLogi = database.getReference("Uzytkownicy/" + mmIMEI + "/Logi");
        //

...

HA
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad rok
  • Postów:115
0

Rozwiązanie tego problemu jest praktycznie takie samo jak Ci pokazałem. Twórz te obiekty w konstruktorze, bo inaczej zostaną one utworzone zanim mmIMEI zostanie ustawiony na prawidłową wartość.

M1
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:16
0

Rzeczywiscie kolego , miales racje ten sposob zadzialal tak jak trzeba.

Kopiuj
...
public class Baza {

    public Baza(String IMEI){
       mmIMEI = IMEI;
        fireUzytkownicy = database.getReference("Uzytkownicy/" + mmIMEI + "/Polaczenie");
        fireOstatniaAkt = database.getReference("Uzytkownicy/" + mmIMEI + "/OstatniaAkt");
        fireKomendy = database.getReference("Uzytkownicy/" + mmIMEI + "/Komendy");
        fireGps = database.getReference("Uzytkownicy/" + mmIMEI + "/GPS");
        fireStan = database.getReference("Uzytkownicy/" + mmIMEI + "/Stan_modulow");
        fireLogi = database.getReference("Uzytkownicy/" + mmIMEI + "/Logi");
    }

    Context context;
    //Polacz z baza
    FirebaseDatabase database = FirebaseDatabase.getInstance();

    //Firebase Storage
    FirebaseStorage storage = FirebaseStorage.getInstance();
    StorageReference storageReference = storage.getReference();
    public String date;
    //Data
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    public String mmIMEI;

    // Deklaracja folderow w bazie
    DatabaseReference fireUzytkownicy;
    DatabaseReference fireOstatniaAkt;
    DatabaseReference fireKomendy;
    DatabaseReference fireGps;
    DatabaseReference fireStan;
    DatabaseReference fireLogi;
    //
...
edytowany 2x, ostatnio: marines.1
M1
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:16
0

Nie moge uporac sie z jeszcze jednym problemem, poniewaz w MainActivity pobieram IMEI urzadzenia i chce go przekazac do konstruktora tworzacego obiekt klasy mojaBaza. Problem polega na tym, ze gdy pobiore IMEI w onCreate to jest juz za pozno zeby przeslac go do konstruktora, poniewaz obiekt mojaBaza jest tworzony na zamym poczatku deklaracji MainActivity, a nie moge utworzyc tego obiektu w onCreate, bo on rowniez jest wykorzystywany w wielu metodach w MainActivity.
I jeszcze jedno , gdy sprobuje pobrac IMEI na samym poczatku czyli w deklaracjach to wywala blad.

Kopiuj
...
public class MainActivity extends AppCompatActivity {

    public static Context context;

    static String mIMEI;
    public static Baza mojaBaza = new Baza(mIMEI);

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

        TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        mIMEI = telephony.getDeviceId();

    }
...
edytowany 2x, ostatnio: marines.1
HA
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad rok
  • Postów:115
0

Rozwiązanie w dalszym ciągu jest takie samo jak w poprzednich przypadkach. Stwórz obiekt Baza dopiero wtedy gdy juz bedziesz miał ten IMEI, czyli po linijce

Kopiuj
  mIMEI = telephony.getDeviceId();
  /// dodaj:
  mojaBaza = new Baza(mIMEI);
M1
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:16
0

Juz tak probowalem, ale niestety gdy zastosuje cos takiego to aplikacja uruchamia sie i od razu wysypuje :

Kopiuj
public class MainActivity extends AppCompatActivity {

    public static Context context;
    public static String mIMEI;

    TelephonyManager telephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    mIMEI = telephony.getDeviceId();

    public static Baza mojaBaza = new Baza(mIMEI);

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

}

Sprawdzalem debbugerem i wywala sie na tej linijce:

Kopiuj
    TelephonyManager telephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
edytowany 3x, ostatnio: marines.1
HA
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad rok
  • Postów:115
1

chodzilo mi zebys dodał

Kopiuj
mojaBaza = new Baza(mIMEI);

w funkcji onCreate, wtedy gdy masz juz IMEI,
To co przed chwilą pokazałeś nawet nie powinno się skompilować.

Na chwilę obecną najlepiej bedzie jak zapamietasz sobie by kod pisać w funkcjach. Nie definiuj wartości w polach.

edytowany 1x, ostatnio: Hagefid
M1
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:16
0

Jak moglem to przeoczyc. Teraz wszystko dziala i nauczka, zeby definiowac wartosci w metodach.
Wielkie dzieki za pomoc.

HA
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad rok
  • Postów:115
0

Jednak warto żebyś wiedział, że czasami trzeba definiować niektóre wartości tak jak robiłeś. Dobrym przykładem tego jest definiowanie stałych:

Kopiuj
public static final int STALA = 2;
M1
  • Rejestracja:około 8 lat
  • Ostatnio:około 8 lat
  • Postów:16
0

Dokladnie tak jak mowisz, czasem jest taka potrzeba.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.