Android Programjaim

Androidfejlesztes

RxAndroid - 3. resz - Retrolambda

2016. július 06. 11:56 - lacas82

Ebben a reszben a lambda-krol lesz szo, azon belul is a retrolambdarol.
Eloszor is miert jo nekunk az RxAndroid, es a lambdak?

Lecsokkenti a kod nagysagat, illetve elkerulheto vele a callback hell.

OK, be kell allitanunk nehany dolgot az android projectunkbe, hogy hasznalni tudjuk a retrolambdat, nezzuk mik ezek.

A root build.gradle-be a dependencybe ezt bemasolni:

classpath 'me.tatarka:gradle-retrolambda:3.1.0'

Ez a library atforditja a lamdba kodot valami olyasmive, amit az android studio is erteni fog.

az app gradle elso soraba pedig ezt:

apply plugin: 'me.tatarka.retrolambda'

majd ezt

android {
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

vegul a retrolambdat

retrolambda {
jdk System.getenv('JAVA8_HOME')
oldJdk System.getenv('JAVA7_HOME')
}

Elvileg ha minden flottul ment es run-oljuk a cuccot pl device-en,
akkor megy, ha nem, akkor kiirja valoszinu ezt:

 

Error:Execution failed for task ‘:app:compileDebugJava’.
> When running gradle with java 6 or 7, you must set the path to jdk8,
either with property retrolambda.jdk or environment variable JAVA8_HOME

Valszeg java7 van beallitva a settings-ben, ezert egyszeru a megoldasa:

File -> Project Structure -> SDK Location -> JDK Location

Itt a JDK7 utvonalat atrakjuk a JDK8 utvonalara. Ezutan mukodni fog.

Ha minden jol ment, akkor bizonyos kodreszleteink elszurkulnek, es kiir ra ilyesmiket:

Anonymous new Action1<String>() can be replaced with lambda...

Alt+Enterre pedig ki is csereli a kodot, azaz egyszerusiti.

Nezzuk milyen volt:

public void listTest() {

String[] manyWords = new String[]{"a", "b", "c"};

Observable<String> oneByOneObservable = Observable.from(manyWords);

Action1<String> action = new Action1<String>() {
@Override
public void call(String s) {
Toast.makeText(mAct, s, Toast.LENGTH_LONG).show();
}
};

Func1<String, String> map = new Func1<String, String>() {
@Override
public String call(String s) {
return s.toUpperCase() + s.toLowerCase() + s.toUpperCase();
}
};

oneByOneObservable
.observeOn(AndroidSchedulers.mainThread())
.map(map)
.subscribe(action);
}

Es milyen lett:

 

public void listTest() {

String[] manyWords = new String[]{"a", "b", "c"};

Observable<String> oneByOneObservable = Observable.from(manyWords);

Action1<String> action = s -> Toast.makeText(mAct, s, Toast.LENGTH_LONG).show();

Func1<String, String> map = s -> s.toUpperCase() + s.toLowerCase() + s.toUpperCase();

oneByOneObservable
.observeOn(AndroidSchedulers.mainThread())
.map(map)
.subscribe(action);
}

 Nezzunk egy masik peldat:

Func1<String, String> toUpperCaseMap = new Func1<String, String>() {
@Override
public String call(String s) {
return s.toUpperCase();
}
};

Ezt eloszor egyszerusiteni tudjuk lambdaval:

Func1<String, String> toUpperCaseMap = s -> s.toUpperCase();

majd:

Func1<String, String> toUpperCaseMap = String::toUpperCase;

RxAndroid - 2. resz

2016. július 04. 12:47 - lacas82

Action1<String> textViewOnNextAction = new Action1<String>() {
@Override
public void call(String s) {
txtPart1.setText(s);
}
};


Kezdjunk is bele! Az Action1 tulajdonkeppen egy hivas/tortenes,
ami nyilvan ismeros lehet ha irtunk mar interface-t generikusan. Ez itt 
egy hivas, ami visszaad egy Stringet esetunkben, de persze a String barmi mar lehet. 


Eddig ugye ezt hasznaltuk arra, hogy a textView-be visszakapjuk a "Hello World"-ot.
De mi van, ha nem a Hello World-ot akarjuk, hanem nagybetukkel a HELLO WORLD-ot?

Akkor letre kell hoznunk egy Func1 nevu metodust:

Func1<String, String> toUpperCaseMap = new Func1<String, String>(){
@Override
public String call(String s) {
return s.toUpperCase();
}
};

Ez ugye nagybetuve alakitja siman, ez egy map lesz. A ket String az input, outputot szimbolizalja.

Nezzuk egyszerubben az Observables-unket:

Observable<String> singleObservable = Observable.just(“Hello, World!”);


Lehetosegunk van a "just" statikus metodust meghivni, ami siman egy shortcut a "Hello World"-re.


Majd osszedrotozzuk:

singleObservable.observeOn(AndroidSchedulers.mainThread())
.map(toUpperCaseMap)
.subscribe(textViewOnNextAction);

 

Az uj dolog itt a map operator! Mi ez? Mielott atdobnank az eredmenyt a subscribernek, meg elvegezzuk rajta a

szukseges modositast, azaz nagybetusse alakitjuk. Majd ezt adjuk vissza. Nagyon sok operator erheto el, ezt egyelore ne is ragozzuk.


Eddig azt lattuk, hogyan lehet egy elemet atadni, de akarmennyit lehet, lassunk peldat List-ekre is mondjuk.

Action1<String> toastOnNextAction = new Action1<String>() {
@Override
public void call(String s) {
Toast.makeText(context, s, Toast.LENGTH_SHORT).show();
}
};

Eddig semmi uj dolog...
Observable<String> oneByOneObservable = Observable.from(manyWords);


vagy

Observable.just(manyWordList);

flatMap

Func1<List<String>, Observable<String>> getUrls = new Func1<List<String>, Observable<String>>() {
@Override
public Observable<String> call (List<String> strings) {
return Observable.from(strings);
}
};

Func2<String, String, String> mergeRoutine = new Func2<String, String, String>() {
@Override
public String call (String s, String s1) {
return String.format(“%s %s”,s, s1);
}
};

Observable.just(manyWordList)
.observeOn(AndroidSchedulers.mainThread())
.flatMap(getUrls)
.reduce(mergeRoutine)
.subscribe(toastOnNextAction);


Teljes forraskod
Címkék: RxAndroid

RxAndroid - 1. resz

2016. július 04. 12:10 - lacas82

Eloszor is a megszokott jutub videjo

 

Ezt a videot valasztottam, mert vicces benne a srac, neha hasonloan gondolkozom, hasonlo szohasznalattal, mint o. Kicsit talan tul sok a "shit" benne. :)

