Temat: Problem z migotaniem ImageView

Staram się zrobić prosty program na andka i za pomocą kontrolki ImageView wyświetlać bitmapy które dynamicznie zmieniam. Obrazki się wyświetlają, i to dość szybko ale i równie szybko znikają... Proszę o pomoc, próbowałem już chyba wszystkiego, wątków, timera, i teraz kodu poniżej, ale efekt taki sam - migoczący obraz.


private final Runnable UpdateImg = new Runnable()
{
public void run()
{
Update();
HandlerUpdate.post(UpdateImg);
}

};


private void Update()
{

byte[] buffer = NextFrame.Get(); //Tworzy obrazek
ImgViewMain.setImageBitmap(BitmapFactory.decodeByteArray(buffer, 0, buffer.length)); //Wyświetla
}

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//[ ... Inicjalizacje itp ...]

HandlerUpdate.post(UpdateImg);
}


EDIT:

Innymi słowy po zakończeniu się HandlerUpdate.post(UpdateImg);
Obrazek znika, niezaleznie, czy metodę Update ustawię w timerze, czy wątku.
Jednak jeśli wywołam ją samodzielnie tak jak poniżej, to obrazek się pojawi i już zostanie.


public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//[ ... Inicjalizacje itp ...]

Update();
}
Mateusz Grzelak edytował(a) ten post dnia 24.08.11 o godzinie 18:46
Michał Kąkol

Michał Kąkol Rozwiązuję problemy,
przenoszę firmy do
internetu.

Temat: Problem z migotaniem ImageView

rozumiem, że obrazek uaktualniasz w handlerze, bo z roznych watkow/runnable itp nie mozna uaktualniac UI

chociaz z tego kodu dziwnie to wyglada, jakbys w runnable uaktualnial image co jest niedozwolone

[edit]: dodaj

Handler hRefresh = new Handler(){

public void handleMessage(Message msg){
switch(msg.what){
case UPDATE_IMG:
updateImg();
break;
default: break;
}
}

a w runnable zamiast updateImg(); odpal hRefresh.sendEmptyMessage(UPDATE_IMG);

oczywiscie update musi jakos dobrze sie odwolywac do istniejacych obiektowMichał Kąkol edytował(a) ten post dnia 24.08.11 o godzinie 17:56

Temat: Problem z migotaniem ImageView

Tylko updateImg to nie metoda tylko obiekt Runable więc go nie moge wywołać jako updateImg(), tylko co najwyżej wykonać poprzez metodę post Handlera:

HandlerUpdate.post(UpdateImg);


Stosując poradę zrobiłem coś takiego żeby pojawił się chociaż jeden obrazek i pozostał, ale się nic nie wyświetla. Jedynie miga tak samo jak w pierwszym kodzie.


Handler hRefresh = new Handler()
{

public void handleMessage(Message msg)
{
Update(); //Ta metoda zmienia obrazek (jak w 1 poście)
}
};




private Runnable UpdateImg = new Runnable()
{
public void run()
{
hRefresh.sendEmptyMessage(UPDATE_IMG);

//Opcjonalnie z pętlą
//HandlerUpdate.postDelayed(UpdateImg, 30);

}

};



public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//[ INICJALIZACJE ... itp]

HandlerUpdate.postDelayed(UpdateImg,1000);
}


EDIT:

Na podstawie porady znalazłem dokładniejszy opis propozycji, gdzie wszystko jest szczegółowo opisane:
http://me.codingthings.com/blog/android-sdk-timers-and...

i zastapiłem fragment:


//Opcjonalnie z pętlą
//HandlerUpdate.postDelayed(UpdateImg, 30);


na:


HandlerUpdate.removeCallbacks(UpdateImg);
HandlerUpdate.postDelayed(UpdateImg, DELAY);


Niestety po części rozwiązało to problem, a po części go jeszcze bardziej skomplikowało, gdyż jesli czas opóxnienia DELAY ustawię na 1000 ms to widać że obrazki nie wygasają, tak samo jak bym wywoływał update przy inicjalizacji. Jednak jesli DELAY zmienię na 25 ms, czyli tyle ile musze uzyskać to obraz migocze jak poprzednio ...

Nie ma jakiejś innej możliwości, bardzo szybkiego wyświetlania Bitmap ?Mateusz Grzelak edytował(a) ten post dnia 24.08.11 o godzinie 19:10
Michał Kąkol

Michał Kąkol Rozwiązuję problemy,
przenoszę firmy do
internetu.

