Skip to content

Commit 31def9f

Browse files
author
Kaushik Gopal
committed
feat: add examples from Retrofit similar to JakeWharton's examples
1 parent a789b5f commit 31def9f

File tree

11 files changed

+291
-39
lines changed

11 files changed

+291
-39
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ Two implementations:
4040

4141
### Retrofit and RxJava (zip, flatmap) (wip)
4242

43-
Working examples of github from JakeWharton's Retrofit preso at Netflix
44-
https://www.youtube.com/watch?v=aEuNBk1b5OE#t=2480
45-
https://speakerdeck.com/jakewharton/2014-1
43+
[Retrofit from Square](http://square.github.io/retrofit/) is an another amazing library that helps with easy networking (even if you haven't made the jump to RxJava just yet, you really should check it out). It works even better with RxJava and these are examples taken straight up from the android demigod developer Jake Wharton's talk at Netflix. You can [watch the talk](https://www.youtube.com/watch?v=aEuNBk1b5OE#t=2480) at this link. Incidentally, my motiviation to use RxJava was from attending this talk at Netflix.
44+
45+
Since it was a presentation, Jake only put up the most important code snippets in [his slides](https://speakerdeck.com/jakewharton/2014-1). Also he uses Java 8 in them, so I flushed those examples out in ~~good~~ old Java 6.
46+
4647

4748
### First retrieve from cached data, then make a network call if you can't find your data (concat) (wip)
4849

app/app.iml

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
1414
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
1515
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
16+
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
1617
<option name="ALLOW_USER_CONFIGURATION" value="false" />
1718
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
1819
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
@@ -37,41 +38,60 @@
3738
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
3839
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
3940
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
41+
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
4042
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
41-
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
4243
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
4344
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
4445
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
4546
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
4647
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
48+
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
4749
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
48-
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
4950
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
5051
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
5152
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
5253
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
5354
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
55+
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
5456
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
55-
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" isTestSource="true" />
5657
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
5758
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
5859
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
59-
<excludeFolder url="file://$MODULE_DIR$/build/intermediates" />
60+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
61+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
62+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
63+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
64+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
65+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
66+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
67+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
68+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
69+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
70+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
71+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
72+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
73+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
74+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
75+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
76+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
77+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
78+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
6079
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
6180
</content>
6281
<orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
6382
<orderEntry type="sourceFolder" forTests="false" />
64-
<orderEntry type="library" exported="" name="support-v13-20.0.0" level="project" />
6583
<orderEntry type="library" exported="" name="timber-2.2.2" level="project" />
84+
<orderEntry type="library" exported="" name="okhttp-urlconnection-2.0.0" level="project" />
85+
<orderEntry type="library" exported="" name="support-v13-20.0.0" level="project" />
6686
<orderEntry type="library" exported="" name="rxjava-core-0.17.6" level="project" />
6787
<orderEntry type="library" exported="" name="gson-2.2.4" level="project" />
68-
<orderEntry type="library" exported="" name="okhttp-1.6.0" level="project" />
88+
<orderEntry type="library" exported="" name="okio-1.0.0" level="project" />
89+
<orderEntry type="library" exported="" name="support-v4-20.0.0" level="project" />
90+
<orderEntry type="library" exported="" name="retrofit-1.6.1" level="project" />
6991
<orderEntry type="library" exported="" name="guava-17.0" level="project" />
7092
<orderEntry type="library" exported="" name="butterknife-5.1.1" level="project" />
71-
<orderEntry type="library" exported="" name="okhttp-urlconnection-1.6.0" level="project" />
7293
<orderEntry type="library" exported="" name="support-annotations-20.0.0" level="project" />
73-
<orderEntry type="library" exported="" name="support-v4-20.0.0" level="project" />
74-
<orderEntry type="library" exported="" name="retrofit-1.5.1" level="project" />
94+
<orderEntry type="library" exported="" name="okhttp-2.0.0" level="project" />
7595
<orderEntry type="library" exported="" name="rxjava-android-0.17.6" level="project" />
7696
</component>
7797
</module>

app/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ dependencies {
99
compile 'com.jakewharton.timber:timber:2.2.2'
1010
compile 'com.netflix.rxjava:rxjava-android:0.17.+'
1111

12-
compile 'com.squareup.retrofit:retrofit:1.6.+'
13-
compile 'com.squareup.okhttp:okhttp:2.0.+'
14-
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.+'
12+
compile 'com.squareup.retrofit:retrofit:1.6.1'
13+
compile 'com.squareup.okhttp:okhttp:2.0.0'
14+
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.0'
1515

1616
}
1717

app/src/main/java/com/morihacky/android/rxjava/MainFragment.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,16 @@ public void demoThrottling() {
4949
.commit();
5050
}
5151

52-
@OnClick(R.id.btn_demo_subject_timeout)
52+
@OnClick(R.id.btn_demo_retrofit)
53+
public void demoRetrofitCalls() {
54+
getActivity().getSupportFragmentManager()
55+
.beginTransaction()
56+
.addToBackStack(this.toString())
57+
.replace(R.id.activity_main, new RetrofitFragment(), this.toString())
58+
.commit();
59+
}
60+
61+
//@OnClick(R.id.btn_demo_subject_timeout)
5362
public void demoTimeout() {
5463
getActivity().getSupportFragmentManager()
5564
.beginTransaction()

app/src/main/java/com/morihacky/android/rxjava/RetrofitFragment.java

Lines changed: 130 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,141 @@
11
package com.morihacky.android.rxjava;
22

3+
import android.os.Bundle;
4+
import android.support.annotation.Nullable;
35
import android.support.v4.app.Fragment;
6+
import android.view.LayoutInflater;
7+
import android.view.View;
8+
import android.view.ViewGroup;
9+
import android.widget.EditText;
10+
import butterknife.ButterKnife;
11+
import butterknife.InjectView;
12+
import butterknife.OnClick;
13+
import com.google.common.base.Strings;
14+
import com.morihacky.android.rxjava.app.R;
15+
import com.morihacky.android.rxjava.retrofit.Contributor;
16+
import com.morihacky.android.rxjava.retrofit.GithubApi;
17+
import com.morihacky.android.rxjava.retrofit.User;
18+
import java.util.List;
19+
import retrofit.RestAdapter;
20+
import rx.Observable;
21+
import rx.Observer;
22+
import rx.android.schedulers.AndroidSchedulers;
23+
import rx.functions.Func1;
24+
import rx.functions.Func2;
25+
import rx.schedulers.Schedulers;
26+
import timber.log.Timber;
427

528
public class RetrofitFragment
629
extends Fragment {
730

8-
}
9-
10-
11-
31+
GithubApi api;
32+
33+
@InjectView(R.id.demo_retrofit_contributors_username) EditText _username;
34+
@InjectView(R.id.demo_retrofit_contributors_repository) EditText _repo;
35+
36+
@Override
37+
public void onCreate(Bundle savedInstanceState) {
38+
super.onCreate(savedInstanceState);
39+
40+
RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint("https://api.github.com/")
41+
.build();
42+
43+
api = restAdapter.create(GithubApi.class);
44+
}
45+
46+
@Override
47+
public View onCreateView(LayoutInflater inflater,
48+
@Nullable ViewGroup container,
49+
@Nullable Bundle savedInstanceState) {
50+
View layout = inflater.inflate(R.layout.fragment_retrofit, container, false);
51+
ButterKnife.inject(this, layout);
52+
return layout;
53+
}
54+
55+
@OnClick(R.id.btn_demo_retrofit_contributors)
56+
public void onListContributorsClicked() {
57+
api.contributors(_username.getText().toString(), _repo.getText().toString())
58+
.subscribe(new Observer<List<Contributor>>() {
59+
@Override
60+
public void onCompleted() {
61+
Timber.d("Retrofit call 1 completed");
62+
}
63+
64+
@Override
65+
public void onError(Throwable e) {
66+
Timber.e(e, "woops we got an error while getting the list of contributors");
67+
}
68+
69+
@Override
70+
public void onNext(List<Contributor> contributors) {
71+
for (Contributor c : contributors) {
72+
Timber.d("%s has made %d contributions to %s",
73+
c.login,
74+
c.contributions,
75+
_repo.getText().toString());
76+
}
77+
}
78+
});
79+
}
80+
81+
@OnClick(R.id.btn_demo_retrofit_contributors_with_user_info)
82+
public void onListContributorsWithFullUserInfoClicked() {
83+
api.contributors(_username.getText().toString(), _repo.getText().toString())
84+
.flatMap(new Func1<List<Contributor>, Observable<Contributor>>() {
85+
@Override
86+
public Observable<Contributor> call(List<Contributor> contributors) {
87+
return Observable.from(contributors);
88+
}
89+
})
90+
.flatMap(new Func1<Contributor, Observable<?>>() {
91+
@Override
92+
public Observable<?> call(Contributor contributor) {
93+
Observable.zip(Observable.just(contributor),
94+
api.user(contributor.login).filter(new Func1<User, Boolean>() {
95+
@Override
96+
public Boolean call(User user) {
97+
return !Strings.isNullOrEmpty(user.name) && !Strings.isNullOrEmpty(user.email);
98+
}
99+
}),
100+
new Func2<Contributor, User, Object>() {
101+
@Override
102+
public Object call(Contributor contributor, User user) {
103+
Timber.d("%s(%s) has made %d contributions to %s",
104+
user.name,
105+
user.email,
106+
contributor.contributions,
107+
_repo.getText().toString());
108+
109+
return Observable.empty();
110+
}
111+
}).subscribe();
112+
return Observable.empty();
113+
}
114+
})
115+
.subscribeOn(Schedulers.newThread())
116+
.observeOn(AndroidSchedulers.mainThread())
117+
.subscribe(new Observer<Object>() {
118+
@Override
119+
public void onCompleted() {
120+
Timber.d("Retrofit call 2 completed ");
121+
}
122+
123+
@Override
124+
public void onError(Throwable e) {
125+
Timber.e(e,
126+
"woops we got an error while getting the list of contributors along with full names");
127+
}
128+
129+
@Override
130+
public void onNext(Object o) {
131+
Timber.d("hi! onNext");
132+
}
133+
});
134+
}
12135

13136
/*
14-
interface Github {
15-
@GET("/repos/{owner}/{repo}/contributors")
16-
Observable<List<Contributor>> contributors (
17-
@Path("owner") String owner,
18-
@sPath("repo") String repo,
19-
);
20-
21-
@GET("/users/{user}")
22-
Observable<User> user(
23-
@Path("user") String user);
24-
}
25137
26-
27-
// Get Observable of List<Contributor>
138+
// Get Observable of List<Contributor>
28139
// Then from each contributor object in that List
29140
// print out the contributions and name
30141
@@ -43,7 +154,6 @@ Observable<User> user(
43154
// combine into a single observable of User --- 2/2 flatmap
44155
// print out the name of user
45156
46-
47157
github.contributors("netflix", "rxjava")
48158
.lift(flattenList())
49159
.flatMap(c -> gitHub.user(c.login))
@@ -74,5 +184,6 @@ Observable<User> user(
74184
.flatMap(c -> gitHub.user(c.login))
75185
.filter(user -> user.name != null)
76186
.forEach(user -> println(user.name));
77-
}
187+
78188
*/
189+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.morihacky.android.rxjava.retrofit;
2+
3+
public class Contributor {
4+
public String login;
5+
public long contributions;
6+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.morihacky.android.rxjava.retrofit;
2+
3+
import java.util.List;
4+
import retrofit.http.GET;
5+
import retrofit.http.Path;
6+
import rx.Observable;
7+
8+
public interface GithubApi {
9+
10+
/**
11+
* See https://developer.github.com/v3/repos/#list-contributors
12+
*/
13+
@GET("/repos/{owner}/{repo}/contributors")
14+
Observable<List<Contributor>> contributors(@Path("owner") String owner,
15+
@Path("repo") String repo);
16+
17+
/**
18+
* See https://developer.github.com/v3/users/
19+
*/
20+
@GET("/users/{user}")
21+
Observable<User> user(@Path("user") String user);
22+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.morihacky.android.rxjava.retrofit;
2+
3+
public class User {
4+
public String name;
5+
public String email;
6+
}

app/src/main/res/layout/fragment_main.xml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@
3434
android:text="@string/btn_demo_subject_debounce"/>
3535

3636
<Button
37-
android:id="@+id/btn_demo_subject_timeout"
37+
android:id="@+id/btn_demo_retrofit"
3838
android:layout_height="wrap_content"
3939
android:layout_width="match_parent"
40-
android:text="@string/btn_demo_timeout"/>
40+
android:text="@string/btn_demo_retrofit"/>
4141
</LinearLayout>
42-
4342
</ScrollView>

0 commit comments

Comments
 (0)