Diskuze: Android - Uložení ArrayListu do souboru na SD kartě
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 9 zpráv z 9.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.
https://docs.oracle.com/…lizable.html
public class Prvek implements java.io.Serializable {
// JE NUTNO JESTE PRIDAT serialVersionUID
private static final long serialVersionUID = -2010768942658426810L;
private String sbr;
private Path patC;
private Path patB;
private int zac;
private int kon;
private Paint barL;
private Paint barR;
private boolean akt;
private boolean zvl;
private int por;
...
}
a to same proved i u Bod
public class Bod implements java.io.Serializable {
// JE NUTNO JESTE PRIDAT serialVersionUID
private static final long serialVersionUID = -2010768942658426811L;
private int sl;
private float[] sou;
...
}
Po té by už mělo fungovat i to tvé první řešení
FileOutputStream fos = new FileOutputStream("prvky.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(prvekU);
oos.close();
Děkuji za rychlou reakci. Zkopíroval jsem do deklarace objektu Prvek implementaci Serializace + následující řádek s uvedenou konstantou serialVersionUID přesně tak, jak jsi mi poradil. Bohužel vůbec nic se nezměnilo. K chybám dochází úplně stejně jak jsem popsal, a to při obou variantách prvního řádku.
//1.
FileOutputStream fos = context.openFileOutput("prvky.dat",
//2.
FileOutputStream fos = new FileOutputStream("prvky.dat");
Při prvním způsobu se alespoň vytvoří FileOutputStream a k chybě dojde až při zápisu do ObjectOutputStreamu. Ve druhém případě se ani nevytvoří FileOutputStream. Přesto děkuji za snahu pomoci. Budu pátrat dál. Jarda
Pokud ti toto nepomohlo pak je problém v nečem jiném. Např. práva
přístupu, špatná kompilace, buildování, bug v JDK apod..
Ukládání/Načítání vlastních objektů(instancí) do souboru je skutečně
jednoduché a stačí pouze implementovat serializaci.
Mimochodem bez vypsání dané výjimky se velmi obtížně odhaduje kde je
chyba. Většinou je ve výpisu výjimky vypsáno v čem je problém.
Podařilo se ti tam uložit obyčejný řetezec, či text přes znakový proud
do stejného úložiště?
Proč nezvěřejníš celý kód ? Věř tomu že tvůj zdroják není fakt
žádné know-how, jedná se o velmi trapně jednoduchou záležitost.
Takto jednoduše ten zdroj v čistě v JAVE vypadá. Zkus to spustit případně upravit pro Android a uvidíš co to udělá.
import java.io.*;
class NeprimObjektTrida1 implements Serializable{
private static final long serialVersionUID = 49774409446745068L;
private int cislo1,cislo2;
NeprimObjektTrida1(int cis1,int cis2){ // konstruktor
this.cislo1 = cis1; this.cislo2 = cis2; }
public String toString(){ return "cislo1 ="+cislo1+"\tcislo2 ="+cislo2;}
}
public class O13_StreamObjekty {
public static void main(String [] args) throws IOException, ClassNotFoundException {
NeprimObjektTrida1 objektCislo = new NeprimObjektTrida1(48,35);
FileOutputStream souborObjekt = new FileOutputStream("souborObj.bin");
ObjectOutputStream objektUkladani = new ObjectOutputStream(souborObjekt);
objektUkladani.writeObject(objektCislo);
souborObjekt.close();
}
}
Tak jsem to vyřešil následovně: Zjistil jsem, že objekt třídy Prvek nešel uložit do souboru, přestože jsem ho deklaroval podle Tvého návodu takto
public class PrvekU implements java.io.Serializable {
private static final long serialVersionUID = -2010768942658426810L;
,
asi proto, že obsahoval objekty tříd Path a Paint. Tak jsem tyto objekty z
něj odebral, takže tam zbyly objekty tříd String, int, a boolean. Teď už
třída Prvek uložit do souboru jde. Ty objekty Path a Paint vlastně není
třeba mít uložené, protože se mohou inicializovat až po načtení objektu
Prvek a pak do něj přidat.
Takže mne to přece jen posunulo vpřed. Děkuji !
Když ti to funguje jak chceš pak je to OK. Nicméně pokud Path,Paint jsou opět tvoje třídy pak i těm je nutno implementovat Serizalizaci a přidat serialVersionUID a mělo by to taky fungovat. Obecně řečeno pokud máš objekty v objektu (tvz. kompozici) a chceš jejich stavy ukládat je nutno všem těm objektům implemtovat serializaci.
Pro příště doporučuji přidávej i výpis vyjímky + i zdroj + importy.
Tu serializaci na objekty Prvek a Bod jsem implementoval tak, že jsem jednoduše zkopíroval Tvůj kód, ale nerozumím mu. Vysvětli mi, prosím, jak jsi došel k té konstantě serialVersionUID, jak jsi získal to dlouhé číslo ? Díky.
Jednoduše řečeno : Pokud používáš při vývoji IDE, a k definici třídy dáš implementovat serializaci
class NeprimObjektTrida1 implements Serializable
pak ti samo IDE hodí Error nebo Warning a požaduje vytvoření proměnné "serialVersionUID" a definování její hodnoty s několika možnostmi generování.
Odborně řečeno : ( viz. https://docs.oracle.com/…lizable.html)
The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long:
Při serializaci je každé serializované třídě definovaný identifikátor, který pak slouží JVM u nacitani ze souboru (tvz. deserializaco) k ověření(porovnání) že se jedná o tu stejnou třídu. Kdyby se lišily pak asi JVM vyvolá vyjímku, ale tento test jsem si nikdy nevyzkoušel.
To je na mne bohužel až příliš odborné. Aplikace vyvíjím v Android
Studiu, tu serializaci jsem implementoval tak, jak jsi mi poradil,
l
public class PrvekU implements java.io.Serializable {
private static final long serialVersionUID = -2010768942658426810L;
ale než jsem to udělal, napsalo mi Studio pouze hlášku :
"Unfurtunately, Pohyb_prvku has stoped. OK". (Pohyb_prvku je název aplikace.)
Někdy používám debugging, ale ani Debugger mi nic nenapíše, pouze vidím
tu hlášku a nemůžu udělat nic než aplikaci ukončit.
Zobrazeno 9 zpráv z 9.