Új hozzászólás Aktív témák
-
thon73
tag
válasz
rgeorge
#1373
üzenetére
Hm. Lehet, hogy találtam valamit. Bár elegánsnak - hát kérdéses...

Az Android valójában egy linux. A Linux nem drive-ként látja az egyes részeket (vs. windows), hanem egyetlen nagy fában, amibe be-mountolja az egyes file-részeket. Ebben az értelemben egyébként az sd-kártya alap-könyvtárát sem kellene közölnie, hiszen az is "csak" egy könyvtár.
Ugyanakkor linux alatt is van mód az egyes összetevők lekérdezésére, legegyszerűbben talán a mount paranccsal. Ebből ugyanis kiderül, hogy melyik "drive" hova került becsatolásra. A mount elérhető android alatt is (én root-olt készüléken használtam, de csak olvasásra talán nem-rootolt masinán is működik.)
A kimenetet nem egyszerű megszerezni, de itt van a módja: [link]
Sok nyitott kérdés marad: pl. hogyan szeded szét a mount elemeket; ill. én nem is foglalkoztam behatóan a parancssorok elérésével, ezért kódot sem tudok adni. De ha ez tényleg ilyen fontos, akkor talán ezen az úton el lehet indulni. ((Én, a magam tapasztalatából megelégednék az external könyvtárral, és nem foglalkoznék azzal, hogy eltávolítható-e, vagy sem.))
-
thon73
tag
válasz
rgeorge
#1367
üzenetére
Az előző linket pont azért tettem be, mert azt boncolgatja, hogy nem triviális a megoldása.
Én ezzel a problémával egy szótár-adatbázis kapcsán találkoztam. Hová tegyem? Végül abban maradtam magammal, hogy ez az external cardon kívül a felhasználó dolga - aki a konkrét esetben én magam vagyok. Annyi segítséget tettem bele, hogy az utoljára kiválasztott könyvtárat megjegyzi. Én meg annyit jegyeznék meg, hogy az új tabletemben nincs sd-kártya, viszont beépített 16 Gb, ami több mint elég. Így az elgondolás "bejött".
Még egy ötletem van: ha betölteni akarsz nagy v. sok file-t, akkor a file-ok alapján lehetne esetleg megkeresni a könyvtárat. Mentésnél ez persze nem segít...
Még egy: Elixir2 - elég ügyes program, de nem tud különbséget tenni "külső" és "belső" sd között
-
thon73
tag
válasz
SektorFlop
#1363
üzenetére
A segítségnyújtáshoz esetleg egy kis kódot tudsz küldeni?
((Az ArrayList miatt nem a tökéletes megoldás számodra, de a CursorLoader-ről találtakat itt foglaltam össze: [link] Főleg a beillesztett külső cikkek miatt írtam ide.))
Még annyi jutott eszembe, hogy az Adapter által látott ArrayList-et leellenőrizted? Biztosan belekerült az adat?
Üdv! -
thon73
tag
válasz
SektorFlop
#1354
üzenetére
Én ugyanezt egy Loader-rel oldottam meg. A konkrét esetben egy CursorLoader-rel, ami nagyon szépen működik automatikusan. Van benne egy filterként működő EditText, ott restartLoader-rel ki tudom kényszeríteni, hogy újra elkészítse a listát.
Korábban ListActivity-ben volt szükségem hasonló megoldásra. ((A kikeresett elemet átszínezte.)) Ott a list.invalidateViews() segített. Ez egy kicsit más oldalról működik, de végső soron ez is újra lekérdezi a megjelenítendő adatokat az adapter-től.
Ha szükséges, este kódokat is tudok küldeni.
Addig ezt érdemes elolvasni: Is there any difference between `ListView.invalidateViews()` and 'Adapter.notifyDataSetChanged()'? -
thon73
tag
No, megvan. Jó hírek minden Win7 használónak, rossz hírek dmc-nek...
A gép Toshiba Portege R830 (ez gondolom, nem lényeges).
Rendszer: Windows 7 Professional Service Pack 1
Összes korábbi JAVA törölve a programok vezérlőpulton, a gépen nincs JAVA könyvtár, nincs JAVA a PATH-ban sem.
Indításkor a megszokott, "nem találom a JAVA-t" üzenet fogad.Oracle honlapról: jdk-7u45-windows-x64.exe letöltve, telepítve a felajánlott c:\program files\java könyvtárba, gép újraindítva. Path NEM tartalmaz Java elemeket!
Android Developres honlapról a felajánlott file letöltése: adt-bundle-windows-x86_64-20131030.zip, egyszerűen TC-vel kicsomagolva. Az alkönyvtárból indítom az Eclipse-t, az indítja az SDK Manager-t (szintén műxik)
És minden működik, a próba project fut a virtuális gépen.
Bocsánat Google, az előző kiadás óta javították a 64 bitet...((Megjegyzés: Az előző verziót is fent hagytam (API 17). A korábbi (6/33) Java 32 bites részének eltávolításakor összeomlott, az SDK Manager már nem ment (fekete ablak), az új Java verzióval pedig egyáltalán nem ment.
))Esetleg még a USER menüben lévő .android könyvtár törlése segíthet a hibás beállítások törlésében.
-
thon73
tag
Jól elvitatkoztunk ugyanarról

(((Nyelvtani ugyan a megjegyzés: nem az sdk-t, hanem a benne lévő egy-egy megoldást tituláltam félkésznek stb. És kivétel nélkül sikerült is megkerülni valahogy mindet. Én csak csodálkozom, hogy egy ilyen egyszerű dolgot, mint pl a 64 bites rendszert - ami egyébként kész, és nyilván nem kevés munkaidő van benne - egy utolsó kis buktató miatt hónapok/évek óta nem oldanak meg. Bizonyára volt más dolguk is, és végeredményben egész helyre kis programokat lehet alkotni rajta...)))dmc! Nem sikerült a 32 bites Java/ 32 bites Android SDk / 64 bites Win7 kombináció sem?
Csak úgy érdekelne... Ha hozzájutok a géphez, kipróbálom én is az up-to-date rendszerekkel.
Az Ubuntu+KDE egyébként nagyon jó, csak ajánlani tudom! -
thon73
tag
Ezen nem fogunk vitatkozni...
De nehogy a Google alaptalan vádaskodásért pereljen
, meg amúgy is elolvasásra érdemesnek tartom:
Overcoming Android's Problems with JDK 7Másrészt az SDK hibáiról:
Egy egyszerű (lévén az android beépített adatbáziskezelőt tartalmaz) adatbáziskezelő felületet készítgettem, fragmentekkel, sqlite-tal, egyebekkel - de semmi extrával.
- query hiba, egyetlen aposztrof miatt
- foreign key engedélyezése
- DialogFragment setRetainInstance(true) nem működik együtt
- Fragment-ből DialogFragment hívása - elvileg működik, de elfordításnál (egyetlen 0 miatt) az ablakok fordított sorrendben jelennek meg (és elfedik egymást), ((sajnos a linket a kóddal együtt töröltem))
...ezek csak azok, ahol a bug-report-ot feljegyeztem, de sorolhatnám azokat a helyeket, ahol már automatikusan a megkerülő lehetőséget alkalmaztam.És ez szerintem azért gond, mert én hobby-programozó vagyok: nem munkaidőben, nem pénzért, nem munkacsoportban írok egyszerű kódokat - részben szükségből, részben szórakozásból. Ha én ennyi hibával találkozom, akkor mennyi lehet a "nagy" programoknál? No, de ez már filozófiai probléma, és nem is ide tartozik.
Ami azonban az Android (és elsősorban a fórumok) javára írandó: egyetlen olyan probléma sem volt, amit némi kutakodással, vagy kérdezéssel nem lehetett volna áthidalni.
Bocs, ha valakit megbántottam
-
thon73
tag
Megoldás szerintem nincs. Karma véleményével messzemenőkig egyetértek, csak éppen a 64 bites Android SDK hibás. Nem működik - legalábbis ezt tapasztaltam - a 32 bites Java nélkül, a netes vélemények alapján egyszerűen nem találja meg. Személy szerint furcsának találom, hogy ezt nem javították (legalábbis addig, ameddig win-en követtem.)
A feleségem laptopján (amit utazáskor használunk néha), hiba nélkül együttműködik a 64 bites Android és a 32 bites Java. Megjegyzem, az is érdekes, hogy az Android Developers oldal mind a mai napig JDK 6!-ot javasol. (Egyébként én is 7-tel használom, gond nélkül, de ez nem jelenti azt, hogy nem is léteznek vele problémák.)
B verzió 32 bites megoldás mindkét oldalon, de akkor még mindig kérdéses a Win downgrade
((Egyébként az android alatt elég sok ilyen félkész/hibás/kerülőutas megoldással fogsz találkozni, ne akadj fenn rajta rögtön az elején...)) -
thon73
tag
Igen, én ajánlottam, mivel kísértetiesen azonos problémával szembesültem Win7/64bit alatt. De a 32 bites Java JDK feltelepítésével (64 bites mellett!!) minden pikk-pakk ment. Kétségtelen, ez egy korábbi verzió volt, azóta áttértem Ubuntura.
A Java telepítése után telepítetted a Bundle-t? Vagy a Bundle telepítése után cserélted a Java-t? ((Vagy már sikerült beüzemelni?)) -
thon73
tag
Én ezt találtam korábban. Nem működött a 64 bites java-val, és nem tudok róla, hogy ez változott volna. Próbáld ki a 32 bites Java-t feltenni!
-
thon73
tag
Meg tudná valaki mondani:
Ha kaszkádszerűen indítom ugyanazt (ugyanazokat) az Activity-ket, (automatikusan eltárolva az előző instance-ot a BackStack-ben,) akkor mi lesz az Activity-hez tartozó FragmentManager-rel? Az új Activity példány új FragmentManagert is kap, vagy abból csak egy van az egész rendszerben, és figyelnem kell a benne lévő Frgamentekre? Köszi! -
thon73
tag
válasz
kemkriszt98
#1281
üzenetére
Ha jól fordítom magyarra a kérdést:
Különböző layout-okon azonos névvel jelölt UI elemek nem zavarják-e a programot?Ez egy nagyon jó kérdés. A gyakorlat azt mutatja, hogy nem zavarja; nekem is van két "filter"-em két különböző layout-ban. Mivel a keresés mindig egy layout-on belül történik, ezért (természetesen) mindig a megfelelőt találja meg.
Ugyanakkor, ha az R.java-t (gen-ben) megnézed, akkor csak egyetlen filter szerepel benne, vagyis esetemben a két filter ugyanazt az azonosítót kapja.
((Én ezt fel is használtam a Fragmentek kezelésében: Ha portrait és landscape módban ugyanazon nevű frame-ek szerepelnek, akkor a kész fragment visszatölthető (pontosabban visszatöltődik). Különböző nevű frame-ekbe ugyanaz a fragment példány nem tölthető be.))
-
thon73
tag
válasz
kemkriszt98
#1277
üzenetére
Gugli első találat
Szépen így kell int-et kiírni:
tv.setText(String.valueOf(k));
De ha valami szöveget hozzáfűzöl, akkor az átalakítás automatikusan megtörténik:
tv.setText(""+k);
Vagy:
tv.setText("Az eredmény: " + k);Volna még egy javaslatom: az activity-re, mint egységes egészre kell tekinteni. Az egyes UI elemek ennek az egésznek képezik részét, és bármely alrészletnek (metódusnak) szüksége lehet rájuk. Ezért érdemes osztály színtű (akár private) változóként elkészíteni őket, melyek az onCreate-ben kapnak értéket. Ettől a ponttól kezdve viszont minden résznek (a Listener-nek is) rendelkezésére állnak. Meglátod, sokat egyszerűsödik a kód.