Hogy kezdjunk neki:

https://github.com/ReactiveX/RxAndroid

Android Studio gradle, dependencies:

compile 'io.reactivex:rxandroid:1.2.1'

"Observables and Subscribers. The first ones will emit any number of items to all the Subscribers that are listening to the changes."

Elso korben nezzuk az RxAndroid ket fo pontjat, az Observablest, es a Subscriberst. Magyarul talan megfigyelo, feliratkozo.

Observable.OnSubscribe observableAction = new Observable.OnSubscribe<String>() {
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext(“Hello, World!”);
subscriber.onCompleted();
}
};
Observable<String> observable = Observable.create(observableAction);


Eloszor tehat letrehozunk egy observablet, a fenti modon.
A Hello World 'String'et fogjuk visszakapni ebbol ugye. Azert van mindenhol String.
Az observable barmilyen bemenetu cuccot kisugaroz majd a subscriberre, ami figyeli
a valtozast. Huh nem tudom mennyire ertheto, magyarul megfogalmazni ezt eleg nehez,
de primitiv dologrol van szo.

Ilyenkor meg semmi se tortenik, kell egy Subscriber ugye, amivel feliratkozunk ra.

Subscriber<String> textViewSubscriber = new Subscriber<String>() {
public void onCompleted() {}
public void onError(Throwable e) {}
public void onNext(String s) {
txtPart1.setText(s);
}
};
Subscriber<String> toastSubscriber = new Subscriber<String>() {
public void onCompleted() {}
public void onError(Throwable e) {}
public void onNext(String s) {
Toast.makeText(context, s, Toast.LENGTH_SHORT).show();
}
};


Itt van 2 db Subscriberunk, az elso siman kiloki onNext-re
a Hello World-ot egy TextView-be, mig a masodik egy Toast-ban megjeleniti azt. 

