Android

To zabezpieczenie nie ma sensu, gdy len == 0 pętla się po prostu nie wykona. A jaki wyjątek rzuca?

Reply to
ohouapss
Loading thread data ...

A może problem wynika z tego, że jak nic nie wpiszesz to dostajesz null, na rzecz którego próbujesz wywołać jakieś metody? Już buf.length może być problematyczne. Wtedy potrzebny byłby test na null i tyle.

Reply to
ohouapss

W dniu 09.02.2011 19:59, Lelek@ pisze:

Chyba trochę namieszałeś: > byte buf[] = new byte[256]; Tworzysz nową tablicę typu byte. Powinna być czytelna w odróżnieniu od tablicy Byte w której trzeba dodatkowo utworzyć każdy element.

Reply to
Michoo

Przed koncem ? Raczej powinna przed poczatkiem - jak rozumiem to getBytes alokuje nowy bufor na odpowiedz.

Przy odrobinie optymalizacji moze nawet nie alokuje wtedy gdy wyraznie piszesz new ..

J.

Reply to
J.F.

W dniu 2011-02-09 19:59 Lelek@ napisał(a):

[...]

Hmmm, coś chyba ściemniasz. Skopiowałem twój przykładowy kod i odpaliłem w emulatorze 2.2. Na głównej aktywności mam kontrolkę edycyjną o nazwie "editText1". Tak wygląda cała metoda (podpiąłem jej wywołanie pod naciśnięcie dodatkowego przycisku):

public void test() { EditText editText = (EditText) findViewById(R.id.editText1); String fromEditText = editText.getText().toString();

byte buf[] = new byte[256]; int bfx[] = new int[256]; int i, len;

try { buf = fromEditText.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); return; }

len = buf.length;

for (i = 0; i < len; i++) { bfx[i] = ((int)buf[i] & 0xFF); Log.d("TEST", "BYTE: " + bfx[i]); } }

Znajduje się tu wszystko, co przytoczyłeś plus dodatkowy kod na początku do odczytania ciągu znaków z kontrolki edycyjnej. Początkowe zaalokowanie bufora buf nie ma znaczenia bo metoda getBytes() i tak zwraca tablicę bajtów i zmienna buf zostanie nadpisana. Prościej jest nie deklarować tej zmiennej na początku tylko dopiero gdy jest potrzebna, np: byte buf[] = fromEditText.getBytes("UTF-8");

W każdym razie uruchomienie daje spodziewane rezultaty. Gdy kontrolka jest pusta to nic się nie wywala, metoda getBytes() zwraca pustą tablicę a nie null, w zmiennej len mamy wartość 0 i nic się nie wypisuje.

Natomiast gdy do kontrolki edycyjnej wpiszę jakiś tekst to także powyższy kod działa zgodnie z oczekiwaniami. Na debugu (to ten magiczny LogCat, w Eclipse możesz go pokazać wybierając z menu: Window/Show view/Other/Android/LogCat albo prościej naciskając Ctrl+3 i wpisując "logcat") jest to pokazywane:

02-09 22:04:03.585: DEBUG/TEST(336): BYTE: 97 02-09 22:04:03.585: DEBUG/TEST(336): BYTE: 100 02-09 22:04:03.585: DEBUG/TEST(336): BYTE: 97 02-09 22:04:03.585: DEBUG/TEST(336): BYTE: 109

Chyba nie unikniesz pokazania większego kawałka kodu aby ustalić co się wywala właściwie. Możesz spakować cały projekt i wrzucić gdzieś na sieć?

Reply to
Adam Dybkowski

No to chyba się wyjasniło

Tutaj buf jest referencją do twojej tablicy...

Ale tutaj już buf jest referencją do obiektu zwróconego przez FromEditText.getBytes(). Wskazanie do tablicy, która zaalokowałeś zostało stracone i przydzieloną pamięcią zajmie się przy najbliższej okazji garbage collector. Powyższy kod jest równoważny takiej linijce:

byte buf[] = FromEditText.getBytes("UTF-8");

Ja bym twój kod przepisał do takiej postaci:

byte buf[] = FromEditText.getBytes("UTF-8"); int bfx[] = nil; if(buf.length>0) { bfx[] = new int[buf.length]; for (i = 0; i < buf.length; i++) { //elementy buf mają po 8 bitów, więc maskowanie 0xff //jest trochę bez sensu bfx[i] = ((int)buf[i] & 0xFF); } }

if(bfx!=nil) { //robimy cos z bfx }

Bardzo ważne jest alokowanie pamięci na bfx po odczytaniu zawartości buf. Przy alokowaniu bfx o stałej długości, dopóki FromEditText.getBytes zwróci tablicę mniej niż 256 bajtów, program będzie działał poprawnie. Ale jeśli buf będzie dłuższe niż długość bfx, program wywali się z błędem dostępu do pamięci przy próbie zapisu pierwszego elementu, który się nie mieści w bfx.

BTW. próbowałeś przechwytywać wyjątki?

pzdr. j.

Reply to
Jacek Radzikowski

Zadeklaruj buf tak, żeby był widoczny wszędzie gdzie występują odwołania do niego. Z kodu, który zacytowałeś wynikało że buf jest deklarowany na tym samym poziomie zagłębienia co odwołanie do FromEditText.getBytes(). A ifie brakuje jeszcze jednego warunku: if((buf != nil ) && (buf.length>0))

A fakt. Zasugerowałem się typem buf i przyjąłem że bfx też jest typu byte :)

pzdr. j.

Reply to
Jacek Radzikowski

Shit bo nie umiesz się nią posłużyć. Napisałem w javie dobrych kilkadziesiąt tysięcy linii i uważam że jest to całkiem przyjemny język. Inne języki też znam, więc mam porównanie.

Nie bardzo wiem o co chodzi, ale mam wrażenie że usiłujesz zrobić coś na około.

Jak powiesz czego nie rozumiesz, to może będę mógł Ci pomóc. Na razie widzę że walczysz z samą ideą obiektów. Bufora nie deklarujesz kilka razy. Samą zmienna buf deklarujesz raz, w takim miejscu żeby była widoczna ze wszystkich miejsc w których musisz się do niej odwoływać (ale bez przesady. Najprawdopodobniej wystarczy ze zadeklarujesz ją lokalnie w funkcji). Buf w twoim przypadku przechowuje nie sam obiekt, a referencję do niego (referencja działa troszkę podobnie jak wskaźniki w C, choć to nie do końca jest to samo). Funkcja FromEditText.getBytes() sama alokuje pamięć na tablicę zawierającą wynik i zwraca Ci wskazanie na nią. Ta referencja jest wpisywane do zmiennej buf. Jeśli przed wywołaniem funkcji było w niej coś innego, poprzednia wartość jest tracona, a w jej miejsce jest wpisywana wartość zwracana przez przez getBytes. Nie następuje tam żadne przepisywanie tablic (dlatego nie trzeba wcześniej alokować pamięci).

Wszelkie operacje jakie wykonasz na zmiennej buf po wpisaniu do niej wartości zwróconej przez getBytes będą wykonywane nie na twojej tablicy, a na tablicy zaalokowanej wewnątrz funkcji. Sprawdzanie warunku buf.length jest potrzebne po to, żeby nie tworzyć tablicy o zerowej długości (przypisanej do bfx).

Może to ci, którzy przesiadają się na jave z bascoma :) Ja też widziałem dużo śmieci, ale też bardzo dużo kodu bardzo dobrej jakości.

Nie tyle zapominali, co woleli się skupić na rozwiązaniu problemu zamiast babrać się z gospodarką pamięcią. Operując na wskaźnikach bardzo łatwo z prostego programu stworzyć koszmarek - java stara się do tego nie dopuścić (a przynajmniej nie przez jeżdżenie po pamięci). Mając do dyspozycji dużo wolnego ramu, nie trzeba się martwić żeby jak najszybciej zwolnić przydzielony a nieużywany obszar. Ręczna gospodarka przydzielaną pamięcią w bardziej skomplikowanych projektach może przypominać chodzenie po polu minowym. Nic dziwnego że nawet najlepszym i najbardziej uważnym programistom zdarza się popełnić głupie błędy, typu nie zwalnianie czegoś czy wielokrotne zwalnianie. Mechanizm odzyskiwania nieużywaniej pamięci jest implementowany w wielu językach wysokiego poziomu. Java jest tylko jednym z nich.

pzdr. j.

Reply to
Jacek Radzikowski

Dnia 07-02-2011 o 12:39:30 Lelek@ snipped-for-privacy@nndn.pl napisał(a):

Wszystko jest totalną porażką jeśli się nie ma odpowiedniej wiedzy :) Jedyne do czego można się przyczepić to, że kompilator Cie nie ostrzegł przed użyciem niezainicjowanej zmiennej. No chyba, że ostrzegł, tylko należysz do tych co instrukcje obsługi czytają dopiero jak wszystkie inne sposoby zawiodą :)

Reply to
Shaman

Alez byla zainicjowana i to nawet dwa razy.

Co najwyzej Javie brakuje definicji funkcji ktora moze zwrocic NULL zamiast referencji i ostrzegania jesli programista nie sprawdza tego warunku przed odwolaniem :-)

J.

Reply to
J.F.

Dnia 11-02-2011 o 14:06:52 J.F. <jfox snipped-for-privacy@poczta.onet.pl> napisał(a):

hmm.. jeszcze raz przejrzałem posty Lelka i nie widzę, żeby gdzieś ją inicjował.

Zwykła Java z tego co kojarzę inicjuje takie pola jedynie w wypadku gdy są to prywatne pola klasy. Pól deklarowanych w metodach Java nie inicjuje - w sensie "zeruje obszaru pamięci zajmowanej przez to pole". Tak jest w "zwykłej" javie.. nie wiem natomiast jakie cuda z tym kodem źródłowym czynią narzędzia dla AVR. Możemy się wymądrzać a okaże się, że całe to zamieszanie jest efektem niezamierzonym :)

Reply to
Shaman

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.