-
thon73
tag
Teljesen más téma, végre egyszer ne csak kérdést tegyek fel. Sokat kínlódtam azzal, hogy automatikusan eltüntessem a soft-keyboard-ot listView használatakor. A neten úgy láttam, hogy ezzel másnak is baja van.
Én a következő érdekességet találtam:A listView megérintésére így tudtam eltüntetni a billentyűzetet:
list.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow( list.getWindowToken(), 0);
}
return false;
}
} );Érdekes, hogy nem kell a focus-t átadni, ill. az is mindegy, hogy melyik View szolgáltatja a Token-t. A billentyűzet eltűnik, és ezt semmi más módon nem tudtam elérni itt.
A készülék elfordításakor azonban a bill. mindenképpen előugrik, és a fenti módszer hatástalan volt. Ezzel szemben a focus elkérése működött (holott a fenti esetben nem!):
@Override
public void onResumeFragments()
{
....
// list.setFocusable( true ); //az utóbbi ezt is beállítja
// list.setFocusableInTouchMode( true );
// list.requestFocusFromTouch();
list.requestFocus();
}Az első három sor nem véletelenül kikommentelt, azok nélkül is működött.
Most csak akkor lesz billentyűzetem, ha a keresőmezőbe írok.

Ha valakinek lenne ennél egyszerűbb/jobb ötlete, szívesen veszem. Ha valakinek segít a fenti snipplet, annak is örülök! -
thon73
tag
válasz
WonderCSabo
#1242
üzenetére
Nem akarom megtartani. Pont ezért kérdezem. De ez a példa szerepel magában a dokumentációban.
((Szerintem egyébként azért "tartja meg", mert a getActivity() mindig Activity-t ad vissza. Így egyszerűbb, mint minden alkalommal átalakítani az Activity-t Listener-é. Ezt csak gondolom.)) -
thon73
tag
Egy egyszerűbb kérdésben kérem a véleményeteket:
A doksiban a Fragments/Creating event callbacks to the activity rész szerint:
public static class FragmentA extends ListFragment {
OnArticleSelectedListener mListener;
...
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnArticleSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
}
}
...
}Az a kérdésem, hogy ezzel a lépéssel nem tartjuk-e meg az mListener-be átadott Activity-t a világ (pontosabban a fragment) végezetéig, tehát nem kellene-e az onDetach() metódusban elengedni?
Ha pedig nem, akkor ugye felhasználhatom az mListener (ami az activity)-t bármikor és null-ellenőrzés nélkül a Fragmentben?
-
thon73
tag
Időközben eddig jutottam:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/ending"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="12dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text=".ext"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true" >
</TextView>
<EditText
android:id="@+id/filter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@+id/ending"
android:hint="@string/filter_hint" >
</EditText>
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:layout_alignParentTop="true"
android:layout_above="@+id/filter" />
</RelativeLayout>De vajon hova kell tenni az empty részt? Pontosabban milyen attribútumokkal, hogy ne takarítson el minden mást?
És egy apróbb kérdés: az ending és filter részeket hogyan lehetne szebben egy magasságba tenni? (Tehát, ha jól olvastam, akkor a fix szélességű ending-nek kell előbb szerepelnie, hogy utána fel tudja tölteni a maradék helyet a filter-rel. De így nem tudom az ending alapvonalát a filterrel egybe állítani.)((Kiegészítve: akkor ugrott fel, ha az empty View jelent meg a list helyett.))
-
thon73
tag
válasz
WonderCSabo
#1208
üzenetére
Igen alignolja is, sőt azt is kiolvastam, hogy először ezt kell megadni, mert különben a listView "mögé" kerül az alsó sornak. Mégis, ha pl. kifogy a lista (mert rászűrtem az elemekre) minden elugrik a... Ha kicsi a képernyő, akkor megintcsak egymás mögé csúsznak az elemek.
-
thon73
tag
Layout témában szeretnék segítséget kérni.
Erre a felosztásra lenne szükségem:
Ez a kép két, egymásba ágyazott LinerLayout-tal működik. Mindkettőben a Weight paraméter van a nagyobb rész javára 1-0-ra beállítva, így mindig minden látszik. Az alsó filter-sor mindig alul van, és egy sor magas, a lista mindig kitölti a fennmaradó helyet.
Az Eclipse panaszkodik, hogy rossz lesz a performance, ezért megkíséreltem az egészet beletenni egy RelativeView-ba. De! Ha a lista üres, akkor a filter sor felugrik a kép tetejére (persze, mert ilyenkor csak egy sima textView jelenik meg a lista helyett). Ha elfordítom a telót, és megjelenik a bill. is, (tehát alig van hely), akkor végképp összeomlik az egész, és egymásra csúsznak az elemek. (LinearView-nél nincs ilyen baj, igaz a listből alig látszik egy sor.)
Megoldható ez RelativeLayout-ban? Tehát a kérések: filter-sor mindig legalul maradjon, és a filter-sor akkor se csússzon össze a listView-val, ha igen kicsi a rendelkezésre álló terület.
-
thon73
tag
válasz
sztanozs
#1188
üzenetére
Az előző hozzászólások alapján megpróbálom átalakítani az egész osztályt stream alapúra. Jelenleg a getChannel.position()-nal küzdök, amit a hozzászólásod alapján találtam lehetséges megoldásnak.
A RAF - C-s hasonlóságok miatt - nagyon szimpatikus volt, és eddig jól is működött. Én ugyan a RAF-ot "byte" alapon használtam - vagyis se nem küldtem, se nem olvastam semmit, ami 255 felett van. A teljes kódolást/dekódolást ebből a kvázi "byte" alapú folyamból végeztem el. Amúgy:
int read()
Reads a single byte from the current position in this file and returns it as an integer in the range from 0 to 255.Így nem lesz persze hiba, de logikailag valóban helyesebb byte-folyamként fogadni, és a rendszerrel átalakíttatni az UTF8 szöveget. És a RAF másik hátránya: tapasztalom, hogy pufferelt, csak sehol nem látom, hogy mekkora pufferrel, és az hogyan állítható be.
Úgyhogy fájó szívvel búcsút mondok a RAF-nak (és a C-s emlékeknek), és igyekszem Java-style I/O-t használni...
-
thon73
tag
válasz
sztanozs
#1186
üzenetére
A RandomAccess akkor is nagyon jól használható, ha a file tartalma indexelve van. Itt pont ez a helyzet: az első olvasás után minden bekezdés pozíciója ismert, a programnak csak a megjelenő bekezdéseket kell feldolgoznia.
A Stream-ek között nem találtam könnyen pozícionálható megoldást, csak a reset/skip párost. RAF esetén viszont rögtön adott ez a lehetőség; ráadásul a C-hez (és én C-ből akartam áthozni a programot) nagyon hasonló módon.
Csak az utf-8-on akadtam el (pontosabban indultam a fenti szálakon). ((Az eredeti adatok pdb-ben voltak))A pozícionálható Stream az kiváló megoldás lenne. ((A jelenlegi megoldás egy olyan "stream" osztály lett, ami háttérként RAF elérést használ, így pozícionálható is, meg a read() révén "stream" is. Ráadásul Utf8-at olvas.))
(((Az UTF-8-ról annyit érdemes megemlíteni, hogy az első közel 65 ezer karakter a Basic Multilingual Plane. Ez nem csak az összes ékezetes betűt, hanem az összes ismert nyelv betűit tartalmazza. Ebben az a nagyszerű, hogy 16 biten tárolható, vagyis épp egy karakteren. Ami ezen felül van, ahhoz UTF-16-on már két karakter kell. Az UNICODE saját dokumentációja állítja, hogy ez a rész nem kellőképpen tesztelt és megvalósított. Az ANDROID sem következetes, uis. ezt néha egyetlen 4 byte-os int-en ábrázolja, néha két egymás utáni karakteren. Mivel nekem még a beszélt nyelvek közül sem kell az összes, ezért a dekódoló algoritmus figyeli a non-BMP karaktereket, de helyettük egy sima '*' hibajelölést tesz, ami bármilyen kódolásban ábrázolható. Nem lenne nehéz egyébként a dekódolást erre a részre sem kiterjeszteni, csak akkor az egész program működését is ki kellene terjeszteni. ASCII-ról nem volt nehéz ITF-16-ra áttenni, de ha néhol két karakternyi ábrázolással kellene számolnom, az megnehezítené a dolgot.)))
Bocsánat egyébként, ha nagyon triviálisakat kérdezek, de az Android/Java párost csak most tanulom. Némely. engem érdeklő részbe már mélyen beleástam magam, de a legtöbb részt egyáltalán nem ismerem. Ezért örültem az előző tanácsoknak is, mert így új koncepcióban készítettem el a megfelelő részt.
-
thon73
tag
Hadd folytassam még az elmélkedést:
Mi a helyzet a RandomAccessFile() eléréssel? Ott nem tudok stream-et használni, vagy nem tudok ugrálni a file-ban.
Vegyünk egy egyszerű példát: sd-kártyára mentett, UTF-8 kódolású, de igen hosszú szöveg egy részét szeretném beolvasni, és a képernyőre írni. (Vagyis egy egyszerű olvasóprogram.) Korábbi olvasásból tudom, hogy hol vannak a bekezdéshatárok, így a feldolgozást tudom a szöveg "közepén" kezdeni.Ha az előző logikát követem, akkor kell készítenem egy saját byte-stream-et, mely a bemenetét a raf.read()-ből veszi, és azt az előző módon adja a konverternek. Ennek az az előnye, hogy minden, android által ismert dekódolást elvégeztethetek.
Vagy - ha biztos vagyok abban, hogy csak BasicMultilingualPlane-t használó Utf8 szövegem van - mégiscsak egyszerűbb magát a decoder-t megírni. Az pont a szükséges byte mennyiséget olvassa ki a forrásszövegből, és karakterenként visszaadja.
Vagy (ezt még nem csináltam): beolvasok egy buffernyi byte-ot, majd valamekkora részt feldolgozok belőle. A végén szinte biztosan egy félbevágott karakter lesz. Átpozícionálom a beolvasást a feldolgozott rész végére, és megyek tovább. Vagy a levágott részeket beteszem a puffer elejére, és onnét folytatom az olvasást.
Mindegyik esetben egy jelentős saját részt kell alkotni, holott egy igen triviális feladatról van szó. Ezt meg tudom kerülni valahogy szabványos rutinokkal?
Ill. a fenti megközelítések közül melyik lenne szerintetek a legeffektívebb/legegyszerűbb??((Az előzőekben egy backup-ként szereplő exportról beszéltünk, ahol a stream kiváló megoldás, mert nem kell benne ugrálni. Az utóbbi egy korábbi probléma, ahol nem ez a helyzet. De kíváncsi lennék a véleményetekre.))
-
thon73
tag
Hátha mást is érdekel, itt a rövid logikája a próbának; egyszerűség kedvéért file helyett stringek, hibakezelés és optimalizálás nélkül. 'c' átalakítása az első ciklusba, a kiírás elé kerülhet. (ed1-ed2-ed3 egyszerűen három EditText. ed2 csak azért kódol ISO-8859-1-et, hogy lássam, hogyan is kerülnek kiírásra a byte-ok.)
Kifelejtettem a lényeget: ed1 (UTF-16 String) -> outputStream==inputStream (UTF-8 byte-array) -> ed3 (UTF-16 String). Tehát oda-vissza elvégzi az átalakítást, és nem String-gel (bár abból indul), hanem Character-folyammal dolgozik.int c;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
StringReader stringReader = new StringReader( ed1.getText().toString() );
while ( (c=stringReader.read()) != -1 )
{
outputStreamWriter.write( c );
}
outputStreamWriter.close();
ed2.setText( outputStream.toString("ISO-8859-1") );
ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() );
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
StringWriter stringWriter = new StringWriter();
while ( (c=inputStreamReader.read()) != -1 )
{
stringWriter.write( c );
}
stringWriter.close();
ed3.setText( stringWriter.toString() );Érdekes, hogy keresgélés közben StraemReader/Writer osztályokat is átfutottam, de nem ugrott be, hogy erre van szükségem. ((Hát, látszik, hogy nem a javaba "nőttem bele", ráadásul évekig nem írtam semmi komolyat.
))A replaceEach is jó ötlet, (és ezzel visszajutottunk a túloptimalizáláshoz.) Ha legyártok egy új string-et, ami már az átalakított részeket tartalmazza, akkor áttekinthetőbbé válik a kód, ill. a fenti helyett a mentést is egy sorban meg tudom oldani. Nem nagy ár ezért az új string létrehozása, akkor sem ha több ezerszer történik meg.
Köszönöm a segítséget, az eredetitől gyökeresen eltérő logikájú kód született, de sokkal szebb, és jobb. Nem végeztem még méréseket, de nem tűnik nagyságrendekkel lassúbnak. (Gondolom, az SD kártya sebessége lesz a meghatározó...)
-
thon73
tag
((A new line/tab átalakítást csak példának írtam, (és ebben az esetben az első pont teljesen jogos) Esetemben egy kicsit összetettebb dologról van szó: tényleges szövegfeldolgozás történik, a mentett oldalon - értelmezést könnyítendő - a rövid bejegyzéseket mintegy kibontja a program, és egy hosszú file-ban tárolja. Igazából ez is egy decoder, csak épp elég speciális. De ez a programozási probléma szempontjából lényegtelen.))
A röviden pont történt meg most (vagyis megoldást kerestem), és a választ is köszönöm: És meg is fogadom, (2. pont), mert igazad van: nem foglalkozok a teljesítménnyel. Én is gondoltam arra, hogy ha a teljesítmény ilyen fontos tényező, akkor ezt a részt natívan kellene elkészíteni, de ebben (még) nincs tapasztalatom. Egyébként nem olyan félelmetesen hosszú a feldolgozás: vmivel több, mint 200e bejegyzésre 20-40 perc jelenleg