Ok megvannak a Subscriberek, es az Observable, mar csak ossze kene kotozni a kettot.


Viszont azt akarjuk, hogy a Main Thread-en kapjuk vissza a cuccokat, mivel az UI threaden akarunk dolgokat csinalni, a TextView ott van.


observable.observeOn(AndroidSchedulers.mainThread());
observable.subscribe(textViewSubscriber);
observable.subscribe(toastSubscriber);


Azaz, observeOn, hol tortenjen meg, subscribe pedig, hogy mire/mikre iratkozzon fel.

Termeszetesen AsyncTask-eket is kivalthatunk majd ezzel, Thread-eken keresztul, majd a kesobbiekben latunk ezekre peldat.

Bovebb leiras

Dependency injections

2016. július 04. 10:59 - lacas82

Ok, DI, mi is az? Eloszor is egy wiki link:

https://en.wikipedia.org/wiki/Dependency_injection

Mi is ez?

A DI egy koncept, ami sok nyelvben megtalalhato, a DI egy olyan koncept, ami mogott az IOC all, Inversion Of Control. Gyakorlatilag egy osztalynak nem kellene statikusan konfiguralnia a fuggosegeit, hanem kivulrol letrehozni azokat.

Ha pl van egy java classunk, amiben van egy masik fuggoseg, mondjuk egy masik osztaly, azt class dependency-nek hivjuk. Idealisan az lenne a jo, ha az osztalyaink fuggetlenek lennenek egymastol, igy tesztelhetoek is. Alant van par pelda is errol.

Androidban vannak DI kontenerek/framework, amiket alkalmaznunk kellene. Errol egy masik postban lesz szo.

Fontosabb dolgok:

Without dependency injection

// An example without dependency injection
public class Client {
    // Internal reference to the service used by this client
    private Service service;

    // Constructor
    Client() {
        // Specify a specific implementation in the constructor instead of using dependency injection
        service = new ServiceExample();
    }

    // Method within this client that uses the services
    public String greet() {
        return "Hello " + service.getName();
    }
}


Ezzel ugye az a baj, hogy a fuggoseg, a Client-en belul letrejon, a new
ServiceExample()-n keresztul. 


Tobb fajta dependency injection van, a lenyege, hogy a fuggo object-et ne
peldanyositsuk itt, hanem ez kivulrol tortenhet meg.

Milyen modjai vannak? pl egy setter, ilyenkor viszont ha van egy masik metodusunk, ami hasznalja a peldanyositott cuccot konnyen elofordulhat, hogy ugye null-al ter vissza, ha nem a megfelelo sorrendben hivjuk meg a metodusait.

Ezt ki tudjuk vedeni a konstruktorban torteno inicializalassal. Illetve van interface-en keresztuli DI is.

Constructor injection

// Constructor
Client(Service service) {
    // Save the reference to the passed-in service inside this client
    this.service = service;
}

Setter injection

// Setter method
public void setService(Service service) {
    // Save the reference to the passed-in service inside this client
    this.service = service;
}

Interface injection
// Service setter interface.
public interface ServiceSetter {
    public void setService(Service service);
}

// Client class
public class Client implements ServiceSetter {
    // Internal reference to the service used by this client.
    private Service service;

    // Set the service that this client is to use.
    @Override
    public void setService(Service service) {
        this.service = service;
    }
}

Tehat valoszinuleg mindenki hasznalt mar ilyet, maximum nem tudta, 
hogy hogyan hivjak.:)

Bovebben meg lehet rola olvasni, de en most android kozelebol fogom megmutatni (a kovetkezo postban), eloszor egy videoval, ami a DI-t magyarazza el siman:

 

 

Címkék: di

Project M

2016. június 28. 11:42 - lacas82

- Appcompat
- Recyclerview-ek hasznalata
- Fragments, VP

- Glide a kepek cache-elésére
- Retrofit2 es/vagy Volley JSON parse-olasara
- Okhttp
- ButterKnife es/vagy Java annotations
- Apache commons
- balysv MaterialMenu (github library)
- PagerSlidingTabStrip (github library kicsit atirva majd)

- RxAndroid
- FireBase
- Realm hasznalata

- Profi sw tervezes, refactoring
- Tervezesi mintak aktivabb hasznalata

- Redmine, Trello?

- Kommentek, dokumentacio
- Teszteles

Címkék: project m