Keresés

Hirdetés

Új hozzászólás Aktív témák

  • thon73

    tag

    válasz WonderCSabo #1442 üzenetére

    Akkor csak a tanulság kedvéért. Vigyázat mindenki csukja be a szemét, hibás kód következik!

    public ABSTRACT class A extends ListFragment {

    public STATIC ListFragment newInstance() {
    return new ??getClass??();
    }
    }

    public class B extends A {
    }

    public class C extends A {
    }

    Az ötlet az volt, hogy B.newInstance() létrehoz egy B példányt, melyet ListFragment-ként visszaad, míg C.newInstance() létrehoz egy C példányt, melyet szintén ListFragmentként ad vissza.
    Ha a tényleges példány csak az abstract, mint minta alapján jönne létre, akkor a kérdőjeles rész mindig a példány osztálya lenne. De persze ez nem működik, legalábbis a static metódusban nincs ilyen hivatkozás. Nem staticban egyébként a this így működik, mentségemre legyen mondva.

    Utólag látom, hogy az egész hibás ötlet volt. (Tegyük még hozzá: newInstance minden esetben egy hosszabb Bundle-t hoz létre, ezért merült fel az ötlet.)

    (((Azt már tényleg csak ezer zárójelben teszem hozzá, hogy a leszármazott osztály nevét meg lehet szerezni, és lehet ilyet körülményesen mégis gyártani, de a javasolt megoldás sokkal átláthatóbb, és kényelmesebb.)))

    Remélem senkit nem bosszantottam azzal, hogy csupán a tanulság kedvéért helytelen kódot szemeteltem a fórumba. :N Én nagyon sokat tanultam a javaslataidból, hála és köszönet! :R

  • thon73

    tag

    válasz WonderCSabo #1442 üzenetére

    Kedves WonderCSabo! (ill. kedves mindenki!)

    Még egy utolsót szeretnék kérdezni, mielőtt végképp feladom a küzdelemet... :W Az előző megoldások tökéletesek, ki is próbáltam őket, - csak éppen (List)Fragment-nél nem működnek. Ott ugyanis úgy kell elkészítenem a kódot, hogy ÜRES Konstruktorral újra elkészíthető legyen a Fragment.
    Problémám a következő: Teljesen egyforma ListView-k (és ListFragmentek) jelenítik meg egy adatbázis különböző tábláit. Az eltérés néhány (6-7) paraméterben van: LoaderId, projection, from, to, content_uri stb.; maga a kód mindig azonos.

    Mi lenne a legjobb módszer arra, hogy egyetlen ListFragment osztály tartalmazza a kódot, és minden táblához ebből - más paraméterezéssel - egy külön ListFragmentet készítsen? Tényleges paraméterezés nem használható, az üres konstruktor miatt. Két ötletet kínlódtam ki: vagy abstract metódusokkal kényszerítem ki a "paraméterek" átadását a leszármazottakban, vagy az argument Bundle-be teszem bele egy-egy konkrét ListView-ban a paramétereket.

    Nem létezik, hogy ne lenne erre valami pofonegyszerű megoldás, csak sehogy nem találom. :(((
    Előre is köszönet minden hasznos ötletért!

  • thon73

    tag

    válasz WonderCSabo #1451 üzenetére

    Köszi! No, ez eszembe se jutott. Csak, hogy jól értem-e:
    Mivel a paraméterek között van kötelező, meg opcionális, az lenne tehát a legjobb, ha készítek egy Builder-t az első létrehozáshoz. Az összes szükséges paramétert ebben megadom a Fragment első létrehozásánál; majd az előbbi módszerrel mentem és visszatöltöm az összes - immáron belső - paramétert az újraindításnál.
    Ez egyúttal azt is jelenti, hogy nem kell leszármazottakat készítenem, egyetlen osztály - többféle paraméterezéssel - megcsinálja az összes tábla listázását.
    ((Hm. Én csak egy könnyen bővíthető programot szerettem volna, de ez a módszer hatalmas előrelépés egy szabadon (programkód változtatás nélkül) megadható adatbázisszerkezetet használó kezelő irányában :R ))

  • thon73

    tag

    válasz WonderCSabo #1453 üzenetére

    Kipróbáltam a lehetőségeket. Végső soron a setArguments() nagyon hasonló lehetőséget ad egy Builder/Fleunt interfészhez. A hátránya, hogy a paramétereket Bundle-ban kell átadnom; előnye, hogy nem kell a mentéssel/visszatöltéssel foglalkozni, a paraméterek újraindítás után is hozzáférhetőek. A Builder/Fleunt talán könnyebben beállítható a hívó oldalon.

    Lenne egy másik kérdésem is: még mindig a template alapján elkészített leszármazottak problematikájával vagyok elfoglalva - ezúttal a layout oldalán. A Fragmentek egy-egy adatbázis táblából származó elemet jelenítenek meg. A layoutban sok a közös, pl. Add, Update, Delete stb. gombok; de az űrlap szerű rész minden táblánál egyedi.
    Úgy gondoltam, hogy létrehozok egy "alap" layoutot egy ViewStub-bal, amit az egyes Fragmentek programból lecserélnek a nekik megfelelő űrlap-layoutra.
    Ahogy olvasgattam, egy ilyen megoldástól több helyen óvtak, merthogy nagyon rontja a performance-ot. (Én nem tudom elképzelni.) Van más lehetőség programból al-layout létrehozására? ((Mind az alap, mind az űrlap layout elég összetett.))

  • thon73

    tag

    válasz WonderCSabo #1455 üzenetére

    Igen, így képzeltem el, de egyetlen részt nem értek: "és a custom view alá berakja a saját űrlapját." Ezt hogy csinálom meg? ((Xml-ben meg is van, de nem akartam, hogy minden layout-nak hivatkoznia kelljen a közös layout-ra (meg akkor az ősfragment működése is komplikálódik.) )) Programkódból ez hogyan oldható meg? addView-vel?

  • thon73

    tag

    válasz Karma #1457 üzenetére

    Köszönöm, ViewStub-bal összeállt az egész.
    Még nem használtam ViewStub-ot, és ahol olvastam róla (persze most sehol nem találom), többen panaszkodtak ilyen megoldásnál a teljesítményre. Mindenesetre én semmi hibát nem látok, megy, mint a kisangyal... :C

  • thon73

    tag

    Kicsit szégyenlem, hogy mindig én kérdezek; valószínű egy picit nagyobb fába vágtam a szekercét, mint gondoltam... :F
    Van két adatbázis-táblám. Db1 egyik mezője (egy long id érték) hivatkozik Db2 egy elemére. Amikor Db1 űrlapját jelenítem meg, akkor természetesen nem a long érték, hanem a Db2-ben hivatkozott elem szöveges részei kerülnek kiírásra. Ez szerencsére eddig elég jól működik.

    A kérdésem a következő: létre tudnék-e hozni olyan custom TextView-t vagy akár speciális osztályt, amelyik KÖVETI a hivatkozás megváltozását. Vagyis, ha a long id megváltozik, akkor frissíti a hozzá tartozó szöveges értékeket is (kikeresi az új értéket az adatbázisból). ÉS mindezt valahogy úgy, hogy a Fragment (amiben az űrlap elhelyezkedik) újraindításait is átvészelje.

    Bocsánat, ha homályos egy kicsit a kérdésem. Bevallom, nekem is. Ezt a funkciót most a Fragment-en belül elhelyezkedő kódrészek valósítják meg, csak szeretném ezt a kódot egy kicsit elhatárolni a Fragmenttől. Pl. ha több hasonló hivatkozó értékem van, akkor is tudjam használni. Van valakinek valami ügyes ötlete? Előre is köszönöm!

  • thon73

    tag

    válasz WonderCSabo #1462 üzenetére

    A teljes táblát egy ListView jeleníti meg, ott a join-nal összekötött táblákat egyszerűen lekérdezem, és a mezőket a megf. TextView-kba teszem. Ez gond nélkül megy.

    Az egyes elemeket azonban egy űrlap jeleníti meg, ahol az egyes elemek önmagukban is megváltoztathatóak. Pl. egy könyv írójának itt az írók közül kiválaszthatok valaki mást, mielőtt magát az adatbázis-sort módosítom. A kódot egyébként megírtam, és működik is, de a linkelt adatbázisok űrlapjának kódja emiatt többször hosszabb, mint az egyetlen adatbázisra hivatkozók. A végleges megvalósításban ráadásul több ilyen "linkelt" elemet is kellene kezelnem, ezért gondoltam, hogy ezt a kódot valahogy leválasztom, akár View-ba, akár speciális új változótípus-szerű osztályba.

    A félelmem pont az amire WonderCSabo rámutatott; hogy ezt túlságosan belekötöm a Fragmentbe, akkor vagy az nem tud békésen eltűnni újraindítás után, vagy a lekérdezést nem tudom megfelelően elvégezni. Pláne, ha több TextView-t kell egy id-hez kötni.

    Hosszas keresés után most találtam egy megoldást (vagy legalábbis annak tűnik): ITT Megpróbálom így átkonvertálni. Meg valószínűleg lassan elolvasok egy komolyabb könyvet a software design patterns témában...

  • thon73

    tag

    Meg tudnátok mondani, hogy ha új, saját témát (konkrétan színvilágot) szeretnék a programomnak, akkor honnan érdemes elindulni? A hogyan az megy, csak nem tudom, hol találok olyan összefoglalót, hogy mi mindenre kell figyelemmel lenni, milyen attributumokat kell feltétlen definiálni stb.

  • thon73

    tag

    válasz WonderCSabo #1470 üzenetére

    Az elejét olvastam, de megriasztott a két utolsó gigantikus méretű file... Ezek szerint ne kézzel álljak neki, hanem fogjak egy ilyen programot (mint pl. a holos cucc), ami legyártja a nekem tetsző színben az egészet. No, nekiállok játszani, ((eddig a külsőségekkel még nem nagyon foglalkoztam.))
    Köszönöm!

  • thon73

    tag

    válasz WonderCSabo #1472 üzenetére

    Köszi, sikerült színes részeredményeket elérni, és ezzel rövidtávon meg is elégszem. De alapos külső segítséget (na jó, kritikát) kaptam a család tízéves stylistjától is :-)

    Még egy kérdés, amivel nem jutok dűlőre: Van egy custom view, ami egy TextView-ból származik. Annak a formázását hogyan tudom a témához hozzáadni? Konkrétan ugyanolyan külsőt szeretnék, mint az EditText, csak más színekkel. Egy ilyesmit (a viewben) készítettem, de nem sikerül a témába szerelni.

    [ Szerkesztve ]

  • thon73

    tag

    válasz WonderCSabo #1474 üzenetére

    Igaz, style nélkül, de ezt csináltam meg. A gond csak annyi, hogy rengeteg ilyen customview van, ezért akartam betenni alapértelmezettenk ezt a style-t, vagy az attributumokat. Még keresek tovább; ezt biztos vhogy. meg lehet csinálni...

    Kieg: a rengeteg, az rengeteg ugyanolyan. Összesen csak két custom view típust csináltam, csak sok példányuk van szana-szét.

    [ Szerkesztve ]

  • thon73

    tag

    Hát, úgy látszik, mindig csak én akadok el... Vérszemet kaptam a stílusokon, és - gondoltam - a fragmentekbe is beteszek egy kis animációt.
    Egymás mellett van két fragment: egy listFrag (list_frame frame layoutban) és egy editFrag (edit_frame-ban). Ez a layout, ami programból kapja meg a fragmenteket:

    <LinearLayout
    android:id="@+id/landscape"
    android:orientation="horizontal" ...>
    <FrameLayout
    android:id="@+id/list_frame"
    android:layout_weight="2" .../>
    <FrameLayout
    android:id="@+id/edit_frame"
    android:layout_weight="3" .../>

    editFrag itt animálva belép (csak lényegi rész!):

    fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left , android.R.anim.slide_out_right, android.R.anim.slide_in_left, android.R.anim.slide_out_right);
    fragmentTransaction.add(R.id.edit_frame, editFrag, "EDIT");
    fragmentTransaction.addToBackStack("LIBDB");

    és itt animálva eltűnik:

    fragmentManager.popBackStackImmediate();

    A gond az, hogy edit_FRAME akkor is "tartja a helyét", ha editFRAG eltűnik, emiatt a listFRAG (és Frame) nem szélesedik ki a teljes képszélességre.
    Ezért hozzátettem még egy sort:

    findViewById(R.id.edit_frame).setVisibility(View.GONE);

    Volilá! A ListFrag most a teljes képszélességet elfoglalja! (Persze, editFrag létrehozásakor a Frame-t is visszakapcsolom.)
    Csakhogy, ezzel eltűnt az animáció, mert a setVisibility előbb végrehajtásra került.

    Meg lehet szerintetek ezt valahogy együtt oldani? Tehát: editFrag animálva elosonjon, és a listFrag EZT KÖVETŐEN (vagy ezzel együtt) kitöltse a teljes helyet??
    Előre is köszönöm!

  • thon73

    tag

    válasz thon73 #1478 üzenetére

    Ezt (az animációs kérdést) még nem tudtam megoldani, addig is kihagytam az animációt.

    Lenne viszont egy egyszerűbb kérdésem: nagy mennyiségű (6-8 db) DialogFragment-et használok/nék. Mi erre a jó megközelítés, hogyan érdemes ennyit beépíteni a programba (egyetlen activity, két fragmenttel)? Van erre egy jó tutorial?
    ((Pontosítom: A DialogFragment-ek - önmagukban - prímán működnek, a kérdés nem A dialogus létrehozására, hanem SOK dialogus ésszerű kezelésére vonatkozik.))
    Köszönöm!

    [ Szerkesztve ]

  • thon73

    tag

    válasz WonderCSabo #1483 üzenetére

    Megerősíteni egy-egy akciót. Van egymás mellett egy list, és a lista egyik elemét mutató űrlap. Az űrlap törlésekor rákérdez, cancel-nél rákérdez, ha a listából másik elemet választok, de az űrlap már szerkesztés alatt van, rákérdez. Ha nem töröéhető az űrlap (foreign key constraint miatt), akkor figyelmeztet. Aztán van egy file választó rész, ott még több figyelmeztetés van.
    Amit nem értek: minden eseménynél a dialógus megfelelő gombja szerint megyek ugye tovább. De vannak nagyon hasonló dialógusok (are you sure pl.), ott mindegyik akciónak külön dialógust (file-t) készítek? Egyáltalán érdemes minden fragmentet külön fileba tenni, vagy egy nagy file készítse el a sok fragmetet? Szóval nem látom, milyen szerkezet a legelőnyösebb; viszont minden tutorial csak egyetlen dialogusról ír.

  • thon73

    tag

    válasz Karma #1485 üzenetére

    Köszi, ez a "középutas" ötlet kiváló.

    Eredetileg AlertDialog-ot használtam (és igen, elég), csak:
    - elfordítás nem megoldott, amit úgy oldottam meg, hogy DestroyView (ha jól emlékszem) magasságában bezártam a dialogust. (na jó, ez apró hiba, minek állandóan forgatni a gépet!
    - tetszett az ötlet, hogy a terjedelmes kódból kikerülnek a dialogusok, bár (mivel a dialogushívás az activity törzsön keresztül történik) ki-be kell ugrálni az egyes programrészek között.

    Ettől függetlenül, egy sima confirmation dialog esetén lehet, hogy tényleg célszerűbb az AlertDialog.

  • thon73

    tag

    válasz SektorFlop #1493 üzenetére

    Köszi SektorFlop! Én már feladtam, pedig klassz lenne :O

    Feladat a következő: van egy listfragment balról, bármelyik elemét tappintva annak részletei megjelennek egy - nevezzük így - editfragmentben jobbról. Az editfragment mintegy "kiúszik" az elemből, majd "visszaúszik" a listába. A nehézséget az jelenti, hogy az editfragment eltűnése UTÁN a listfragment a teljes képszélességet foglalja el.
    Ameddig eljutottam: A két fragment egy linearlayoutban volt. Az editfragment lassabban tűnt el, mint a helyéül szolgáló frame, így az animáció nem látszott.
    Az a gyanúm, hogy átfedő fragmentekkel kellene dolgoznom (framelayout) és a programból beállítani a szélességeket. Igaz, hogy a listfragment így is azonnal elfoglalná a teljes szélességet, de legalább látszana az átfedő editfragment animációja. Ehhez a történethez viszont elég sok elvarázsolt számítás kellene - különösen, ha hozzávesszük, hogy más az elrendezés fekvő és álló módban.
    ((Extraként még jobb lenne, ha az activity-k is így animálnának, csak teljes képernyőben. De ez már egyszerűbb ügy lesz.))
    Minden jó ötletet köszönök!

  • thon73

    tag

    válasz WonderCSabo #1502 üzenetére

    Keress ra Jess Anders two way gridview! En meg nem probaltam, de szerintem ez pont az, amit keresel! ((bocs, kulfoldon vagyok, nem tudom a pontos cimet eloasni)) Ha megvan, beszamolnal, h. jo-e?

    Udv es BUEK mindenkinek!

  • thon73

    tag

    Egy kicsit elakadtam, tudna valaki utat mutatni? Egy file importja során a program a következő "elvi" úton fut végig:

    - MainActivity: Import gomb -> meghívja a FileSelectorActivity-t
    - FileSelectorActivity: kiválasztjuk a file-t
    - MainActivity: onActivityResult() -> meghívja MainDialogFragment-et
    - MainDialogFragment: importálhatjuk az adatokat?
    - MainActivity: positiveAnswerFromDialog -> meghívja az importálásért felelős Activity-t

    Ez így egyszerűnek tűnik, de több helyen is vérzik:

    1. Ha a dialogus "importálhatunk?" kérdésére nemmel válaszolunk, akkor vissza kéne jutni a FileSelectorActivity-ba (ráadásul az elhagyott könyvtárba!), hogy tovább válogassunk. Itt akkor újra ugyanúgy meg kell hívnom a FileSelectorActivity-t, mint az Import gombnál? :F

    2. A dialogus csak a file nevére kérdez rá. A file adatai (Uri vagy File) hogyan "utaznak át" az onActivityResult részből (ahol megkapjuk őket) a positiveAnswerFromDialog részbe (ahol a dialogus visszatér)? Hozzak létre egy osztályváltozót a MainActivity-ben, vagy küldjem körbe az adatokat a dialoguson keresztül? :F

    Hogyan érdemes egy ilyen összetett (többlépcsős) kommunikációt szépen megszervezni? Előre is köszönöm!

    [ Szerkesztve ]

  • thon73

    tag

    válasz Karma #1517 üzenetére

    Köszönöm! Akkor nekiállok bogozgatni... :)

    Ezek szerint minden egyes lépés más és más, egymástól távol eső kódba kerül, ráadásul közöttük még az egész hóbelevanc újra is indulhat.
    Végső soron akkor ezek között a részek között a file Uri-t kell körbe-körbe küldözgetnem. Abból le tudom vágni a nevet, a path-ot, az external drive-ot is (mármint ez utóbbit akkor, ha nem kell).
    ((Hogy teljes legyen a boldogságom, a MainActivity már most is négy "beszélgetős" funkciót tartalmaz, és közülük az import a legegyszerűbb...))

    Kicsit égnek áll a nem létező hajam, de majd kifésülöm (legalább a kódot) :K Köszönöm!

  • thon73

    tag

    válasz Karma #1519 üzenetére

    Megpróbálom. Végiggondolva a lehetőségeket, mindig a visszatérésnél van a gondom. Az Activity ugyanis az onActivityResult-ba tér vissza (ami a MainActivity-ben van), ill. a DialogFragment is az Activity-t kapja meg, tehát oda mehet vissza.
    Namármost: Vagy szétosztom mindkét helyen a négy további osztály irányába az eredményeket (pl. a rquestCode alapján)
    Vagy mégis egyszerűbb (csak áttekinthetetlenebb), ha az egyes eseményeket itt (vagyis a visszatérési metódusokban) kezelem le.
    Hm. Emellett még meg kell tartani egy csomó paramétert, ami ugye vagy egy "utazó" Uri, de valószínűbb, hogy kellene csinálnom egypár változót (pl. egy retained Fragmentben), és a kérdések során ezek kerülnek egymás után feltöltésre. Amikor az utolsó kérdés is teljesült, akkor ezen változók alapján tudom végrehajtani a feladatot (pl. az import-ot). A változók talán azért előnyösebbek, mert segítenek, ha egy lépéssel vissza kell lépni. ((Mert pl. a FileSelector-nak meg kell kapni a "címsort" is, vagyis, miért válasszunk ki egy file-t.))
    Lehet, h. kicsit zavaros, bocs. De bennem valahogy talán kezd körvonalazódni. Köszönöm a segítséget! :R Kicsit még kezdő vagyok ebben a szervezésben, túlnőtt rajtam a program (önmagában már működő 31 class, 4 funkcióval, és ez tenne rendet közöttük), de majd belerázódom...

  • thon73

    tag

    válasz Karma #1521 üzenetére

    Persze, csak az a vicc, hogy épp ezt a négy funkciót akartam egy közös Activity-be rakni, amit most visszatennék négy másikba...
    (((Eredetileg maga a FileSelectActivity végezte el az import/export funkciót, mert csak arra kellett a file kiválasztása. De most ugyanezt a file-kiválasztót szeretném másra is használni (háttérben álló külső file becsatolása egy adatbázis-rekordba), és ezért "kiszerveztem". Így viszont már két emeleten lépnek be az Activity-k, egy harmadikon pedig a DialogFragment.))) Izgalmas lesz tesztelni...

  • thon73

    tag

    válasz Karma #1523 üzenetére

    És akkor a "mögötte lévő", vagyis utoljára indított Activity látszik?

    Első körben kiebrudalatam a teljes DialogFragment-et. Egyszerű dialogusokkal átlátható a kód teljesen, majd meglátjuk hogy kell (kell-e egyáltalán) visszatenni. Végülis, amíg elforgatás nincs, addig minden oké...

    ((Egy picit más: mi a nyavajának tűnik el az EditText tartalma a DialogFragment-ben elforgatáskor? Dinamikusan adtam hozzá, itt is kéne vhogy ID-t adni neki, hogy menteni tudja?))

    Bocs, közben bővült a válaszod... Megpróbálom második körben így átalakítani.

    Eredetileg azt hittem, ez valami triviális kérdés, amivel csak én nem találkoztam. De ezek szerint ez nem is olyan egyszerű...

    [ Szerkesztve ]

  • thon73

    tag

    válasz Karma #1525 üzenetére

    Akkor ügyködök, és gondolkodok is rajta ... meg persze beszámolok! Köszönöm, rengeteget segítettél!

  • thon73

    tag

    Sziasztok! A keresőrutin egy nagy (7-15 Mb) fileban ide-oda ugrál, és minden alkalommal kb. 1-5 byte-ot olvas be. Amikor megtalálja a megfelelő részt (ez kb 10-20 beolvasás), akkor beolvas max. 1000 karaktert egyetlen helyről.
    Érdemes-e puffert használni, ha érdemes, akkor mekkorát? Van az androidon valami hardveres/op rendszer által meghatározott minimális puffer méret? Köszi!

  • thon73

    tag

    válasz WonderCSabo #1566 üzenetére

    A file indexelve van, és az indexek sorba rendezve. De a szabadszavas keresésnél meg kell nézzem, hogy melyik indexnél kezdődik ugyanígy a bejegyzés. Ezzel egyébként nincs is gond, a rendezettség miatt rohadt gyorsan kikeresi a megfelelő bejegyzést.

    Eredetileg RandomAccessFile segítségével oldottam meg az egész beolvasást, mivel az könnyen pozícionálható (csak nem pufferelt beolvasást csinál.) Itt javasoltátok, hogy a szabványos read... metódusokat használjam,, mert az is pozícionálható, egyúttal pufferelhető is. (((Hozzáteszem, a RAF ráadásul elég érdekesen (halasztottan) működik, ami egy kicsit megnehezítette, hogy a file véletlen módosulását az időpont ellenőrzésével figyeljem...)))

    Szóval ezt a read dolgot építeném be, mert több szempontból is jobbnak tűnik. A BufferedReader wrapper osztályban meg lehet adni a puffer méretét (gyárilag 8192). Azt nem látom át, hogy nekem ilyen rövid beolvasásokkal van-e értelme a BufferedReader-t használni, és ha igen (mert gondolom, csak egy egységnyit tud fizikailag beolvasni a rendszer), akkor van-e értelme a 8192-t lecsökkenteni? És tovább: ha igen, mekkorára?

    Bocs, ha előbb félreérthető voltam, nem az egész file-t akarom pufferolni, csak az előolvasást. Ill. nem akarom, csak lehet, h. célszerűbb. (((Beolvasások: ListView-ban egymás utáni rekordok, darabonként kb. 30-300 karakter, de talán egy sincs 1000 felett. Keresésnél: 10-20 db 1-5 karakter hosszú beolvasás különböző helyekről, majd a megtalált rekord a fenti módon.)))

    Amit eddig a doksikban olvastam, az elég általánosan fogalmaz, és nem is magyarázza el a miérteket.
    [Ja, és még egy: sqlite-tal is kipróbáltam, de ekkora méret több sebből vérzik, jobb lett a saját adatbázis]

    [ Szerkesztve ]

  • thon73

    tag

    válasz WonderCSabo #1568 üzenetére

    Nem az SQL önmagában, hanem a konkrét megvalósításban. Az adatbázis (most) statikus, nincs törlés, nincs beillesztés, (ha lenne, itt már nyerne az SQL), csak olvasás van. A statikus adatbázist be kellene olvasni teljes egészében (egyébként már ez elég lassú, közel 300.000 elemről beszélünk (Ja igen, és már most van 8 ilyen adatbázisom)). A legnagyobb probléma azonban az, hogy sqlite-ban (legalábbis android alatt) az összehasonlító metódust nem tudom én, kódból elkészíteni (más nyelvekben van erre lehetőség). Emiatt minden egyes bejegyzésre (rekordra) le kell generálni a mezőket pl. ékezet nélkül. Nem akarok részletekbe menni, de nekem háromféle összehasonlítás kell, amit most kód végez. Sqliteban ehhez minden rekordban 3 mező kellene, praktikusan mindegyik ugyanazzal az adattal, amit mindhárom mezőben más írásmóddal írok. Ezek egyébként izgalmas kérdések, mert azt boncolgatják, lehet-e ilyen volumenű feladatra telefont használni.

    Namármost a vicc az, hogy lehet; legalábbis nekem prímán működik. A sebessége is kiváló, hiszen max. 20 keresésből megtalálja a kívánt elemet. Ez azt jelenti, hogy írom a keresőszót, és folyamatában, minden betű után keres. Ugyanakkor - mivel nem elég gondosan oldottam (még!) meg - csak az indexadatok olvasása 4 másodperc (ez lassú, ha elfordításkor ennyit kell várni), az indexelés meg 45 perc (SGSII-n), de ugye azt egyszer csinálom meg egy életben (elvileg).

    Úgy gondoltam, ha már ezt kijavítom (a 4 mp-et mármint), akkor az itt javasolt beolvasást is átírom, csak éppen elakadtam a puffer-méret kérdésnél. (No igen, az is egy válasz, hogy 8192, nem olyan sok az... :) )

    A "szívásról" annyit, hogy az első verzió PalmOS alatt született, ahol még kevesebb adatbázis-támogatás volt. Sőt! legfeljebb 64K elemet tudott kezelni, tehát több "táblába" kellett rendeznem az adatokat. Na az szívás volt, 3 hétig törtem a fejem az algoritmusokon. Viszont ezt átteni Android (és Java) alá csak egy délután volt. Most ott tartok, hogy az Android alatt néhány dolgon lehetne gyorsítani és egyszerűsíteni...

  • thon73

    tag

    válasz Karma #1571 üzenetére

    Igen, ez egy szótár, pontosabban szótár keretprogram. ITT elkezdtem irogatni egy-két dolgot, csak nem volt időm még befejezni. Viszont a program működik, sőt V.Attila is ezt használja. (csak az ő verziója fapadosan bővíthető) (((Vannak más szóanyagok is, de legalitásuk kétséges.)))

    Ha röviden akarok arra válaszolni, hogy miért kell még egy szótár: mert elég könnyűnek tűnt megcsinálni, olyan functionalitást tartalmaz, amit máshol nem találtam, és úgy tudom beállítani, hogy a kezem alá dolgozzon. ((Aki szótárazott hosszú szöveget képernyőn, az tudja miről beszélek.))

    "Az indexet desktopon kéne megcsinálni" - ez teljesen igaz, az androidos indexelés kísérlet volt, pont azt felmérni, hogy mennyi időbe telik. Aztán így maradt. Megjegyzem, ez egy külön app, amit csak én használok, nekem viszont fontos volt (utazás alatti fejlesztés miatt), hogy desktoptól független legyen.

    A "háromféle" módból kettőről fent már írtam, de kell még egy. Nézzünk két bejegyzést: "adatbázis" és "adat-bázis".
    (1) Ha ki akarod keresni, nem biztos, hogy lesz ékezetes billentyűd stb., tehát mindkettoben kell egy "ADATBAZIS"-t tartalmazó mező.
    (2) Ha sorba akarod rendezni, akkor kell az ékezet, de a két bejegyzés megfelelő mezője egyforma lesz: "ADATBÁZIS", vagyis eltűnik a kötőjel.
    (3) Kell az eredeti, átalakítatlan szó is, többek között azért, mert Attila szópárokat ír be, én viszont szeretném az azonos szavakat egyetlen bejegyzésba sűríteni, és ekkor az "adatbázis" és az "adat-bázis" két külön szóként szerepel.

    Ehhez sqlite-ban (mivel csak a standard sorbarakó lehetőségeket használhatom (((Megj: az UNICODE NEM alkalmas szótáras sorrend kialakítására, mert az pl. németben és magyarban más lesz, bár ettől még használható)))), szóval, három mezőben kell tárolnom ugyanazt a szót. Egyébként pont a kipróbálás végett készítettem egy sqlite keretet is. (A keret közel kész, de teljes anyaggal még nem töltöttem fel.)

    Bocs, nem akartam ennyire eltérni a témától, bár szívesen és örömmel megvitatom az egész szótár-projektet. Eddig úgyis csak a saját elgondolásaimra támaszkodhattam, ill. most már a tapasztalatra is, mert két platformon is jól működik. ((Na jó, az egyik halott...))Sőt, ha van itt profi fejlesztő, én én annak is örülnék, ha valaki az ötleteimet megvalósítja; a költségen felül ráadásnak az ötlet is az övé lehet. De az egész onnan indult, hogy (még a Palm OS időkben) nem vállalta senki, hogy ilyesmiket fejlesszen...

    P.S: ha valaki egyébként tudja az eredeti kérdésre a választ: vagyis milyen értéket érdemes BufferReader-ben puffernek megadni rövid beolvasásoknál, azt továbbra is köszönöm! :))

  • thon73

    tag

    válasz Karma #1573 üzenetére

    Igen, a mérés bennem is felmerült. Nem voltam biztos abban, hogy nincs egy konkrét elméleti adat - pl. az említett méretek, ezért kérdeztem. A mérés nagy hátránya, hogy könnyen lehet, h. ez az érték gépfüggő. Mellesleg - megjegyzem - puffer nélkül is észrevehetetlenül gyors, gyanítom, hogy pufferrel is az lesz. Tényleg igaz: nem kell talán minden lépést kimérni, azér' van a négy processzor...

    Hm. Nekem a Java és az Android teljesen új volt, C-ben programoztam előtte (ráfordított időt tekintve: hobbiszinten). Talán furcsa, de - ennek ellenére - a natív rész akkor még nagyon távolinak tűnt, egyszerűbb volt Java-ra átteni, és még akkor sokat javítottam (pontosabban bővítettem) az algoritmuson. Az eredetit amúgy se lehetett volna átteni, a PalmOS nagyon máshogy "gondolkodott". A sebességgel most nincs gondom, a teljes szöveges keresést jó lenne natívan megcsinálni, de az eddig nem volt szükséges.

    A program elkészülte után Attila megkért arra, hogy legyen bővíthető a szótár. Emiatt elég mélyen beleástam magam az sqlite-ba, most lett egy komplett front-end, ami kapcsolt táblákat is kezel. (Ez nem baj, mert egy ilyen nyilvántartó program amúgy is kellett volna, de eredetileg a szótár miatt csináltam.) Arra rájöttem, hogy ilyen speciális megoldásoknál az sqlite "kicsit" korlátozott. Az idő rövidsége miatt viszont a blog folytatására nem maradt időm, így aztán se az sqlite front-end, se a szótár doksija nem került (még) se fel, se megírásra. Szóval hiányos a "doksi", igyekszem pótolni (mert nekem is segítség), de ha bárki egy picit is érdeklődik, a kódot/adatot szívesen megosztom addig is.

  • thon73

    tag

    Megint egy Java/Android problémába futottam bele. :W
    Sqlite adatbázist használok több táblával. A táblák kezelése igényel egy csomó String konstanst, amiket eddig ténylegesen String konstansként is tároltam, táblánként. Ez eddig működik.
    A több tábla miatt szerettem volna a "közös" részeket kiemelni: pl. a contentType() az minden táblában ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + contentSubType() érték lesz, természetesen a contentSubType() táblánként különböző.
    Ezért fogtam a konstansokat, és áttettem őket metódusokba, melyek nem tesznek mást, mint visszaadnak egy String értéket (ehhez más metódusok meghívása is szükséges lehet, de végső soron ezek konstansok lesznek). Emiatt static-ként jelöltem meg ezeket.
    DE! A szülő osztályban (ami az általános tábla azonosítókat kezelné) a static-abstract összeférhetetlenség miatt nem tudok abstract metódusokat alkalmazni! (amik az egyes táblábakat kényszerítenék a saját, egyedi azonosítóik megadására)

    Vagyis a gond gyökere: sqlite adatbázisnál nincs a tábláknak megfelelő osztálypéldány, csupán az adatbázishoz/táblához tartozó konstansok vannak (amit a Java nagyon nem szeret). Nem találtam ideális megoldást, eddig minden táblához van egy osztály, ami csak a konstansokat tartalmazza.

    Ti hogyan szervezitek az adatbázistáblák konstansait egységes rendszerbe?

  • thon73

    tag

    válasz WonderCSabo #1608 üzenetére

    Abszolút off, de nagyon kíváncsi vagyok!

    Bevallom, én EGY egész évig bütyköltem az androidon, mire az első komoly programot biztonságosan el tudtam készíteni. (Igaz, munka és család mellett, kicsit hobbiból csináltam, viszont komoly C hátterem volt, és az objektumokkal sem most találkoztam először.)

    Mondjuk, most tartok ott, hogy a Karma által felsorot elemek egy részét én is felsoroltam volna, a másik részében meg tudom, honnan kell elindulni, de még soha nem használtam.

    Viszont a sokadik emberke kérdezi meg, hogy itt van egy ilyen meg olyan program, segítsetek, hogyan dobjam össze egy esős (havas) délutánon! Androidot(Eclipset stb.) ugyan még nem is láttam közelről.

    Most komolyan: én rontottam el valamit, és negatív az iq-m? Ez tényleg így megy?
    Mert akkor LÉGYSZI LÉGYSZI LÉGYSZI nekem is árulja el valaki, hogy a túróba kell ezt a vacakot felprogramozni!? Nekem valahogy mindig hibaüzenetek jönnek, és a legtöbbször nem is egy e betűt hagytam le az utasítás végéről...

    Bocs, nem akartam gunyoros lenni, de engem ez télleg nagyon érdekel!

    Ja, és ami nem OFF: Meg lehet tanulni Java-t is (azt még magyarul is), Androidot is (ahhoz azért angol tudás kell), internetes útmutatókból is. Nekem ugyan nem hirtelen, de sikerült. Amikkel kezdtem, azt ITT leírtam. Ez is egy forrás, elég alapszintű, van sok más is, néhányat az oldalon is felsoroltam.

    [ Szerkesztve ]

  • thon73

    tag

    Csak egy apró kérdés: gondoltam kimérem az sd kártya műveletek idejét.
    A programciklus végtelenül egyszerű: egymásba ágyazott BufferedReader/InputStreamReader/FileInputStream olvas hátrafelé (getChannel/position() beállításával) egy kb 7 megás file-t, mindig ugyanazt. Kiírás (képre, logra) nincs, csak mérés SystemClock.elpsedRealTime()-mal. A program UI szálon van, végig előtérben.

    De miért van az, hogy ugyanaz a program, ugyanazt csinálja, ugyanazon a file-on - és mégis valami irgalmatlanul szór? Ennek nem kellene egy közel konstans értéknek lennie? :F
    (Pontosabban: az irgalmatlanul az közel 1000 ms)

    [ Szerkesztve ]

  • thon73

    tag

    válasz thon73 #1659 üzenetére

    Elkészültem az első mérésekkel. A szórás ugyan nem változott, de a pufferelt és nem pufferelt beolvasás között több nagyságrendi különbség van. Még file-ban való ugrálás és rövid stringek esetén is, és még utf-8 átalakítással együtt is nyer a pufferelt változat. :C
    Én legalábbis nem gondoltam volna, hogy ekkora különbség van...

  • thon73

    tag

    válasz Karma #1573 üzenetére

    Visszatérek egy korábbi beszélgetéshez, mert ígértem, hogy számot adok az eredményeimről (ezt egy rövid részben már megtettem). Bocs, egy kicsit hosszabb lesz, aki nem érdeklődik, ugorjon nyugodtan! :P
    Másrészt kicsit Java topicba kívánkozik, de mivel a mérések célja az Android felderítése volt, (no meg itt kezdtünk bele), inkább itt folytattam.

    A probléma: indexelt utf-8 kódolású fileban ugrálni (seek) ide-oda, és rövid részeket beolvasni. Az első ötlet a Reader, a második ötlet a puffer használata volt. Mindkettő jó, de az alap osztályokkal nem megvalósítható.

    fis = new FileInputStream( file ); // byte alapú beolvasás
    isr = new InputStreamReader( fis, "UTF-8" ); // már karakteralapú, dekódolt és pufferelt (fix puffer)
    br = new BufferedReader( isr ); // readLine is van, és még nagyobbra állítható puffer

    fis.getChannel().position(pos) segítségével seek megvalósítható. DE! Amíg van a pufferban elem, azt használja. A puffer nem törölhető, az available() sem implementált, amivel skippelni lehetne. Egy megoldást láttam: minden seek után újranyitni a file-t. További hátrány: a puffert teljes egészében dekódolja, ha kell, ha nem.

    Megoldás: puffereléssel és utf8 dekódolással bővített Reader osztály (én valójában a RandomAccessFile-t használok a háttérben, de FileInputStream ugyanúgy jó. A "kimenet" azonban Reader lesz.) Ez már másnak is eszébe jutott ITT, én ezt az ötletet fejleszettem tovább.

    A tesztben hátulról előre 100 byte-onként végzek lineRead()-et egy 3,8 megás, rövid sorokat tartalmazó szöveges file-ban. Az eredmények megdöbbentőek (sajnos eléggé szórnak) A nem-pufferelt (egyébként azonos osztály) 20000 ms körül teljesített. Ugyanez puffereléssel: 600-900 ms

    Kimértem a különböző pufferméreteket is (ez a szórás miatt nehezebben meghatározható). DE! Az jól látszik, hogy 500 byte puffer alatt rosszabb a teljesítmény (800-1000 ms); 500-2000 byte között a legjobb (700-750 ms), 2000 felett pedig konstansan romlik (800-900 ms).

    Ez utóbbi eredmények között lényegi különbség (szerintem) nincs, vagyis nincs értelme sokat változtatni a 8192 standard pufferméreten. (((A régi szép időkben ismert szektornyi "raw" readhez amúgy sem enged oda a rendszer)))
    A pufferelt/nem pufferelt közötti különbséget sokkal kisebbnek gondoltam. Érdekes, hogy ennek ellenére nincs pufferelésre (gyári) lehetőség RandomAccessFile esetén. 20x különbség nagyon sok.

    Ha esetleg már valaki küzdött ezzel, és megosztaná a véleményét, nagyon örülnék. :R

  • thon73

    tag

    válasz RexpecT #1655 üzenetére

    JAVADOC: Én is próbálkozom most JavaDoc-kal. A beállítás utf-8, mégse jelenik jól meg. De a hiba nem a mentésben van, az szabványos, hanem a html-ben nincs benne a kódolás. Ha a browsert explicite Utf-8-ra állítom, akkor működik. Talán ez segít...

  • thon73

    tag

    válasz lac14548 #1686 üzenetére

    Speciel nekem van egy szótár (egyfajta saját adatbázis alapján) és egy sqlite adatbázist használó keretprogramom is.
    Egy ilyet összerakni tényleg nem rövid idő és nem is kevés munka. De a fentiek nagyjából készek. A szótár amúgy is érdekel, ha az átalakítás nem olyan vészes, akkor abban tudok segíteni. Kis java/android tudás azért a megértéséhez sem hátrány.

  • thon73

    tag

    válasz lac14548 #1692 üzenetére

    Akkor jó, ezt alapból tudja. A megnevezéseket kell átírni, meg bevinni egyszer az adatokat.
    ((Amúgy egyáltalán nem (volt) egyszerű feladat. Pontosabban egyszerű, de nem rövid feladat. Android alatt van egy príma sqlite adatbáziskezelő, de nincs összekötve a felszínnel (mármint a képernyővel), tehát meg kell írni a listázós/űrlapos részeket is.))

    Küldd el, kérlek, pontosan milyen mezők kellenek! A megnevezéseket uis. a kódban tudom megváltoztatni. És milyen "végtermék" kellene? Forrás-project eclipse alá? Vagy csak a kész progi?

    Egyébként van kész, és szabadon beállítható adatbáziskezelő a marketen: pl. Memento Database. Ez a feladat azzal is tökéletesen elvégezhető.

    A saját programnak mások az előnyei: speciális részek is beépíthetőek (pl. ékezetes keresés, összekötés naptárral) stb. A kívánt feladatot egyébként ebben is könnyen meg tudom csinálni.

  • thon73

    tag

    válasz TheProb #1693 üzenetére

    Mi akadálya van előtte elolvasni egy java könyvet is?
    A saját tapasztalatom az volt, hogy C alapok mellett elég volt két rövid jegyzetet elolvasni, és utána a Java-val együtt az Androidot elkezdeni. Nem akarok keveset mondani, de a Java-val nem volt semmi komoly gondom 2-3 hónap után. Az Android 2 év után is produkál számomra átláthatatlan kérdéseket. Bár bizonyára én sem vagyok kellő módon képzett... :N

  • thon73

    tag

    válasz lac14548 #1714 üzenetére

    Engem se fogott meg :N Ezért csináltam sajátot. A program kész, csak átírom a mezőket. Kis türelmet mégis kérek (munkahely, egyebek), de sztem. hétvégén küldöm. Az ékezetekkel nem értek egyet, mert uis. pl. én is ékezet-mentes bill.zetet használok. Egyébként egy kódtábla átírásával gyakorlatilag bármilyen keresési megfeleltetés beállítható, úgyhogy kipróbálhatjuk az ékezetes keresést is. Üdv!
    Azért írtam ide, mert úgy gondoltam, ide küldöm - hátha más is érdeklődik.

    [ Szerkesztve ]

  • thon73

    tag

    válasz pittbaba #1716 üzenetére

    Lehet, h. hülyeség, amit gondolok, de a "kilövés" az egész Application process-t érinti. A handler azon belül van, - elvileg - az is megszűnik. Arra kellene rájönni, hogy miért lő ki a rendszer egy előtérben lévő Applicationt? B lehetőség: Ha esetleg nem az application process indítaná a handler-t? Pl. service - bár ezzel nincs tapasztalatom.

  • thon73

    tag

    Bocsánat, ha nagyon alapot kérdezek:
    Az android forráskódban mindig synchronized( mLock ) kifejezés szerepel. Miért nem a védett tartalomra (mondjuk egy array-listre) szinkronizál, miért kell egy külön objektumot erre létrehoznia? (Azt értem, hogy ez miként működik, csak azt nem, hogy ez így miért jobb?)
    Én ugyanis eddig mindig a védett tartalmat írtam be.

    A másik hasonló kérdésem: ha ugyanazt a file-t külön szálakon is írom, de minden szál külön nyitja meg (tehát nem közös leírót használnak), akkor ugye nem kell a szálakkal és a szinkronizálással törődnöm, a rendszer sorba rakja a kiírt adatokat? (Mindig csak egy sornyi append van, tehát a program oldaláról nem feltétlenül kellene külön lock-olnom a file-t)

    Gyakorlatilag működik a program, csak azt nem tudom bizonyítani, hogy elvileg is mindig működőképes lesz. Köszönöm!

  • thon73

    tag

    válasz Karma #1733 üzenetére

    Aha! Köszönöm. 1. pont alapján a kódot javítottam.

    2. Eddig multithreadet (a rendszer által kínált lehetőségeken kívül) csak időzítési feladatokra használtam. Viszont - a log szigorításával - szükségem lett volna egy "saját" log-ra, amit akkor is használhatok, ha tableten dolgozom. A program nagyon egyszerű, egy file-ba írja az üzeneteket. ((Az esetleges összeomlás miatt a metódus nyitja-írja-zárja a file-t (flush is lehetne helyette, de az idő nem volt lényeges szempont)). Ilyen üzenet bármelyik thread-ről érkezhet, ezért szeretnénk biztos lenni abban, hogy működik.

    Két megoldást találtam a figyelmeztetésed után:

    private final Object lock = new Object();

    private static String addTextToFileLog( File logFile, String text )
    {
    synchronized( lock )
    {
    OutputStreamWriter logStream = new OutputStreamWriter( new FileOutputStream(logFile, true));
    logStream.append( text );
    logStream.flush();
    logStream.close();
    }
    }

    illetve:

    private static synchronized String addTextToFileLog( File logFile, String text )
    {
    OutputStreamWriter logStream = new OutputStreamWriter( new FileOutputStream(logFile, true) );
    logStream.append( text );
    logStream.flush();
    logStream.close();
    }

    (A hibaellenőrzést az egyszerűség kedvéért töröltem.)
    Van előnye egyik vagy másik megközelítésnek? Egyáltalán jó ez így, vagy valamit elnéztem?
    Ha még abban tudnék egy kis segítséget kapni, hogy ezt hogyan tesztelhetem a szimpla próbálkozáson kívül, azt is megköszönném!

    [ Szerkesztve ]

  • thon73

    tag

    válasz Sianis #1737 üzenetére

    Vicces, most derült ki mennyire topa vagyok a multithread-del, mégis megosztom egy volt ötletem. Én scrolloztatni akartam a képet, amíg a delikvens hosszan nyom egy pontot. A longpress nem jó, mert az csak egy dolgot csinál meg utána, aztán megint vár. Sztem. neked ugyanez kell fordítva: Ha érintés történik, akkor megszakítod a thread-et.
    Egy két kódrészlet:

    TouchThread touchThread;

    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
    ...
    case MotionEvent.ACTION_DOWN:

    touchDirection = 1;
    touchThread = new TouchThread();
    touchThread.start();
    break;

    case MotionEvent.ACTION_UP:

    if (touchThread != null)
    touchThread.interrupt();
    break;
    }
    ...
    }

    private class TouchThread extends Thread
    {
    @Override
    public void run()
    {
    // Csak vár, hogy hosszú nyomás legyen
    for (int cnt=0; cnt<3; cnt++)
    {
    sleep(100);
    if (isInterrupted())
    {
    touchThread = null;
    return;
    }
    }

    // Innentől történik a gyorsuló görgetés
    int pause = 150;
    while(true)
    {
    for (int cnt=0; cnt<15; cnt++)
    {
    sleep(pause);
    if (isInterrupted())
    {
    touchThread = null;
    return;
    }
    // Itt kérjük meg a görgetést az UI száltól !!!!!!
    touchThreadHandler.sendEmptyMessage(0);
    }
    if (pause > 85)
    pause -= 30;
    }
    }

    // A görgetést a Handler fogja elvégezni
    private Handler touchThreadHandler = new Handler()
    {
    @Override
    public void handleMessage(Message msg)
    {
    if (touchDirection >= 0)
    rollForwardLine();
    else
    rollBackwardLine();
    touchState = 0;
    invalidate();
    }
    }
    }

    Ezt elég régen írtam, aztán megszakadt a dolog. Egyébként nem csak az időzítést tudja, hanem egyre gyorsul is a görgetés, amíg nyomod a képet.
    Bocs, hogy a kód összetöredezett, amíg kiszemezgettem, de sztem a lényeg érthető. Mint kiderült, nem vagyok (még) teljesen otthon a thread-ekben; (ha valaki hibát talál, és szól, köszönöm); de a kód prímán működik.

    [ Szerkesztve ]

  • thon73

    tag

    válasz Karma #1735 üzenetére

    Bocs, :B farkas hiba! Nem is lehet pédányváltozó, mert az egész osztály nem példányosított.
    Szóval a private static final Object lock lenne a jobbik megoldás. Köszönöm! :R Tanulok, csak lassan.

  • thon73

    tag

    válasz Sianis #1739 üzenetére

    Egyszerűbb, célszerűbb.
    Nekem emlékeim szerint egy fejvakarásom volt, az UI műveleteket először nem a Handlerbe tettem, ami tilos. Vagyis nem az UI szálon dolgozni velük.

  • thon73

    tag

    válasz thon73 #1740 üzenetére

    Még egy utolsó kérdést hadd tegyek fel:
    A file írás nem mindig történik meg a záráskor sem (Ezt RandomAccessFile esetén tapasztaltam, még a program bezárása után is hozzányúlt, igaz, csak a metaadatokhoz).
    Nem biztonságosabb a FileLock használata az esetemben? Vagy ugyanazt az eredményt érem el, mint a synchronized védelemmel?

  • thon73

    tag

    válasz Karma #1746 üzenetére

    Aha. Ezt nem olvastam, csak a doksit. Akkor tényleg nem véletlenül írják, hogy Android alatt ez nem használható.

    Megnéztem a "hivatalos" Log-ot is, de az teljesen használhatatlan (nekem), mert alacsony szintű hívással az op-rendszer logját írja, amit viszont én nem tudok kiolvasni. (Ill. csak PC kapcsolatban, meg rootolt készüléken)

    Még nem tudok teljes mélységben válaszolni, de próbálkoztam, olvasgattam, és érdekes eredményeket kaptam.
    1. A külön file-író thread azért is nagyon jó ötlet, mert akkor ez nem is lassítja pl. az UI thread-et. Az elkészítéstől egy kicsit megriadtam, de nekiláttam. ITT találtam egy hasonló elgondolást, ebből annyi látszik, hogy ez nem lesz olyan egyszerű.

    2. A Channel thread-safe egy programon belül. Hm. ezt nem tudtam, pedig a doksi is egyértelműen ezt írja.

    3. ITT azt az okosságot írják, hogy Channelen kívül NEM lehet többször (tehát több threadból) írásra megnyitni egy file-t. (Ez szerintem nem igaz, én írtam file-t egyszerre több nyitott úton keresztül, igaz egy thread-en.)

    4. Ez a legérdekesebb: leteszteltem. Csináltam több párhuzamos thread-et, mindegyik ugyanazt csinálja: megnyitja/írja/bezárja ugyanazt a file-t, mégpedig OutputStreamWriter(FileOutputStream) úton. (Igaz, ez pufferelt, de a puffer többszörösét írtam ki, kb 2 Mbyteot, 4 threadról.)

    Nem létezik, hogy soha ne ütközzenek. Mégis, az összes kiírás tökéletes! Tettem elé time-stamp-et, sokszor egyforma, mégsincs hiba!!

    Vagyis: Minden elmélet ellenére gyakorlatilag lehet egyszerre több threadról írni ugyanazt a file-t. Most akkor ez hogyan lehet? Mégis "thread-safe" lenne az alacsony szintű írás androidon?? Lehet, h. itt működik, más java környezetben meg nem??

  • thon73

    tag

    válasz lac14548 #1714 üzenetére

    Az E-számokat tároló adatbázis kísérleti programja (és kódja) ITT TÖLTHETŐ LE Telepíthető adb a /bin mappában.
    A program az alfa változat alfája. Egy nagyobb történetből lett "lebutítva". Teljesen működőképes (én használom), de nincs széles körben tesztelve, szóval AS IS (olyan amilyen). Ez azt is jelenti, hogy nem tökéletesen kész, de különben soha nem érnék idáig vele.
    Mivel a kérdés itt merült fel, itt is osztom meg, de a megosztás célja elsősorban a tanulás. Ha bárkit érdekelnek részletek, talál hibákat stb. itt/püben/egyéb módon is szívesen fogadom.
    Egy-két apróság:
    Ez egy egyszerű sqlite alapú adatbázis, id-n kívül 3 szöveges mezővel. A negyedik mező tartalmazza a "normalizált", vagyis ékezetek nélkül kereshető kódot. Az adatbázist lista, ill. az egyes elemeket szerkeszthető módon is megjeleníti. A lista az E-számokra rendezett, szűrhető (minden mezőre, ékezet, kis-nagy betű nem érdekes), és (most még) unique bejegyzések nincsenek kikötve.
    Gyakorlatilag loggol (igencsak bőven) egy {sdcard}/enumberdb mappába (a syslogon kívül), de elmétileg ez összeakadhat (ld. előző kérdéseim a threadekkel kapcsolatban) dolgozom rajta.
    Az érdekessége (talán) a saját (egyszerű) file kezelővel bíró csv szerű export/import funkció, az adatok ezzel is bővíthetőek, ill. archiválhatóak. Vigyázat! importnál beilleszti a meglévő adatok közé a rekordokat!! (KI van kapcsolva az unique védelem, ugye.)
    Külcsín, működés (pl ékezet, kereshető mezők) könnyen, igény szerint módosíthatóak. Persze a nyelv is.
    Jó próbálgatást! Ötleteket, kritikákat szívesen veszek - már ami a kóddal kapcsolatos. Tudom, ez nem a Google Play, nem is ilyetén céllal került ide ez a kód.

  • thon73

    tag

    válasz Karma #1787 üzenetére

    A kérdés több, mint jogos, de a válasz egyszerű: megígértem, hogy még a hétvégén elkészítem, és így egyszerűbb volt feltölteni. (Így is késtem vele egy napot :B) ((Igaz, az nem mentesít, hogy az AIDE, amit tableten használok, alapból ismeri a GitHubot)) Ha megfelelő géphez kerülök, akkor felkerül oda, ill. blogcikket is szerettem volna/szeretnék írni erről, mert én rengeteget tanultam belőle - többek között itt kapott infókból is. Az eredeti ötlet többet tud, a kapcsolt táblákat (kereszthivatkozásokat) is kezeli.

Új hozzászólás Aktív témák