Temat: Problem z migotaniem ImageView

Mateusz Grzelak:
Nie ma jakiejś innej możliwości, bardzo szybkiego wyświetlania Bitmap ?

a google nic na ten temat nie wie? :)

moze image switcher? kolejne obrazki bedziesz dodawal jako kolejny element imageswitchera, a w handlerze zmienial obrazek na nastepny - should work ;dMichał Kąkol edytował(a) ten post dnia 24.08.11 o godzinie 19:22

Temat: Problem z migotaniem ImageView

Po włączeniu LogCat'a znalazłem w końcu prowodyra, problem występuje gdy pojawia się Log typu:


tag
skia

Message
--- SkiImageDecoder::Factory returned null

oraz

Message
--- decoder->decode returned false


i ma miejsce gdzieś w linii samego wyświetlania:

ImgViewMain.setImageBitmap(BitmapFactory.decodeByteArray(buffer, 0, buffer.length));


Więc pseudo timery nie były złe... jak tylko znajdę co to oznacza i czym jest spowodowane, to dam znać...Mateusz Grzelak edytował(a) ten post dnia 24.08.11 o godzinie 23:49
Michał Kąkol

Michał Kąkol Rozwiązuję problemy,
przenoszę firmy do
internetu.

Temat: Problem z migotaniem ImageView

aaaa hahha no tak, jedna fajna rzecz

decodebytearray czasami zwraca null - taki psikus od androida

w razie zwrocenia null jeszcze raz sprawdz

ja mialem taka rzecz ze pobierajac okolo kilkuset zdjec i zapisujac je na dysk ciagle wyswietlam wszystko na liscie i w czasie przesuwania wczytywane pliki jpg z karty/pamieci wewnetrznej czesto zwracaly null

problem rozwiazalem dobry while'em w ktorym w przypadku zwrocenia null jesszcze raz probuje kilka razy wczytac i wszystko bangla, czasami za drugim razem, czasami za 7-8rzem wczyta sie fotka ale dla uzytkownika koncowego nie widac zadnej roznicy bo wszystkie zdjecia sie laduja jedno po drugim z automatu gdy przesuwa liste

Temat: Problem z migotaniem ImageView

Zgadza się, w moim wypadku pobierałem dane poprzez połączenie TCP
Serverem jest PC, klientem Android.
Z tego co zauważyłem teraz nawet połowa Bitmap nie jest przesyłana prawidłowo. Myślałem, że w TCP nie ma możliwości jak w UDP utraty danych ???

kod:

public byte[] Get() throws IOException
{

int availibleData = MyInputStream.available();

while(availibleData == 0)
{
try{Thread.sleep(2);}catch(Exception e){}
availibleData = MyInputStream.available();
}
buffer = new byte[availibleData];

MyInputStream.read(buffer);

return buffer;
}


Oszukującą mnie metodą jest MyInputStream.available(); Mimo, że rozmiar Bitmap jest niemal identyczny +- 50B to owa metoda jakimś cudem zwraca wartości z przedziału +- 2000B;

Tak też teraz zamiast migania mam śnieg jak w starych telewizorach.
Michał Kąkol

Michał Kąkol Rozwiązuję problemy,
przenoszę firmy do
internetu.

Temat: Problem z migotaniem ImageView

nie chodzi o utrate danych, chodzi o to ze android w momencie wczytywania obrazka (dekodowania) nie gwarantuje poprawnosci tej czynnosci nawet gdy obrazek fizycznie istnieje i widzisz go innym programem, dlatego warto zrobic sobie dobrego while i sprobowac kilka razy nim program pojdzie dalej i nie wczyta obrazka

ja w swoim programie sprawdzam istnienie pliku a jezeli takowy istnieje to w petli while chyba do 10-15 powtorzen sprawdzam wynik dekodowania pliku, jezeli null to jeszcze raz, a jezeli sie wczytal wszystko leci dalej dzieki czemu zniknal problem niewyswietlonych plikow :)

Temat: Problem z migotaniem ImageView

Sprawdziłem dokładnie i na 1000% winna jest moja sieć, niezależnie od prędkości wysykłi (Delay) zawsze conajmniej od 1500B do 4 000B jest przesyłane prawidoło, a reszta to już tylko random. Jutro postaram się sprawdzić ciągłe wysyłanie podzielonych tablic bajtów. Myślę,że to może rozwiązać problem.
Bo kiedy wstawiam wila to po prostu wiruje w nieskończoność, jako że dane są faktycznie uszkodzone.Mateusz Grzelak edytował(a) ten post dnia 25.08.11 o godzinie 02:23
Michał Kąkol