((Arra az indiszkrét kérdésre, hogy akkor miért a telefonom csinálja, csak azt tudom mondani: az mindig nálam van. De egyébként a teljes adatbázist csak egyszer kell megcsinálni, a többi meg már rövid...))((A 3. pontban is nagy igazság van, bár egyszer beleástam magam az unicode-ba, és írtam konvertáló algoritmust is, tehát az van. Az UTF16->UTF8 irány elég egyszerű, hiszen ott (felső részek kivételével) minden karakter létezik. A fordított irány az érvénytelen szekvenciák miatt egy kicsit izgalmasabb.
A gond egyébként pont abban van, hogy az UTF8 nem egyforma hosszú részekből áll (na persze ez az előnye is), és ez - saját kód nélkül - megnehezíti a szövegfeldolgozást. A legegyszerűbb példa: nagyon nehéz effektív UTF8 beolvasást csinálni, mert nem tudod, hogy pontosan hány byte-ot kell/lehet a pufferbe olvasni, és ezért pl. vagy "görgetni" kell a puffert, vagy figyelni a végén az eltört karakterekre. Ezért is gondoltam, hogy egyfajta stream-szerű beolvasás (szerű, mert UTF8 karakterenként olvas/ír) egyszerűsíteni az életet, de még nem találtam ilyet készen. Ettől függetlenül masszívan igaz, hogy meglehetősen túlkomplikálja a programot. Bocs a hosszú okfejtésért.)) -
thon73
tag
válasz
sztanozs
#1173
üzenetére
Igen, ez világos. Igyekeztem a kérdést a problémás részig egyszerűsíteni, ebből a félreértés. De a szélesebb problémára is szívesen fogadok ötleteket:
Adott egy String, ami EditText-ből, vagyis a felhasználótól származik (és egy adatbázis tárolja). Ezt a Stringet szeretném UTF-8 kódolású txt file-ba menteni. Ez idáig egyszerű, és két sorban megoldható.
DE!
Mentés előtt a String-en utólagos feldolgozást végez a program, néhány részét cseréli. (Gondoljunk pl. arra, hogy pl. tab-ot \\t-re, new-line-t \\n-re, vagy esetemben speciális, de olvasható tag-okat szúr be.) Erre a legegyszerűbb mód, ha StringReader-ként kiveszem a karaktereket, átalakítom, és az eredményből egy új folyamot hozok létre. A karakterek 99%-a változatlanul (vagyis egy karakterként) fut tovább, de néha a karakter helyett egy rövid szövegrész megy ki. Nem akartam új String-et készíteni, hanem azonnal az UTF-8 típusú kimenetre küldeném az adatokat.
Eddig csak olyan megoldást találtam, ami String-et, vagyis hosszabb szöveget alakít UTF-8-ra. Az 1%-nyi részben ez tökéletes, de 99%-ban ez a String csupán egyetlen karakter hosszú lesz. Van vajon erre frappáns megoldás, vagy egyszerűbben járok egy UTF-8 kódoló megírásával?
Vagy esetleg lehet-e az egész gondolatmenetet előnyösebben elrendezni? -
thon73
tag
Még egy kérdés. más témában:
EGYETLEN karaktert kell Character típusról (UTF-16) UTF-8-ra konvertálnom (mármint egyszerre egyet, de nem teljes stringet). Mi szerintetek erre a leggyorsabb/legegyszerűbb módszer?
(A String konvertálása ok, csak szerintem az nagyon pazarló, ha csak külön karakterek átalakításáról van szó.) -
thon73
tag
Kérdés: A FragmentManager-ben tárolt Fragmentek megjelenési sorrendjét miként lehet megváltoztatni?
Issue 31116 problémába futottam bele. A készülék elfordítása után az átfedő Fragmentek nem a megfelelő (eredeti) sorrendben jelennek meg, ezért az utolsó, DialogFragment "alulra", a többiek mögé kerül.
Megpróbálkoztam a getChildFragmentManager() használatával, vagyis a DialogFragment-et is egy Fragment nyitná meg, de ebben az esetben elforgatáskor a DialogFragment - hibaüzenet nélkül - eltűnik. Ettől eltekintve ez működik.
A másik ötletem, hogy minden Fragment-et az Activity kezel, és minden alkalommal újra felépíti a teljes miskulanciát. Ez csak azért rossz, mert eddig mindent meg tudott oldani maga a rendszer, csak az utolsó, Igen/Nem kérdés kezelését nem.
A harmadik - és eddig legjobbnak tűnő módszer -, hogy egy hagyományos Dialog ablakot nyitok meg a Fragment-ből. Kétségtelenül ez a legegyszerűbb. Az elforgatáshoz viszont itt is külön kód kell.
Nem tudtok vmi. ennél egyszerűbb megkerülő módszert erre a hibára? Köszi!
-
thon73
tag
No, kiteszteltem, hogyan működik. Ha a Frgamentben egy View objektum értéket kap, akkor a hozzá tartozó View mögötti objektum megmarad az életciklus végéig, tehát írható. A TextView-t még az onDestroy-ban is tudtam írni.
Az más kérdés, hogy az onDestroyView magasságában a rendszer elbontja az egész View struktúrát, tehát írhatom az egyes objektumokat, csak megjelenni nem fog semmi.
Az onCreateView viszont újraindul az életciklus elején, és - normál megoldás esetén - minden View objektumnak újra (new használatakor új) értéket ad.A lényeg, hogy nem kell külön ellenőrzés, a Fragment View objektumai az első onCreateView után bármikor írhatóak (az UI threadról), bár néha (onDestroyView és onCreateView között pl.) a kiírt érték nem jelenik meg; ill. egy adott View-ra hiavtkozó objektum megváltozhat (az onCreateView ismételt lefutásakor).
Ez némileg egyszerűsítette a kódomat...
-
thon73
tag
válasz
WonderCSabo
#1160
üzenetére
Időközben megtaláltam miért kell konstruktort készíteni DialogFragment-hez. A rendszer készít default konstruktort, de az érvényességi tartománya az osztályéval fog megegyezni. Itt viszont public konstruktor KELL. Másrészt, ha van paraméterezett konstruktor, akkor nem készül üres.
Vagyis:
public osztályban, ahol nincs konstruktor, ott nekünk sem kell készíteni.
Nem public DialogFragment-nél, vagy ha van paraméterezett konstruktor, akkor kell készíteni public jelzővel és paraméter nélkül.
Talán másnak is segít ez.De van egy másik elméleti kérdésem: Van egy Fragment (az egyszerűség kedvéért onRetainInstance(true), és ebben van egy TextView. Egy háttérszálon futó folyamat időnként kiüzen az UI szálra, és innen írja a TextView-t. Mikor lehet ezt büntetlenül megtenni? Melyik életciklusok között, vagy mit kell ellenőrizni? Vagy teljesen mindegy, akkor is írhatja, ha pl. a Fragment nem is látszik, vagy dettach-olva van? Van erre valami szabály?
Köszi! -
thon73
tag
válasz
WonderCSabo
#1157
üzenetére
Köszönöm, rengeteget tanultam! Sok példát elolvastam, de a static factory method kifejezést egyik sem említette, (csak használta.) De én nem ismertem, úgyhogy köszönöm!
Még egy kérdés: Ha jól látom, akkor általában static factory method esetén érdemes "elrejteni" a konstruktort. Fragment-nél ezt nem tehetjük meg, mert újraindításnál a rendszer a public konstruktoron keresztül indítja újra a Fragment-et.
De akkor miért készít egy csomó példa expliciten public konstruktort? Az üres, public, alapértelmezett konstruktor nem készül el automatikusan az osztályhoz? Tényleg ki KELL írni, vagy ez csak didaktikailag szerepel ott? (speciel nekem külön odaírás nélkül is működött) -
thon73
tag
Bocsánat előre a kezdő kérdésért.
DialogFragment készítésénél minden útmutató készít egy newInstance() metódust, sőt az arg-okat is ezen keresztül adja át. ((Amúgy én is ezt használtam.)) A google útmutatóban is ez szerepel.
Arra nem jövök rá, hogy ez miért jobb, mint ha a DialogFragment elkészítését (new) a show() hívás előtt végzem el (mint egy sima Fragmentnél). Ugyanúgy egy sor, ugyanúgy működik.
Csak izlések és pofonok? Vagy van valami, ami elkerülte a figyelmemet? Még egyszer: értem, hogy hogyan működik, használtam is, csak az zavar, hogy magamtól teljesen más módszert alkalmaznék/alkalmaztam volna. Viszont kivétel nélkül mindenki más a fenti módszert írja le, de senki nem említi, hogy miért pont ezt.
Bocs, ha nagyon stupid a kérdés; hálás köszönet, ha valaki mégis veszi a fáradtságot, és elmagyarázza, hogy mit nem vettem észre. Köszi!
-
thon73
tag
válasz
sztanozs
#1137
üzenetére
Vagyis asynctask, egy progress-szel, miközben a program - a felhasználó szempontjából - "áll". Ill. dolgozik. Jogos, mert max 10-20 sec-ról van szó.
Az nem is jutott eszembe, hogy a "külső" hozzáféréseket korlátozzam. Pedig milyen fontos! Több activity van, de mind saját, ezzel nem lesz gond. Köszi!
(((A konvertálás kicsit érdekes. PalmOS alatt PalmPilot adatbázisról van szó. Az adatokat alig bírtam kibányászni belőle, csak PC oldali programok garmadájával. Egyébként a Palmon mind a mai napig tökéletesen működik, csak épp androidra áthozni nem tudtam. Vicces volt, mert már a PalmPilot egykori fejlesztőivel is beszéltem (Franciao-ban!), de persze nem emlékeztek részletekre, source-kódból kellett volna kibányászni...
Hogy rövidre fogjam, az előszedett csv adatbázisokat szeretném importálni, és egyúttal úgy elkészíteni a programot, hogy soha többé ne legyen ilyen probléma: az adatok hozzáférhetőek legyenek valami teljesen egyszerű formátumban is.))) -
thon73
tag
Köszi a gyors válaszokat! De a probléma valóban ez: programból szeretném sd-re tenni, lehetőleg emberi fogyasztásra is alkalmas formában. Ez a fele nem is jelent gondot.
Abban nem vagyok biztos, hogy a programszervezés szempontjából melyik a legjobb módszer. Pl. mentés történhet nyugodtan a háttérben (pl. service), de töltésnél ilyenkor mi lesz? Folyamatosan változik a lista, ahogy töltöm? Vagy jobb mindkét esetben leállítani a programot és egy asynctaskkal dolgozni? Szóval kiváncsi lennék a véleményetekre. -
thon73
tag
SQLite adatbázist szeretnék exportálni/importálni pl. csv-be. Az adatbázis elég nagy. Mit javasoltok, milyen keretben érdemes ezt megtenni? AsyncTask, Servive, Loader (import oldal), egyéb? Szerintetek mi a legelőnyesebb? Köszi!
-
thon73
tag
válasz
WonderCSabo
#1116
üzenetére
Mindkettőtöknek nagyon köszönöm a segítséget; továbblökött a mélypontról. Ennyire nehéz hibakeresést még soha nem csináltam, ugyanis minden próbálkozás között újra kellett indítani a telót (ami kb. fél perc).
Bocsánat, az onPause irány véletlen volt (de egy fél nap keresés után már nem találtam más okot)
,valóban úgy tűnt, hogy az marad ki: a hiba CSAK leállításkor jelentkezett; az eclipse debugger nem követte ilyenkor az onPause-t (mint utóbb rájöttem: hiszen leállt), a Log-ot meg én bénáztam el. De a hozzászólásotok után végig belogoltam, és akkor kiderült, hogy onPause van, csak ami benne lenne - no az nincs.A tanulság kedvéért a hiba (egyébként utólag pofon egyszerű, de csapdás):
A program egy gigantikus RandomAccessFile-t ír/olvas az sd-n. (Ennyiben a felhasználói adatok azonnal kikerülnek.)
Az onPause részben (többek között) azt kell elmenteni, hogy valaki nem piszkál-e bele a RAF file-ba, amíg távol vagyunk. Ehhez mentem (név mellett) a méretét (File.length()) és az utolsó módosítás időpontját (File.lastModified()). Újraindításkor ezt ellenőrzi.
Ez a módszer prímán működik, amíg ki nem kapcsoljuk a telót.A gondot az jelentette, hogy a RandomAccessFile NEM szinkron írást csinál, sőt a close() után sem írja ki az adatokat! (Ezt bizonyára mindenki tudja, valószínűleg én is, csak nem gondoltam rá.) Véletlenül "rw" módot adtam meg az "rws" helyett.
Az érdekesség, hogy több hetes próbálgatás alatt is a nem-szinkron kiírás MINDIG bekövetkezett az onPause előtt, ha szabványosan léptem ki. Ha a telefont kikapcsoltam akkor SOHA nem következett be az aszinkron írás az onPause előtt (ezt két napja tudom).
((Megjegyzem, sehol nem találtam részletes dokumentációt arról, hogy pontosan mi és milyen sorrendben történik a kikapcsoláskor.))Van még egy probléma, ami komoly fejtörésre adhat okot: RandomAccessFile "rws" írásakor SEM stimmel a lastModified() érték a visszaolvasáskor!! Az esetek 90%-ban pontosan EGY másodperc (1000 ms) különbség van a két külön alkalommal visszaolvasott érték között!! Mivel a lastModified() érték MINDIG három 0-val végződik (vagyis nem ms, hanem másodperc pontos) valószínűleg a kerekítésnél lehet gond; de ezt nem tudom, csak gondolom. Hivatkozást nem találtam SGS2 és Note gépeken próbáltam.
Köszönöm, hogy kipróbáltátok, teljesen fals útról térítettek vissza; így jópár további óra alatt meglett a hiba!
-
thon73
tag
Sziasztok!
Az onPause metódusban van egy fontos mentésem. Próbálgatás közben az derült ki, hogy amikor kikapcsolom (úgy értem teljesen, android logo meg minden) a gépet, akkor NEM fut le az onPause, és következményesen NEM történik meg a mentés.
Az onPausenek nem kellene mindig lefutnia?? Hová lehet még tenni a mentést, hogy biztosan megtörténjen?? (Jó, mondjuk akksi kivétel ellen nincs orvosság, de ez egy "tervezett" leállítás!)
Találkoztatok már ezzel a problémával? Minden segítséget hálásan köszönök!
-
thon73
tag
válasz
WonderCSabo
#1024
üzenetére
Köszi, ez jó ötlet. De kicsit félreérthető voltam, én nem az Activity-n BELÜL szeretném megtudni, hogy eltűnt, hanem KÍVÜLRŐL szeretném látni, hogy most már eltűnt/újraindult. Csak olyan ötleteim vannak, hogy megnézem a futó task-ok között stb., de nincs erre valami fejlettebb fejlesztői megoldás?
Pl. az onActivityResult más módon (az on...-ok között más sorrendben) kerül meghívásra a két esetben; és szerettem volna kicsit körüljárni, hogy mi történik. De csak nagyon körülményes megoldásokat találtam. -
thon73
tag
Sziasztok!
Tudja valaki:
1. hogyan lehet arról tudomást szerezni, hogy a rendszer (pl. memóriaigény miatt) kilőtte a hátterben álló programot/activity-t?
2. hogyan lehet ezt kikényszeríteni; vagyis, h. a rendszer lője ki a programot, mintha csak további erőforrásra lenne igénye? (A TaskKiller ugyanúgy csinálja?)
Mindkettő kizárólag teszteléshez kellene, tehát root, eclipse-es pc kapcsolat, stb. nem probléma. Köszönöm! -
thon73
tag
Sziasztok!
4.1.2-es készülékem lett, és ezen már nem láthatom a LogCat kimenetét "biztonsági" okokból. Mármint magán a készüléken. Van valakinek bevált ötlete arra, hogy ilyenkor mit lehet/érdemes csinálni?
Amennyit erről olvastam, a Google nem is nagyon akarja, hogy a fejlesztők a system log-ot használják. Márpedig nekem eddig nagyon hasznos volt...
-
thon73
tag
válasz
WonderCSabo
#862
üzenetére
A jelenlegi 2x7 mega. Nincsenek benne a formázások, részletek stb.
Sokat gondolkodtam a tároláson, de mivel az adatok nem változnak, ezért tűnt ez a legcélszerűbbnek. Ha adatkezelés is cél lenne, sql-ben csinálnám.
A fenti módszer egyébként így működik, csak az osztály konstruktorába szerettem volna belebűvölni. Ja, és fontos előny, hogy egy keresésnél max. kb. 100 byte beolvasás kell! -
thon73
tag
A következőt szeretném egyszerűsíteni:
raf1 = new RandomAccessFile( "filename", "r");
raf2 = new RandomAccessFile( "filename", "r");
raf3 = new RandomAccessFile( "filename", "r");
raf4 = new RandomAccessFile( "filename", "r");Azért van szükség több "raf"-ra, mert össze szeretném hasonlítani a file két (vagy több) pontján lévő szövegeket egymással.
A fenti módon persze ez megoldható, a gond csak az, hogy a "filename" - hacsak nem tárolom - később már nem hozzáférhető. (Uis. a "raf utazik paraméterként az osztályban) Azt gondoltam, van egy egyszerűbb módszer pl.:raf = new RandomAccessFile( "filename", "r");
...
raf1 = raf.clone();
raf2 = raf.clone();
raf3 = raf.clone();De sajnos nincs, mert ez valóban nem clonable.
A singleton szerintem erre nem megoldás, pont az ellenkezője kellene. (Singletonban mindenki biztosan ugyanazt a raf-ot kapja meg, nekem pedig az kell, hogy biztosan senki ne kaphassa meg ugyanazt a raf-ot)
-
thon73
tag
válasz
WonderCSabo
#852
üzenetére
Egy RandomAccessFile objektumra lenne szükségem, több példányban. Vagyis: ugyanazt a file-t szeretném elérni, de különböző pontokon. A RandomAccessFile konstruktora vagy egy File vagy egy filenév paramétert kér. Eddig úgy oldottam meg, hogy ugyanahhoz a File-hoz több RAF-ot gyártottam le. Most viszont ezek az értékek nem állnak rendelkezésemre (vagyis külön kellene tárolnom őket), ezért örültem meg a clone-nak.
Semmi más módszert nem találtam arra, hogy a RAF objektumot megduplázzam - a belső adataihoz (értelemszerűen) nem férek hozzá. Függetlenül az én konkrét példámtól, ez más objektumokra is igaz.
Nincs véletlenül ötleted arra, milyen uton lehet/illik ezt megoldani? Vagy tároljam el mindig a file nevét, és akkor már tudok olyan osztályt bővíteni, ami implementálhatja a Clonable interface-t.
De ez nem tűnik túl szép megoldásnak. Köszi! -
thon73
tag
válasz
WonderCSabo
#852
üzenetére
Köszi! Jogos. Az Inherited Methods from java.lang.Object alatt szerepel, és a doksi egy szóval nem említi, hogy ez az osztály ezt nem valósítaná meg. Miután most a címét is tüzetesen elolvastam, valóban ott áll, hogy protected. Pedig olyan egyszerűnek tűnt...
A választ nagyon köszönöm, nem töröm rajta tovább a fejemet
-
thon73
tag
Meg tudnátok mondani, hogy miért nem tudom használni a clone()-t egy komolyabb (pl. egy RandomAccessFile) objektumra? A doksi szerint - mint objektum - rendelkezik ezzel a metódussal, az Eclipse mégsem engedi használni. Más osztályokkal is próbáltam, de az Eclipse-ben fel sem merül, hogy elfogadja... Bizonyára apróság, de nem jutok át rajta.

-
thon73
tag
válasz
WonderCSabo
#823
üzenetére
Hát pont ez az! Miért szükséges, ha csak a Reader-t (tehát csak olvasást) szinkronizál, és közben a Writer-t (írás, de nem csak másik példány, hanem osztály) nem szinkronizálja? Nem hagyhatnám ki egy az egyben?
-
thon73
tag
Sziasztok! A következő kódrészlet az android-17 source-ból van:
public abstract class Reader implements Readable, Closeable {
protected Object lock;
...
public int read() throws IOException {
synchronized (lock) {
...
return charArray[0];
}
return -1;
}
}
1. Miért kell egy olvasást szinkronizálni?
2. Ha jól értem a synchronized(lock) csak a "lock" objektum alapján figyeli a hozzáférést.
Mi akadályoz meg más példányokat abban, hogy ugyanahoz a hátterben álló adathoz hozzányúljanak, és különösen mi akadályozza meg a Writer osztályt, hogy időközben ne írjon bele ugyanebbe az adatstruktúrába?Készítettem uis. egy Reader osztályt, de nem értem, hogy miként véd meg a fenti elrendezés a Writer-től. Meg tudná ezt valaki világítani nekem? Köszi!
-
thon73
tag
válasz
pittbaba
#751
üzenetére
A problémával csak felhasználóként találkoztam. [link] Ez a program olyat tud, hogy az előtérbe került hívást (még a hallgató felvétele előtt!!) háttérbe nyomhatod, ahonnét később (amíg a hívás tart) előtérbe lehet venni, és felvenni. Tehát elvileg megoldható.
((Mielőtt valaki megkérdezné, hogy ez mire jó: hosszú úton SVOX-szal szoktam könyvet felolvastatni. De ha hívás érkezik, akkor a felolvasás megszakad, majd a telefon felvétele után beleolvassa a könyvet a telefonba. Na ezt szoktam befejezni egy mozdulattal, mielőtt fogadom a hívást.)) -
thon73
tag
Sztem., aki most kezd ismerkedni a java-val, az nem a közeljövőben fog a natív programozással foglalkozni, ne riogassátok őket! ((Mellesleg én ugyan fordítva, vagyis C után tanultam a java-t; de aki már ott tart, annak a natív rész nem sok gondot fog okozni...))
Megkérdezhetem, hogy pontosan melyik ez a könyv? Én szívesen belekukkantanék.
-
thon73
tag
válasz
shinodas
#733
üzenetére
ITT leírtam, amit csináltam. Menj be a megfelelő (sdk/platform-tools) mappába, ott az adb. És ne felejtsd előle a ./-t! (mint régi win-es, én is mindig lefelejtem, de a Linux NEM keres az aktuális mappában sem!)
Azóta tovább olvastam, a Google is azt írja, hogy így kell csinálni (kézzel). Két dolgot nem értek: miért kell ezt kézzel csinálni, ill. a Samsungnál pl. miért nem kellett csinálni? Annak az ID-jét talán tudta a cég, a kinaiékat meg nem?? -
thon73
tag
válasz
shinodas
#727
üzenetére
Akár hiszitek, akár nem, tegnap este ugyanebbe a problémába futottam bele. Mivel egy barátom Wayteq xTab-700dc készüléke nem óhajtott drivert telepíteni a munkahelyi WinXP alatt, hazavittem reggel, ahol viszont Ubuntu 12.04 van. Nem találta ez sem...
lsusb parancs alapján a Vendor-kód 2207, ezt beírtam a /etc/udev/rules.d/51-android.rules file-ba, közvetlenül a Samsung alá (ami viszont működik).
SUBSYSTEM=="usb", ATTR{idVendor}=="2207", MODE="0666"
Az adb device parancs azonban csak a Samsungot látta.Az ~/.android/adb_usb.ini file az én gépemen egyáltalán nem létezett (pedig sgsII prímán működik), mindenesetre létrehoztam ezt
0x2207
tartalommal. Kétségtelen, újra kellett indítanom a rendszert, de innentől az adb látja az xTab-ot is.
((Elég vicces a sorszáma:
0123456789ABCDEF
Gondolom, az összes többié is ugyanez lesz
))Csak azt nem tudom, az SO hozzászólásban lévő fejléc alapján nem kellene ezt
android update adb paranccsal készíteni. Mindenesetre az (még) nem ment, a fenti viszont igen.Neked sikerült beüzemelni?
-
thon73
tag
válasz
shinodas
#725
üzenetére
Az én tapasztalataim itt vannak: [link]
Gondolom, neked a Miként használjuk Linux alatt... rész lesz a jó. Nem az a gond, hogy nem jó a vendor kód a géphez? De ezt gép és udev file nélkül nem lehet megmondani.Apropó, az én fenti kérdéseimre senkinek nincs ötlete? Ez a Fragmentes dolog egyáltalán nem úgy működik nekem, ahogy a nagykönyvben meg van írva. (Igaz, legalább működik
) -
thon73
tag
válasz
pittbaba
#711
üzenetére
Én magam nem tudtam, de sztem. itt a megoldás: how-to-access-device-settings-programmatically
naandesh hozzászólása, első sor, ha gond az angol.
Írd meg, légyszi., hogy sikerült-e!Ja, és ne felejtsd az engedélyeket!! Köv. hozzászólásban ott van az is

-
thon73
tag
Tovább tudom finomítani a kérdést:
- A ListFragment MINDIG EmptyView-val indul, csak később készíti el a listát; gondolom, amikor a CursorLoader betölti az elemeket.
- Ez a második lépés kizárólag abban az esetben történik meg, ha a ListFragment először indul, vagy kiadom a ...getContentResolver().notifyChange(uri, null); parancsot. Az uri praktikusan bármi lehet, egyetlen elem, vagy az egész tábla, ez mindegy.
Enélkül elakad az EmptyView-nál.
- Ha debug-ban megyek végig a Fragment részein, akkor NEM jelenik meg az EmptyView, az onLoadFinished már korábban lefut, és az eredmény (Cursor) már fel van töltve.Megoldásként azt tudtam megtenni, hogy a fenti notifyChange parancsot minden - módosítás nélküli - visszatérés esetén kiadom. Ez azonban szerintem nem helyes technika. Másrészt szeretném tudni, hogy mi történik, hol a hiba. Minden ötletet szívesen várok!
-
thon73
tag
Íme egy újabb feladvány:
Egy ListFragment-et tölt fel egy CursorLoader, éppen úgy, ahogyan az API Guides/Loaders-ben meg van írva.
A program tökéletesen működik, hol a ListFragment, hol a másik ugrik fel. De csak akkor, amikor a másik fragmentben történik vmi. adatbázis változtatás. Ha változtatás nélkül térek vissza (pl. Back), akkor valamiért az EmptyView-t kapom meg.
Pedig az onLoadFinished mindig meghívásra kerül (változó, hogy hol, de mindig az onResume előtt). Sőt, az itt lévő Cursor tartalmazza az elemeket!! Hiába próbálom rávenni az Adaptert, hogy megváltoztak az elemek, marad az EmptyView.
Ha az Activity újraindul, akkor persze (először) működik. Ami fontos, a ListFragment-et tárolom, így mindig ugyanaz a Fragment "jön vissza".
Röviden: A ListFragment saját list View-ja nem érzékeli az Adapterben lévő Cursor-t.
Kérdéseim:
Találkozott már valaki ilyennel, és tudja, hogy mit rontottam el?
Ha nem, akkor tudja-e valaki, hogy miként tudnám kényszeríteni az adaptert v. a listView-t, hogy frissítse magát? Pontosabban HOL tudnám ezt megtenni, mert az egész lekérdezés az onResume UTÁN történik, minden ELŐTTE kiadott invalidate, notify stb. parancs hatástalan.
Vagy tudja-e valaki fejből merre kell keresnem a forráskódban azt a részt, ahol eldől, hogy Empty v. List view lesz a megjelenített?
Ami érdekes: hasonló tapasztalat van fenn a SO-n, de választ nem találtak rá. Ötletem még annyi van, hogy csinálok saját adaptert, aztán csak kiderül, hol a bibi. De ha valaki tudná a választ, az valószínűleg sok-sok órát megtakarítana.
Kódot szívesen küldök, de hosszú. Ha van érdeklődő, akkor megpróbálom a hibáig leegyszerűsíteni. Előre is köszönöm! -
thon73
tag
A kérdésem második felével kapcsolatban - vagyis, hogy mi történik, amikor a telefon elalszik - is érdekes viselkedést találtam:
Elalváskor dob egy onPause-onResume-onPause hármast, ébredéskor uez. visszafelé: -onResume-onPause-onResume.
A tesztet az Eclipse által létrehozott alapprogrammal (sehol egy fragment!) is megcsináltam, eredmény uez.
Tudja valaki, hogy ennek mi az értelme és magyarázata?(((Természetesen elfogadom, hogy minek kell izgasson ez az egész - ha egyszer működik. Csak a személyes gondom az volt, hogy elalváskor a rendszer a második onPause után valamiért belenyúl egy, az onPause-ban már lezárt adatbázisba. Ezt csak úgy tudtam kikerülni, hogy átpakoltam az egészet az onResume-onPause cikluson kívülre, így működik. Ami érdekes, hogy a hiba kizárólag elalváskor, és a második onPause után jelenik meg.)))
-
thon73
tag
válasz
SektorFlop
#684
üzenetére
Köszi!
-
thon73
tag
Hm. Úgy látom, a fragmentek kérdéskörével egyedül maradtam.
Én végül is változókban (is) tároltam el a visszakapott Fragmenteket. Így sikerült a számukat darabonként egyetlenre korlátozni. Ez az egy példány aztán hol bekerül egy View-be, hol kiveszem onnan. A kód működik, de hogy ez helyes megoldás-e, nem tudom. Gondoltam, azért esetleges későbbi olvasókkal ezt megosztom.Egy másik problémával kapcsolatban kérnék viszont jó tanácsot: Látszólag jól működik a program, tehát elfordításra is szabványosan leáll és újraindul. De ha az elfordítást kikapcsolt állapotban végzem el, akkor a program - hibaüzenet nélkül - leáll; pontosabban a Log-on jelentkezik egy le nem kezelt exception, amiről fogalmam sincs, hol ered. Az utolsó log-bejegyzés szerint az onPause lefutott. (minden visszahívást log-oltam) A hiba bekapcsoláskor jelenik meg, és ekkor már nem kapok debug üzeneteket.
A programot még tesztelem. A kérdés az, hol találhatok leírtást arról, mi (más) történik a programmal miközben a készülék stand-by-ba (és vissza) kapcsol? Azt gondolom, hogy egy onPause-onResume hívásnak kellene következnie, de erről nem találtam infot. Tud valaki esetleg ilyen jellegű forrást?
-
thon73
tag
Fragmentek körében - tud nekem segíteni valaki?

A kód hosszú, de ha kell elküldöm. A kérdések egyszerűbbek.
Ha egy Fragment objektumot létrehozok, az - már bizonyos - örökre megmarad.
Ráadásul, hiába adom ki a remove transactiont (és commit-ot is, persze), utána eltűnik, de az activity újraindulásakor visszalópódzik az elvileg üres View-ba.
A Tag és Id csak akkor él, amikor a Fragment be van rakva a View-ba.- Hogyan lehet ezt a létező Fragment-et (remove, commit után) fellelni? ((Az Activity felleli, mert indításkor visszapakolja! De én csak akkor tudom megtalálni, ha egy globális "változóban" tárolom.))
- vagy hogyan lehetne "destroy"-ra kényszeríteni?
- Tapasztalta-e már valaki a fentieket, ill. okozott-e ez problémát?
- Ti ezt hogyan csináljátok?A hiba akkor bukott ki, amikor egy amúgy jól működő(?) kód, minden fordításkor szaporítani kezdte a menu elemeket. További vizsgálódáskor találtam ezt, amit a doksi nemigen emleget. A neten a fentiekkel csak kérdés formájában találkoztam, választ nem találtam.
Előre is köszönöm, ha valaki fáradozik ezzel! -
thon73
tag
Kötözködés nélkül, és csak a teljesség kedvéért: single-tap esetén csak A_DOWN generálódik először, és csak mozdítás után A_MOVE. A konkrét példában ez nem látható (tehát igazad van), de ha az else-t kivesszük, akkor megfigyelhető, mert közeli érintésre (és nem mozgásra) is mozdul a joy.
A megelőző példában viszont először én sem tettem be az A_DOWN-t, és érintésre nem jelentek meg a karikák, csak mozgatásra. -
thon73
tag
Módosítok: az elv jó, csak megfogni nehéz így. Ha viszont az "else"-t kivesszük (vagy opt. miatt lehet "if (joyid[n]!=-1)"), akkor értelmet kap a DOWN ág is. Uis. már érintésre arrébb tud ugrani.
API17-ben van egy hypot() függvény, ami a distance számítást leegyszerűsíti (nekem API10-ben még nem működik.)
MATEMATIKUSOK!
Mi a legegyszerűbb számítás ahhoz, hogy a kör - az érintéstől függően - a periméteren keringjen? Csak szögfüggvénnyel megoldható?
-
thon73
tag
válasz
shinodas
#661
üzenetére
Itt egy lehetséges megoldás. API10 és AIDE alatt készült, de elvileg bármiben működik. 800x480 pixeles képernyőm van, de persze a méretek a képnek megfelelően változtathatóak. Az egyszerűség kedvéért beágyazott View-t használtam, ill. nem ellenőrzi a View beállításait, ez végleges megoldásnál ildomos!
A kód sok helyen nincs optimalizálva, inkább jól érthetőt akartam írni. ((Pl. én nem is tennék két joysticket egy view-ba, vagy ha igen, akkor két külön objektumként stb.))public class JoystickActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(new Felulet(this));
}
public class Felulet extends View
{
private float[] origox = {200f, 600f};
private float[] origoy = {180f, 220f};
private float joyx[] = {origox[0], origox[1]};
private float joyy[] = {origoy[0], origoy[1]};
private float joyarea = 150f;
private float joyrad = 40f;
private int joyid[] = {-1, -1};
private Paint area;
private Paint rad;
public Felulet(Context context)
{
this(context, null, 0);
}
public Felulet(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public Felulet(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
area=new Paint();
area.setStyle(Paint.Style.STROKE);
area.setColor(Color.RED);
area.setStrokeWidth(5f);
rad=new Paint();
rad.setStyle(Paint.Style.FILL_AND_STROKE);
rad.setColor(Color.GREEN);
rad.setStrokeWidth(5f);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
int pointerCount = event.getPointerCount();
for (int n=0; n<2; n++)
{
if (joyid[n] == -1)
{
for (int cnt = 0; cnt < pointerCount; cnt++)
{
if (distance(joyx[n], joyy[n], event.getX(cnt), event.getY(cnt)) < joyrad)
{
joyid[n] = event.getPointerId(cnt);
break;
}
}
}
else
{
boolean id_flag = false;
for (int cnt = 0; cnt < pointerCount; cnt++)
{
if (joyid[n] == event.getPointerId(cnt))
{
if (distance(origox[n], origoy[n], event.getX(cnt), event.getY(cnt)) < joyarea - joyrad)
{
joyx[n] = event.getX(cnt);
joyy[n] = event.getY(cnt);
this.invalidate();
}
else
{
// aránypárral v. szögfüggvénnyel mozgatható a kerületen
}
id_flag=true;
break;
}
}
if (!id_flag)
reset_joy(n);
}
}
break;
case MotionEvent.ACTION_UP:
reset_joy(0);
reset_joy(1);
break;
}
return true;
}
protected void reset_joy(int n)
{
joyid[n] = -1;
joyx[n] = origox[n];
joyy[n] = origoy[n];
this.invalidate();
}
protected float distance(float x1, float y1, float x2, float y2)
{
float x = x1 - x2;
float y = y1 - y2;
return FloatMath.sqrt(x * x + y * y);
}
@Override
protected void onDraw(Canvas canvas)
{
for (int n=0; n<2; n++)
{
canvas.drawCircle (origox[n], origoy[n], joyarea, area);
canvas.drawCircle (joyx[n], joyy[n], joyrad, rad);
}
}
}
}Az elv: a két index a két külön joysticket jelenti. Origox/y a közepe a két joysticknek, Joyx/y pedig az aktuális helyzete. Joyrad (kiskör) karikán belül lehet csak "megfogni" a joysticket, Joyarea (nagykör) sugaron kívül nem tud mozogni. A távolságot Pithagorasz tétellel számolja, ez nem a legjobb helyen van az osztályon belül.
A JoyId a legfontosabb: ha -1, akkor nincs érintés hozzárendelve (középen van a joystick). Ha egy érintés belelép a kiskörbe, akkor annak id-je lesz a JoyId és azt követi. A nagykör szélén megáll, de az érintéshez továbbra is ragaszkodik. Nem akartam bonyolítani, de az igazi az lenne, ha a köríven menne az ujjad után. (a megjegyzés helyén kezelhető ez)
Ha az Id eltűnik (ezt ellenőrzi a flag), vagyis azt az ujjad felemelted, akkor középre áll. Szintúgy akkor is, ha ACTION_UP lesz, vagyis minden ujj elhagyta a képet. Ilyenkor lehetne ütemadóval visszaúsztatni, de kis méretben az ugrás sem zavaró.
Ilyenre gondoltál? Remélem segít továbblépni, a lényeg úgyis az ID kezelés volt. Ha valami nem tiszta, szívesen segítek. -
thon73
tag
válasz
shinodas
#657
üzenetére
Pedig az nem nehéz, nekem inkább az időzítéssel gyűlt meg a bajom.
1. KÉT View esetén csak az egy érintéssel kell foglalkozni sztem.
2. KÖZÖS View-ban végig kell menni az összes érintés tömbjén, mint a fenti példában.
Én ellenőrizném a koordináták alapján, melyik ID koordinátája van a joystick körének területén.
A. lehetőség: Továbbra is végigmegyek az indexen, de ennek az ID-nek az alapján mozgatom a kört. Ha az ID eltűnt, akkor ez az érintés befejeződött. Kell keresnem egy újat, v. visszavinni középre a joysticket, és utána keresni.
B. lehetőség: ugyanúgy végigmegyek a tömbön, de nem foglalkozom az ID-vel, hanem ami megfelelően közel van a középpontjához, oda mozdítom a kört. Ha nincs ilyen, mehet vissza középre.Az egész kulcsa az, hogy amíg egy ponton is érinted a képet, az ID megmarad. Ha elengedted a képet, akkor teljesen új érintés kezdődik, új Idkkel. Ezért kell az elején a megf. érintést mindenképp a koord. alapján kiválasztani.
-
thon73
tag
válasz
shinodas
#655
üzenetére
Én lényegesen leegyszerűsíteném ezt a problémát. Készítenék egy speciális View-t, mely egy ilyen joystick-et mutat be. Ebből aztán kettő is elhelyezhető egy layoutban.
A joystick mindig középen áll. Ha megérintem valahol máshol a View-t (vagy a View belül egy kört is kijelölhetek erre), akkor a joystick/kör oda ugrik (és persze ezt az értéket kérdezhetem le). Ha elengedem, akkor visszaugrik középre.
Ez persze nem túl szép, mert a joysticknem ugrál, hanem szépen mozog. Ennek a szimulálására viszont el kell indítani a háttérszálon egy "ütem-adót", ami időnként jelzi a View-nak, hogy mozdítania kell egy kicsit a joystickon. Így úszhat a kör az érintés felé, vagy elengedésnél vissza középre. Az ütemadó nélkül nincs olyan esemény, ami a kör mozgását kiváltaná.
A másik lehetőség, hogy a kör csak akkor mozdul, ha az érintés a középpontjához megfelelően közel következett be. Ilyenkor nem kell ütem-adó, hiszen az "ugrás" megfelelően kicsi. Ez azt is szimulálja, hogy a joystick nem ugrik magától a kezembe, ha nem a tetejét fogom meg. Persze a "visszaúthoz" elengedés után még mindig szükséges az előző módszer.
((Nem dolgoztam még két külön View-val az érintéssel kapcsolatban, de nagy a gyanúm, hogy nem kell törődni, csak az elsődleges érintéssel, mert mindkettő azt kapja meg. Ezt ki kellene próbálnom.))
Ez persze csak az én ötletem, lehet, hogy más tud ennél jobbat is. Külön-külön már minden részét elkészítettem a folyamatnak, csak nem ilyen összefüggésben - ennek alapján szerintem azért el lehet vele játszani, mire összeáll, de megvalósítható. ((Ha nem sürgős, a konkrét megvalósításban is szívesen segítek, a grafika és az időzítés most nálam is pont napirenden van.)) -
thon73
tag
válasz
shinodas
#653
üzenetére
?? Ez azt jelenti, hogy a körök nem mozdíthatóak teljesen szabadon? Vagyis pl. nem keresztezhetik egymást? Mindkettőnek van egy saját területe? Mert akkor jobb lenne egy külön View-t alkotni egy körrel a közepén, amiben a kör - mint egy thumbstick mozgatható. Ha hozzáérsz valahol, akkor arra elmozdul a kör. Ha elengeded, akkor visszaúszik középre. Ez lenne a terv?
-
thon73
tag
Nem tudok elszakadni a felszaporodó fragmentek problémájától...
Sehol nem írják ezt a megoldást, pedig nekem minden bajomat megoldotta. Sőt! Portrait-ból Landscape-be való visszafordításnál a másodlagos Fragmentben lévő adatok is megmaradtak! (Lévén ugyanaz a Fragment jelent meg máshol)layout/main.xml
<FrameLayout
android:id="@+id/portrait"
... >
<FrameLayout
android:id="@+id/list_frame"
... />
<FrameLayout
android:id="@+id/edit_frame"
... />
</FrameLayout>layout-land/main.xml
<LinearLayout
android:id="@+id/landscape"
... >
<FrameLayout
android:id="@+id/list_frame"
... />
<FrameLayout
android:id="@+id/edit_frame"
... />
</LinearLayout>Vagyis: ugyanazok az id-k mind landscape,mind portrait módban. Természetesen portrait módban a két frame "átfedi" egymást, tehát a program logikájának kell megoldani, hogy hol az EDIT, hol a LIST fragment legyen felcsatolva a saját (átfedő) Frame-jébe.
Az egész program (ill. ez a része) csak KÉT Fragment Példányt tartalmaz. És egy Activity van (ez volt a cél)Szól ez ellen a megvalósítás ellen vmilyen. érv? Nekem működőképesnek tűnik. Mivel a két layout egyszerre nem valósul meg, az id-k sem akadnak össze. Mindkét frame mindig a "saját" frame-jébe lesz bekapcsolva, mindig a saját tag-jével jelölve. Nincs változás, nincs hibaüzenet. Mivel nem a frame-ek kapcsolnak ki/be, az animációk ugyanúgy látszanak.
Mégsem olvastam ilyen megoldást sehol. Van ezzel vmi baj szerintetek?
Tényleg senkinek nem volt még nehézsége a fragmentek megvalósításával? Tényleg senkinél nem szaporodtak még fel az elforgatások során?
-
thon73
tag
válasz
shinodas
#649
üzenetére
Ez csak egy bemutató-példa. Mi lenne a cél? Ha két fix alakzatot akarsz mozgatni, akkor azok koordinátáit kell külön tárolni, és egy-egy érintésnél legfeljebb a megfelelő ID-jű érintéshez rendelni.
Egy touchEvent az tényleg egyetlen érintés(sorozatot) ír le. Az ID arra szolgál, hogy EZEN BELÜL egy-egy ujjat kövessen akkor is, ha a többit felemeled (az index uis. csak felsorolja az aktuálisan hozzáérő pontokat, de a sorszám itt változhat.) Az már a Te programod feladata, hogy az alakzatok (és mozgásuk) valamint az érintések közötti logikát megalkossa. A bemutató csak minden mozdulatnál új alakzatokat rajzol az érintési pontokra, nem "gondoskodik" az alakzatokról, ezért is tűnnek el. -
thon73
tag
válasz
shinodas
#643
üzenetére
Két fontos dologra érdemes figyelni:
1. az onDraw minden invalidate után üres lappal indul. Ha meg akarod tartani az alakzatokat, akkor tárolni kell a koordinátáikat, és mindenannyiszor újrarajzolni őket. A gond az alakzatok "újra megfogásakor" jelentkezik: uis. honnét tudod, hogy egy már letett alakzatot kell mozgatnod, vagy egy újat? Legjobb lenne talán ellenőrizni, hogy az érintés vmelyik alakzat közelében van-e, és akkor azt hozzárendelni. De mindenképpen tárolni kell az adatokat.
2. nem az index számít, hanem az ID. Ez utóbbi ugyanis nem változik egy multitouch érintés során. Csak éppen nem sorban van, hanem végig kell nézni az indexeket és úgy kikeresni.
((És akkor még ott van a "historical" pontok sokasága, amivel nem foglalkoztunk.)) -
thon73
tag
Bocs, csak úgy értettem, hogy volt-e már valakinek ehhez hasonló tapasztalata. Neki is láttam egy egyszerűsített tesztkódot írni (az enyém meglehetősen hosszú).
Ez a teszt fragment, egyetlen metódus:public class TestFragment extends Fragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
TextView tv = new TextView(getActivity());
tv.setText("Hello világ!");
return tv;
}
}És a lényeg: az activity:
public class MainActivity extends FragmentActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
FrameLayout fl = new FrameLayout(this );
fl.setId(1234);
setContentView(fl);
}
@Override
public void onResumeFragments()
{
super.onResumeFragments();
FragmentManager fragmentManager = getSupportFragmentManager();
TestFragment test = (TestFragment)fragmentManager.findFragmentByTag("TEST");
if (test == null)
{
test = new TestFragment();
}
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(1234, test, "TEST");
fragmentTransaction.commit();
}
@Override
public void onPause()
{
super.onPause();
FragmentManager fragmentManager = getSupportFragmentManager();
TestFragment test = (TestFragment)fragmentManager.findFragmentByTag("TEST");
if (test!=null)
{
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// fragmentTransaction.detach(test);
fragmentTransaction.remove(test);
fragmentTransaction.commit();
}
}
}((Igazából ezeken a kódokon kívül az eclipse saját indítókódján semmit sem kell változtatni, mert a View-k dinamikusan jönnek létre. A rengeteg Log-ot kitöröltem, de akár minden metódus figyelhető a LogCat-ben.))
A LÉNYEG:
Sztem. az indítás során az onResumeFragments-ben hozzáadjuk a "TEST" fragmentet,
leállításnál az onPause-ben eldobjuk. (Ha akarjuk, akkor detach is lehet.)A REMOVE UTÁN SZERINTEM A FRAGMENTNEK EL KELLENE PUSZTULNIA A DESTROY FOLYAMÁN!
Ehhez képest újraindítás után hibaüzenet:
java.lang.RuntimeException: Unable to resume activity {.fragmenttest.MainActivity}: java.lang.IllegalStateException: Fragment already added: TestFragment{40525cf0 #0 id=0x4d2 TEST}Vagyis az eldobott Fragmentünk "visszajött".
Ugyanez történik ID és Tag alapú keresésnél is: az eldobott Fragment megjelenik
Ha két (landscape és portrait) layout között váltogatok, akkor még hibaüzenet sem jön, csak a Fragmentek sokasodnak.
((Világos, ha a remove átkerül a legelejére, akkor nem lesz hiba, de a Fragment megmarad))SZERINTEM:
A Fragment-ek NEM objektumként működnek, hanem sokkal jobban hasonlítanak az Activity-ra. Vagyis: létrehozás után (ez történik objektumok módjára), mindvégig megmaradnak, csak ide-oda kapcsolgathatjuk őket.
Az onRetain...-nál annyi különbség lehet, hogy ott érinetetlenül maradnak meg, itt meg a View újra készül.Ez azért gond, mert ha egyszer egy Fragmentet valamelyik View-ba bekapcsoltunk, akkor ragaszkodik a saját View-jához, más View ID esetén hibát dob.
Képzeljünk el egy szituációt: bal oldalon a lista, jobbra az egyes elemek, külön fragmentben. Ha ezt EGY activityvel oldjuk meg, akkor NÉGY fragmentet kell kezelnünk (2 landscape, 2 külön portrait módban) VAGY ha ugyanazt az Id-t adjuk meg a két külön layout-ban lévő fragmentet fogadó View-nak, akkor csak KÉT fragmentet kell kezelnünk.
Tudom, hogy a KÉT ACTIVITY-vel való kezelést preferálják, de 1. ettől nem tudom meg, miért nem tűnnek el a fragmentek. ((2. Az activity-k közötti kommunikáció miatt ez a megoldás most nem az igazi nekem (de ez a teszt szempontjából lényegtelen))Bocs, ha nem teljesen érthető ez, igyekeztem nagyon rövidíteni a kódot. De már csak azért is hajt a kíváncsiság, hogy ez miként műxik.
-
thon73
tag
Amíg a válaszokra vártam, tovább nyomoztam:
Úgy tűnik, ha egyszer egy Fragment példányt létrehoztunk, akkor az örökkön-örökké létezni fog a FragmentManager-ben - pontosabban addíg, amíg a program VÉGLEG be nem fejeződik (tehát nem konfig vált. miatt.) Ez meglehetősen furcsa működés, mert akkor mire szolgál a setRetainInstance?
Érdekes, jobban elolvasva a doksi is ezt mondja: a detach hasonló ahhoz, mintha a BackStack-en lenne a fragment, csak ilyenkor a FragmentManager tárolja.
Support package-ot használok API8 minimum mellett API17-tel fordítva.
Meg tudná ezt valaki erősíteni v. cáfolni? Lehet, h. ez egy hiba? Vagy a supporttal van valami gond? -
thon73
tag
-
thon73
tag
válasz
shinodas
#636
üzenetére
Pl. így? Az ID-t is kiírja.
private final int MAX_POINTER=10;
private float[] posx=new float[MAX_POINTER];
private float[] posy=new float[MAX_POINTER];
private int[] id=new int[MAX_POINTER];
private int pointerCount = 0;
@Override
public boolean onTouchEvent(MotionEvent event)
{
switch (event.getActionMasked())
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
pointerCount = event.getPointerCount();
for (int cnt = 0; cnt < pointerCount && cnt <MAX_POINTER; cnt++)
{
posx[cnt] = event.getX(cnt);
posy[cnt] = event.getY(cnt);
id[cnt] = event.getPointerId(cnt);
}
this.invalidate();
break;
}
return true;
}
@Override
protected void onDraw(Canvas canvas)
{
for (int cnt = 0; cnt < pointerCount; cnt++)
{
canvas.drawText(Integer.toString(cnt) + ", [" + Integer.toString(id[cnt]) + "]", posx[cnt], posy[cnt]-80f, text);
canvas.drawCircle (posx[cnt], posy[cnt], 30f, paint);
}
}
}
}Nem vagyok benne biztos, hogy a getAction() action_POINTER_up kódot is visszaad. Ahhoz sztem. getActionMasked() lekérdezés kellene. De lehet, h. rosszul tudom. A fenti megoldás viszont akár tíz ujjal is működik. (Már ha a hardver tudja...)
-
thon73
tag
Igen, a menü létrehozása tökéletesen megy. A menüt a fragmenten belül hoztam létre, és szeretném is, ha ott maradhatna. A gond akkor kezdődik, ha egy fragment osztály több példánnyal kapcsolódik be, mert akkor minden példány hozzáadja a saját menüjét. Ez idáig logikus is, de ha remove v. replece-szel elveszem a fragment-példányt (és persze a back-stack-ben sincs), a menüje akkor is megmarad. És - noha nincs már hivatkozás elvileg sehol erre a példányra - a menü az activity újraindítása után is megmarad! Minden indításnál új fragment-példányt adtam egy FrameLayout-ba (az előzőt elvileg eldobtam) és több száz bejegyzésem lett a menüben!
Tudom, vissza lehet szerezni a Fragmentet, a gond csak az, hogy ha egyszer valahova becsatoltam, ugyanazt a példányt (külön időpontban sem!) nem lehet másik Layout-ba becsatolni. Ezért kellene két példány egy fragmentből (külön elrendezésben tehát külön időben) de EGY menüvel egyszerre.
Egyetlen ötletem van: az activity onprepareoptionsmenu-jében ellenőrizni, hogy adott taggal van-e élő fragment, és eszerint betenni a menüt. De ha lehet, a fragmenten BELÜL szeretném a menükérdést megoldani. Csak nem megy…A BackStack kérdés egyszerűbb: az nekem is prímán működik. De ha nincs szükségem az utolsó elmentett transaction példányra, azt hogy tudom "visszajátszás" nélkül eldobni? Vagyis csak levenni a stackról, de nem végrehajtani.
Köszönöm!
-
thon73
tag
A mérgelődésen kívül két konkrét kérdésem lenne Fragment-ekkel kapcsolatban:
1. A Fragment által létrehozott Options-Menu a Fragment eltávolítása után is megmarad. Ha új Fragment példányt csatolok be, akkor az előző (eltávolított) példány Options-menu-je is, és az új is látszik. Ezt (a régi menüt) mivel tudom kitörölni a Fragment eltávolításakor? (Az előző Fragment már "eltűnt", vagy legalábbis tag keresésével nem találja meg. De a menu maradt.)
Az invalidateOptionsMenu nem működik, vagy nem tudom, hol kellene kiadni. A menu.clear() (pl. a prepare részben) viszont mindent kitöröl, és egyáltalán nem látszik a menü.2. Ha elmentettem egy transaction-t a backstack-re, és nem arrafelé megyek vissza (mert pl. elfordítottam a telo-t), akkor hogyan tudom azt onnan eltüntetni? ((A BackStack-on lévő elemek száma minden elfordításkor növekszik, hiába lesz közben "Destroy". Ez nem is lenne baj, csak a visszafordításkor az alap Fragment-ről szeretnék indulni, miközben a "második" Fragment (vagyis a tranzakció) el van mentve a BackStack-re.))
API17-tel fordítottam, de API8 minimumra, tehát support package-t használtam. Elvileg ez nem lehetne baj. Előre is köszönöm, ha valakinek van ezzel tapasztalata.
-
thon73
tag
Elkezdtem haladni a korral, megismerkedtem a Fragment-kezeléssel.
DE!
Az normális, hogy az Android Developers honlapon lévő példakódok hibásak??
Namármost, ahogy végiggondoltam, úgy viszont működik (és a hibás elgondolást is megtaláltam a példakódban).
Van viszont erről (Fragment) valahol használható leírás, hogy mi a helyes felhasználás módja, vagy mindenki kitalálja magának oszt lesz ami lesz??
Vagy mi van ilyenkor, amikor a "HIVATALOS" dokumentáció hülyeséggel példálózik? -
thon73
tag
...feladtam a harcot az Android életciklusainak megértésére. Sztem. a fejlesztők is, API11 felett teljesen más módszereket alkalmaznak.
Segítséget szeretnék kérni: egy príma Wayteq xtab700dc-t szeretnék rábírni az Eclipse-szel való együttműködésre most WinXP, (egyébként linux alatt, ami esetünkben könnyebbnek tűnik).
Android 4.1.1 alatt kell windows driver? Ha igen, tudja-e valaki, hogy ezekhez a remek kínai termékekhez hol lehet szerezni/mit lehet használni?
Van egy "Internal Memory" (pontosabban csak az van...) feliratú fa-struktúrám. (nem rootolt gép). Ez vajon hova lehet be-mountolva? Vagyis hogyan érhetem el programból? (Rögtön a '\' alatt lehet?) Ha esetleg valaki rootolt gépet használ, megnézné?
Előre is hálásan köszönöm!
((Bocsánat, hogy nem tényleges programozást kérdezek, de oda szeretnék eljutni ezzel a géppel is. Másutt nem hiszem, hogy segítséget találok erre a problémára...)) -
thon73
tag
Még egy apróság: a problémám abból fakad, hogy a dokumentáció kihangsúlyozza, az onPause után az Activity-t a rendszer kilőheti.
Ezzel szemben többen állítják (és elvileg ez így kell legyen, hiszen az activity csak egy objektum, hogy lehet eltüntetni egy objektumot?), hogy a rendszer Activity-t nem, csak process-t tud kilőni. Márpedig a teljes application egy processben van benne.
De akkor hogyan lehetséges, hogy az egyszerű példaprogramom újra el tud jutni az onCreate-be, onDestroy nélkül. Kilőtte a rendszer a process-t az egész alkalmazás alól?
Kételyek között vagyok - nem értem az egészet.És a source-ban is elég nehéz egy ilyen komplex eseményt lenyomozni... -
thon73
tag
Pontosan. Ha onPause-ban bezárom, akkor nem lesz.
DE:
onPause után a rendszer bármikor bezárhatja a programot, és akkor az onStop ill. onDestroy nem kerül meghívásra. Ha a zárás az onDestroy-ban van, akkor soha nem kerül meghívásra és bezárásra.Ez a helyzet sokkal gyakoribb, mint gondolnánk. Most próbáltam tesztelni: ha home-mal lépek ki a programból, és utána egy csomó minden mást elindítok (ez azért gyakori), akkor az eredeti program figyelmeztetés nélkül bezár ((egyébként a gyakorlatban ez az onStop után következik be, elméletileg már az onPause után is bekövetkezhetne))
Azt nem tudom, zavarja-e az adatbázist és a cursor-t, ha nyitva marad. Szerintem nem, mert adapterről van szó, tehát csak olvasásról.
Zavarja-e a rendszert, ha nyitva marad az adatbázis? Mem-leak?
Vagy ne foglalkozzak az egésszel, mint ahogy a legtöbb példaprogram teszi.Egy ideje olvasgatok erről, de sehol nem találtam korrekt módszert a zárásra. Kivéve az onPause-onResume párosát, de annak meg más baja van. (vagyis túl gyakran kerül meghívásra.) Szerintem az egyik legnagyobb hiba az Android tervezésében, hogy az onPause után megengedett a rendszernek az erőltetett kilépés. Mi a nyavajáért nem fejezheti be ilyenkor a dolgát a program!?
((A listView esetén sajnos teljes activity-ben kell gondolkodni: amíg a listview látszik, addig az adapter aktív, tehát kell a nyitott cursor és adatbázis is.)) -
thon73
tag
válasz
SektorFlop
#573
üzenetére
Kellene. Elvileg. A LogCat tele lesz hibával, ha nem zárod, de a program működik. Alattomos.
A lista jó, ilyen szempontból, csak zabálja a memóriát. Mindent kétszer tárolsz, másolsz, stb. Én csak próbálgatom az SQLITE-t, de a végleges megoldásban több, mint kétszázezer rekordot kellene kezelnem. igaz rövidek, az egész nincs 10 mega. -
thon73
tag
válasz
SektorFlop
#571
üzenetére
Sianis-nak: Igen, ez fontos észrevétel, nem gondoltam rá. Így már akkor is visszaáll az elejére, ha csak pl. megnézek külön egy rekordot, hiszen más Activity kerül előtérbe. Hm.
Ez a téma szerintem sokaknak okoz fejtörést. Honeycomb felett változott egyébként a megközelítés (és én még nem tartok ott), de sajnos, a konkrét probléma ettől még megmarad.
A probléma veleje: az Activity az onCreate-onStart-onResume metódusokon kersztül indul, és rendre az onPause-onStop-onDestroy metódusokon áll le. Ezek persze párban állnak, tehát ha csak az onPause-ig jut a leállás (más kerül az előtérbe), akkor az onResume ponton éled fel a program.
Ez azt jelenti, hogy az onCreate-ben megnyitott adatbázist az onDestroyban kellene bezárni. Ha előbb zárjuk be (pl. onPause), akkor visszatéréskor (onResume-tól kezdődik), nem lesz nyitott adatbázisunk (mivel a megnyitást végző onCreate nem kerül meghívásra!)
DE! ÉS ITT JÖN A BAJ! Az Android rendszer - ha fogy a memória - CSAK AZ ONPAUSE VÉGREHAJTÁSÁT GARANTÁLJA! Simán kihagyja az onDestroy-ban lévő zárást.
Az adapternek viszont végig szüksége van a nyitott adatbázisra, ill. a hozzá tartozó cursorra. Ezért jutottam oda, hogy a listát az onResume-ban kell lekérdezni és megalkotni, aztán az onPause-ban bezárni. Sianis-nak azonban igaza van, ezzel minden apró-cseprő dolog miatt újraépül a lista.Kérdések:
- lehet, hogy nem kell törődni az onPause utáni kényszerleállással? A vélemények szerint kell, saját tapasztalatom nincs (túl nagy a memóriám
)
- javítja-e a helyzetet, ha onPause-ban pl. a lista helyzetét is tároljuk?
- van-e valakinek precízebb ötlete?
- javasolják a singleton-t (Application-ból származtatva), ami járható út; így ugyanis a teljes Application (és nem Activity!) futás alatt nyitva marad az adatbázis (és a cursor). De honnét tudom, hogy véget ért a történet, és be kell zárni az adatbázist?Néha nem látom át, hogy milyen logika alapján képzelték el ezt az egészet. Igaz, én csak amatőrben játszom...
-
thon73
tag
Érdekes. Az egész adapter-kérdést az onResume-ba helyezve is működik. (bocsánat, az előbb elírtam onStart-ra, de az onPause párja az onResume)
Tehát: adatbázis megnyitás, query, majd a simplecursoradapter az onResume-ban van,
cursor zárás, adatbázis zárás az onPause-ban.
((Az más kérdés, hogy a gyakoribb lekérdezés lehet hosszú, de most csak néhány elemről van szó - inkább az elmélet megértésére.))
A kérdés most fordítva merül fel bennem: van valami oka, amiért annyi más (hibaüzenetet adó) megoldás mellett ezt nem találtam a neten? Nekem elméletileg és gyakorlatilag is korrektnek tűnik (időtényezőt nem nézve); szól ez ellen a megoldás ellen valami, amit nem vettem észre? -
thon73
tag
Köszönöm! Mindkét link nagyon hasznos!
Egy újabb apró kérdés, amin nem jutok át (google segítséggel sem). Ki tudja, hogy az adapterben átadott nyitott adatbázist és cursor-t hol kell bezárni? A doksi az onDestroy-t javasolja (és az logikus is, mint az onCreate párja), de a program az onPause után is meg tud lógni...
Vagy hogyan tudom az onStart-ba tenni az adapter elkészítését? Az nem kell az onCreate után kész legyen? (ListActivity-ben) Előre is köszönöm!
Új hozzászólás Aktív témák
- PlayStation 5
- Milyen processzort vegyek?
- PlayStation 1 / 2
- Diablo II: Classic és Resurrected
- One otthoni szolgáltatások (TV, internet, telefon)
- Apple iPhone 17 Pro Max – fennsík
- Audi, Cupra, Seat, Skoda, Volkswagen topik
- Napelem
- Elektromos autók - motorok
- Milyen egeret válasszak?
- További aktív témák...
- Eladó Lenovo Legion Y530 magyar vil.bill.
- 512GB M.2 NVMe SSD-k nagy tételben eladók.
- HP EliteBook 755 G5 Ryzen 5 PRO /16GB RAM /500 GB SSD/15.6 FHD / magyar bill.garanciás laptop
- Új! WHITE 4K GAMER PC! AMD RYZEN 7 7800X3D / RX 9070XT 16GB / 32GB 6000Mhz / 1TB Nvme / 750W GOLD
- Gamer Pc jó áron! RTX 4060/16GB Ram/1TB SSD/R5 5500
- Apple MacBook Air 13 (2020) M1 8GB/256GB használt, szép állapot 87% akku (317 ciklus)
- ÁRGARANCIA! Épített KomPhone Ultra 9 285K 32/64GB RAM RTX 5080 16GB GAMER PC termékbeszámítással
- GYÁRI TÖLTŐK Macbook Magsafe 1 és 2 Budapest,/MPL/Foxpost
- Szép állapotban Lenovo ThinkPad T14s Gen 4 i5-1335u/16 GB/256 SSD/FHD+/IPS/Garancia 2027
- Kezdő Gamer PC-Számítógép! I5 6500 / GTX 1050Ti / 8GB DDR4 / 240GB SSD
Állásajánlatok
Cég: Laptopműhely Bt.
Város: Budapest

Bocsánat Google, az előző kiadás óta javították a 64 bitet...

, meg amúgy is elolvasásra érdemesnek tartom:

Azt szeretem az androidban, hogy olyan konzekvens...

))

Én végül is változókban (is) tároltam el a visszakapott Fragmenteket. Így sikerült a számukat darabonként egyetlenre korlátozni. Ez az egy példány aztán hol bekerül egy View-be, hol kiveszem onnan. A kód működik, de hogy ez helyes megoldás-e, nem tudom. Gondoltam, azért esetleges későbbi olvasókkal ezt megosztom.