Michał Kąkol Rozwiązuję problemy,
przenoszę firmy do
internetu.

Temat: Problem z migotaniem ImageView

no to powiedz czemu gdy mam zapisane wszystkie pliki jpg w pamieci telefonu w czasie wczytywania rowniez lapie nulle? ;d

temat poznalem dokladnie przeszukujac stackoverflow i oficjalna strone googla i na ktorejs z podstron (developers.android.com) jest jak byk napisane, że nie mozna byc pewnym zwracanego rezultatu decode

a jezlei chodzi o pamiec, moze chodzi ci o 4k kb - byloby logiczne bo tyle daje wirtualna maszyna pamieci, i jezeli ja przekroczysz to wycina wszystko kolejne na null i rzuca wyjatkami na lewo i prawo, wystarczy zaladowac za duzo fotek albo co gorsza resize'owac duze fotki do mniejszych rozmiarow - gdzies jest wyciek pamieci i system mowi do aplikacji: hasta la vista babe!!

Temat: Problem z migotaniem ImageView

To że czasami null'uje to w pełni potwierdzam ale jest to o wiele mniejszy % w moim wypadku w stosunku do ilości pobranych tablic, które róznią się od swoich oryginałów przed wysyłką przez sieć. Więc szybciej dla mnie pominąć taką Bitmapkę, gdyż zależy mi na dostępie w czasie rzeczywistym do obrazu.

Jeśli tablica przed wysyłką ma 100 KB, a po przesłaniu już tylko 1,5KB to coś jest nie tak również z połączeniem. Zauważyłem również, że jeśli tablica jest ucinana to o wiele częściej pojawia się null.

tj:

Pobrano 8535;
returned null
Pobrano 65312;
Pobrano 65350;
Pobrano 65372;
Pobrano 66103;
Pobrano 15235;
returned null
Pobrano 5235;
returned null
Jarosław Pietras

Jarosław Pietras YarMobile.com -
aplikacje mobilne
Android, aplikacje
webo...

Temat: Problem z migotaniem ImageView

Przepraszam, nie przeczytałem całości z braku czasu, ale zasadniczo ImageView w zwykłym layoucie, ViewGroup, generalnie View, jest przeznaczony do wyświetlania raczej statycznych obrazków. Ewentualnie można je zmienić raz na jakiś czas (tj nie kilkadziesiąt razy na sekundę), w wątku UI. Jeśli z zewnątrz to np. przez runOnUiThread().

Jeśli potrzebujesz dynamicznych, b. często zmienianych obrazów to proponowałbym jedno z poniższych:
- zastosować nie ImageView, a animacje dostępne w View
- "malować" bezpośrednio do Canvas
- użyć SurfaceView jak w grach.

http://developer.android.com/guide/topics/graphics/ind...

Temat: Problem z migotaniem ImageView

Sprawdziłem w pętli z obiektem Date() i SurfaceView jest troszkę szybsze, ale za to częściej wpadają "mikro zawiechy".

przy czym kolejne ciekawoski -> Udało mi się dopatrzeć błędu, który powoduje połaczenie TCP -> dane są o dziwo pobierane w całości !, ale nie do końca i metoda read() KOŃCZY prace przed końcem strumienia !!!

Po prostu po każdej wysyłce Bitmapy wysyłałem jeden bit kontrolny, i oto co ujżałem w LogCacie... wnioski nasuwają się same.


Obrazek


Swoją drogą bardzo ciekawi mnie taki stan rzeczy... (Oczywiście kod pobierania jest taki sam jak w moim czwartym poście)

EDIT

Obrazek


Jedynym wyjściem, z tego co widzę, żeby dane zostały pobrane w całości po kolejnym przesłaniu to zamknąć strumień na serverze i następnie znowu otworzyć i jeszcze raz połaczyć się na kliencie.

Jeśli ktoś zna inny sposób to proszę o radę.

No i oczywiście problem ten wystepuje przy odczycie z Pamięci, i trochę trzeba się pomęczyć z buforowaniem... Tak więc wychodzi na moje, na to że to wcale nie nulluja się bitmapy przy przetwarzaniu tylko po prostu są uszkodzone:

http://tutorials.jenkov.com/java-io/bufferedreader.htmlMateusz Grzelak edytował(a) ten post dnia 26.08.11 o godzinie 00:27

Następna dyskusja:

Problem z uruchomieniem AVD




Wyślij zaproszenie do