├── README.md ├── RRDM.iml ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── javalong │ │ └── rrdm │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── javalong │ │ │ └── rrdm │ │ │ ├── activity │ │ │ ├── LoginActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── component │ │ │ │ ├── LoginActivityComponent.java │ │ │ │ └── MainActivityComponent.java │ │ │ ├── iview │ │ │ │ ├── ILoginView.java │ │ │ │ └── IMainView.java │ │ │ ├── module │ │ │ │ ├── LoginActivityModule.java │ │ │ │ └── MainActivityModule.java │ │ │ └── presenter │ │ │ │ ├── LoginPresenter.java │ │ │ │ └── MainPresenter.java │ │ │ ├── app │ │ │ ├── AppBaseActivity.java │ │ │ ├── AppBaseApplication.java │ │ │ ├── annotation │ │ │ │ └── ActivityScope.java │ │ │ ├── component │ │ │ │ └── AppComponent.java │ │ │ ├── iview │ │ │ │ └── MvpView.java │ │ │ ├── module │ │ │ │ └── AppModule.java │ │ │ └── presenter │ │ │ │ └── AppPresenter.java │ │ │ └── retrofit │ │ │ ├── ResponseMessageBean.java │ │ │ ├── RetrofitHelper.java │ │ │ ├── ServerApi.java │ │ │ ├── TWGsonConverterFactory.java │ │ │ ├── TWGsonRequestBodyConverter.java │ │ │ ├── TWGsonResponseBodyConverter.java │ │ │ └── TWJavaCallAdapterFactory.java │ └── res │ │ ├── layout │ │ ├── activity_login.xml │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── javalong │ └── rrdm │ └── ExampleUnitTest.java ├── build.gradle ├── build ├── generated │ └── mockable-android-24.jar └── intermediates │ └── dex-cache │ └── cache.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── local.properties └── settings.gradle /README.md: -------------------------------------------------------------------------------- 1 | # Retrofit2-RxJava-Dagger2-MVP 2 | -------------------------------------------------------------------------------- /RRDM.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.neenbedankt.android-apt' 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "25.0.1" 6 | defaultConfig { 7 | applicationId "com.javalong.rrdm" 8 | minSdkVersion 14 9 | targetSdkVersion 21 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile fileTree(dir: 'libs', include: ['*.jar']) 23 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 24 | exclude group: 'com.android.support', module: 'support-annotations' 25 | }) 26 | compile 'com.android.support:appcompat-v7:24.2.1' 27 | testCompile 'junit:junit:4.12' 28 | compile 'com.google.dagger:dagger:2.0' 29 | apt 'com.google.dagger:dagger-compiler:2.0' 30 | provided 'org.glassfish:javax.annotation:10.0-b28' 31 | 32 | compile 'io.reactivex:rxandroid:1.2.0' 33 | compile 'io.reactivex:rxjava:1.1.5' 34 | compile 'com.squareup.retrofit2:retrofit:2.0.2' 35 | compile 'com.jakewharton.rxbinding:rxbinding:0.4.0' 36 | compile 'com.squareup.retrofit2:converter-gson:2.0.2' 37 | compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2' 38 | } 39 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/javalong/Android/Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/javalong/rrdm/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.javalong.rrdm", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/activity/LoginActivity.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.activity; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.view.View; 8 | 9 | import com.javalong.rrdm.R; 10 | import com.javalong.rrdm.activity.component.DaggerLoginActivityComponent; 11 | import com.javalong.rrdm.activity.component.LoginActivityComponent; 12 | import com.javalong.rrdm.activity.iview.ILoginView; 13 | import com.javalong.rrdm.activity.module.LoginActivityModule; 14 | import com.javalong.rrdm.activity.presenter.LoginPresenter; 15 | import com.javalong.rrdm.app.AppBaseActivity; 16 | 17 | /** 18 | * Created by javalong on 16-12-27. 19 | */ 20 | 21 | public class LoginActivity extends AppBaseActivity implements ILoginView{ 22 | 23 | public static void start(Context context) { 24 | Intent starter = new Intent(context, LoginActivity.class); 25 | context.startActivity(starter); 26 | } 27 | @Override 28 | protected void onCreate(@Nullable Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_login); 31 | findViewById(R.id.bt_request).setOnClickListener(new View.OnClickListener() { 32 | @Override 33 | public void onClick(View v) { 34 | mPresenter.login(); 35 | } 36 | }); 37 | } 38 | 39 | @Override 40 | protected void initInjects() { 41 | LoginActivityComponent component = DaggerLoginActivityComponent.builder() 42 | .appComponent(getAppComponent()) 43 | .loginActivityModule(new LoginActivityModule(this)) 44 | .build(); 45 | component.inject(this); 46 | component.inject(mPresenter); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.activity; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.view.View; 6 | import android.widget.TextView; 7 | 8 | import com.javalong.rrdm.R; 9 | import com.javalong.rrdm.activity.component.DaggerMainActivityComponent; 10 | import com.javalong.rrdm.activity.iview.IMainView; 11 | import com.javalong.rrdm.activity.module.MainActivityModule; 12 | import com.javalong.rrdm.activity.presenter.MainPresenter; 13 | import com.javalong.rrdm.app.AppBaseActivity; 14 | import com.javalong.rrdm.retrofit.ServerApi; 15 | 16 | import java.util.Timer; 17 | 18 | import javax.inject.Inject; 19 | 20 | public class MainActivity extends AppBaseActivity implements IMainView{ 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_main); 26 | mPresenter.test(); 27 | } 28 | 29 | @Override 30 | protected void initInjects() { 31 | DaggerMainActivityComponent.builder() 32 | .appComponent(getAppComponent()) 33 | .mainActivityModule(new MainActivityModule(this)) 34 | .build() 35 | .inject(this); 36 | } 37 | 38 | 39 | @Override 40 | public void showMainMessage() { 41 | ((TextView)findViewById(R.id.tv_test)) 42 | .setText("你好 dagger"); 43 | findViewById(R.id.bt_login) 44 | .setOnClickListener(new View.OnClickListener() { 45 | @Override 46 | public void onClick(View v) { 47 | LoginActivity.start(MainActivity.this); 48 | MainActivity.this.finish(); 49 | } 50 | }); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/activity/component/LoginActivityComponent.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.activity.component; 2 | 3 | import android.util.Log; 4 | 5 | import com.javalong.rrdm.activity.LoginActivity; 6 | import com.javalong.rrdm.activity.module.LoginActivityModule; 7 | import com.javalong.rrdm.activity.presenter.LoginPresenter; 8 | import com.javalong.rrdm.app.annotation.ActivityScope; 9 | import com.javalong.rrdm.app.component.AppComponent; 10 | import com.javalong.rrdm.app.module.AppModule; 11 | import com.javalong.rrdm.retrofit.ServerApi; 12 | 13 | import dagger.Component; 14 | 15 | /** 16 | * Created by javalong on 16-12-27. 17 | */ 18 | @ActivityScope 19 | @Component(dependencies = AppComponent.class,modules = {LoginActivityModule.class}) 20 | public interface LoginActivityComponent { 21 | void inject(LoginActivity loginView); 22 | void inject(LoginPresenter loginPresenter); 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/activity/component/MainActivityComponent.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.activity.component; 2 | 3 | import com.javalong.rrdm.activity.MainActivity; 4 | import com.javalong.rrdm.activity.iview.IMainView; 5 | import com.javalong.rrdm.activity.module.MainActivityModule; 6 | import com.javalong.rrdm.app.annotation.ActivityScope; 7 | import com.javalong.rrdm.app.component.AppComponent; 8 | 9 | import dagger.Component; 10 | 11 | /** 12 | * Created by javalong on 16-12-27. 13 | */ 14 | @ActivityScope 15 | @Component(dependencies = AppComponent.class,modules = MainActivityModule.class) 16 | public interface MainActivityComponent{ 17 | /** 18 | * @param mainView 19 | * 这里必须使用MainActivity,不能使用IMain接口 20 | * 否则会造成@Inject注入失败 21 | */ 22 | void inject(MainActivity mainView); 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/activity/iview/ILoginView.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.activity.iview; 2 | 3 | import com.javalong.rrdm.app.iview.MvpView; 4 | 5 | /** 6 | * Created by javalong on 16-12-27. 7 | */ 8 | 9 | public interface ILoginView extends MvpView { 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/activity/iview/IMainView.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.activity.iview; 2 | 3 | /** 4 | * Created by javalong on 16-12-27. 5 | */ 6 | 7 | import com.javalong.rrdm.app.iview.MvpView; 8 | 9 | /** 10 | * MVP ----> V 11 | */ 12 | public interface IMainView extends MvpView{ 13 | void showMainMessage(); 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/activity/module/LoginActivityModule.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.activity.module; 2 | 3 | import com.javalong.rrdm.activity.iview.ILoginView; 4 | import com.javalong.rrdm.activity.iview.IMainView; 5 | import com.javalong.rrdm.activity.presenter.LoginPresenter; 6 | import com.javalong.rrdm.app.annotation.ActivityScope; 7 | 8 | import dagger.Module; 9 | import dagger.Provides; 10 | 11 | /** 12 | * Created by javalong on 16-12-27. 13 | */ 14 | @Module 15 | public class LoginActivityModule { 16 | private ILoginView loginView; 17 | 18 | public LoginActivityModule(ILoginView loginView) { 19 | this.loginView = loginView; 20 | } 21 | 22 | @Provides 23 | @ActivityScope 24 | ILoginView provideILoginView(){ 25 | return loginView; 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/activity/module/MainActivityModule.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.activity.module; 2 | 3 | import com.javalong.rrdm.activity.iview.IMainView; 4 | import com.javalong.rrdm.activity.presenter.MainPresenter; 5 | import com.javalong.rrdm.app.annotation.ActivityScope; 6 | 7 | import javax.inject.Singleton; 8 | 9 | import dagger.Module; 10 | import dagger.Provides; 11 | 12 | /** 13 | * Created by javalong on 16-12-27. 14 | */ 15 | @Module 16 | public class MainActivityModule { 17 | 18 | private IMainView mainView; 19 | 20 | public MainActivityModule(IMainView mainView) { 21 | this.mainView = mainView; 22 | } 23 | 24 | @Provides @ActivityScope IMainView provideIMainView(){ 25 | return mainView; 26 | } 27 | 28 | /** 29 | * 这种方式,和直接在MainPresenter构造方法上添加@Inject是一样的 30 | * 二选一即可. 31 | */ 32 | // @Provides @ActivityScope MainPresenter provideMainPresenter(IMainView mainView){ 33 | // return new MainPresenter(mainView); 34 | // } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/activity/presenter/LoginPresenter.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.activity.presenter; 2 | 3 | import com.javalong.rrdm.activity.iview.ILoginView; 4 | import com.javalong.rrdm.app.presenter.AppPresenter; 5 | import com.javalong.rrdm.retrofit.ServerApi; 6 | 7 | import javax.inject.Inject; 8 | 9 | import rx.Observer; 10 | import rx.android.schedulers.AndroidSchedulers; 11 | import rx.schedulers.Schedulers; 12 | 13 | /** 14 | * Created by javalong on 16-12-27. 15 | */ 16 | 17 | public class LoginPresenter extends AppPresenter { 18 | 19 | @Inject 20 | ServerApi serverApi; 21 | 22 | @Inject 23 | public LoginPresenter(ILoginView mvpView) { 24 | super(mvpView); 25 | } 26 | 27 | @Override 28 | public void attach() { 29 | } 30 | 31 | @Override 32 | public void detach() { 33 | } 34 | 35 | public void login(){ 36 | serverApi.requestUrl("login") 37 | .subscribeOn(Schedulers.io()) 38 | .observeOn(AndroidSchedulers.mainThread()) 39 | .subscribe(new Observer() { 40 | @Override 41 | public void onCompleted() { 42 | } 43 | 44 | @Override 45 | public void onError(Throwable e) { 46 | } 47 | 48 | @Override 49 | public void onNext(String s) { 50 | } 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/activity/presenter/MainPresenter.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.activity.presenter; 2 | 3 | import android.util.Log; 4 | 5 | import com.javalong.rrdm.activity.iview.IMainView; 6 | import com.javalong.rrdm.app.annotation.ActivityScope; 7 | import com.javalong.rrdm.app.iview.MvpView; 8 | import com.javalong.rrdm.app.presenter.AppPresenter; 9 | 10 | import javax.inject.Inject; 11 | 12 | /** 13 | * Created by javalong on 16-12-27. 14 | */ 15 | 16 | public class MainPresenter extends AppPresenter{ 17 | 18 | @Inject 19 | public MainPresenter(IMainView mvpView) { 20 | super(mvpView); 21 | } 22 | 23 | @Override 24 | public void attach() { 25 | 26 | } 27 | 28 | @Override 29 | public void detach() { 30 | 31 | } 32 | 33 | public void test() { 34 | mvpView.showMainMessage(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/app/AppBaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.app; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | 7 | import com.javalong.rrdm.app.component.AppComponent; 8 | import com.javalong.rrdm.app.presenter.AppPresenter; 9 | import com.javalong.rrdm.retrofit.ServerApi; 10 | 11 | import javax.inject.Inject; 12 | 13 | /** 14 | * Created by javalong on 16-12-27. 15 | */ 16 | 17 | public abstract class AppBaseActivity extends AppCompatActivity { 18 | @Inject 19 | protected T mPresenter; 20 | 21 | @Override 22 | protected void onCreate(@Nullable Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | initInjects(); 25 | mPresenter.attach(); 26 | } 27 | 28 | protected abstract void initInjects(); 29 | 30 | @Override 31 | protected void onDestroy() { 32 | super.onDestroy(); 33 | mPresenter.detach(); 34 | } 35 | 36 | protected AppComponent getAppComponent(){ 37 | return AppBaseApplication.getInstance().getAppComponent(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/app/AppBaseApplication.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.app; 2 | 3 | import android.app.Application; 4 | 5 | import com.javalong.rrdm.app.component.AppComponent; 6 | import com.javalong.rrdm.app.component.DaggerAppComponent; 7 | import com.javalong.rrdm.app.module.AppModule; 8 | 9 | /** 10 | * Created by javalong on 16-12-27. 11 | */ 12 | 13 | public class AppBaseApplication extends Application { 14 | 15 | private static AppBaseApplication instance; 16 | 17 | public static AppBaseApplication getInstance() { 18 | return instance; 19 | } 20 | 21 | AppComponent appComponent; 22 | 23 | public AppComponent getAppComponent() { 24 | return appComponent; 25 | } 26 | 27 | @Override 28 | public void onCreate() { 29 | super.onCreate(); 30 | instance = this; 31 | if (appComponent == null) { 32 | appComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).build(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/app/annotation/ActivityScope.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.app.annotation; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | import javax.inject.Scope; 7 | 8 | /** 9 | * Created by javalong on 16-12-27. 10 | */ 11 | 12 | @Scope 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface ActivityScope{ 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/app/component/AppComponent.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.app.component; 2 | 3 | import android.content.Context; 4 | 5 | import com.javalong.rrdm.app.module.AppModule; 6 | import com.javalong.rrdm.retrofit.ServerApi; 7 | 8 | import javax.inject.Singleton; 9 | 10 | import dagger.Component; 11 | 12 | /** 13 | * Created by javalong on 16-12-27. 14 | */ 15 | @Singleton 16 | @Component(modules = AppModule.class) 17 | public interface AppComponent { 18 | Context getContext(); 19 | /**这里必须加上这个,因为在LoginPresenter里面我@Inject ServerApi, 20 | 这里不加的话,会造成这个ServerApi找不到 21 | */ 22 | ServerApi getServerApi(); 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/app/iview/MvpView.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.app.iview; 2 | 3 | /** 4 | * Created by javalong on 16-12-27. 5 | * 可以放一些共用方法 6 | * showProgress 7 | * hideProgress 8 | */ 9 | 10 | public interface MvpView { 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/app/module/AppModule.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.app.module; 2 | 3 | import android.content.Context; 4 | 5 | import com.javalong.rrdm.retrofit.RetrofitHelper; 6 | import com.javalong.rrdm.retrofit.ServerApi; 7 | 8 | import java.util.Timer; 9 | 10 | import javax.inject.Singleton; 11 | 12 | import dagger.Module; 13 | import dagger.Provides; 14 | 15 | /** 16 | * Created by javalong on 16-12-27. 17 | */ 18 | @Module 19 | public class AppModule { 20 | 21 | private Context mContext; 22 | 23 | public AppModule(Context context) { 24 | this.mContext = context; 25 | } 26 | 27 | @Provides @Singleton 28 | Context provideContext(){ 29 | return mContext; 30 | } 31 | 32 | @Provides @Singleton 33 | ServerApi provideServerApi(Context context){ 34 | RetrofitHelper.init(context); 35 | return RetrofitHelper.getApi(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/app/presenter/AppPresenter.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.app.presenter; 2 | 3 | import com.javalong.rrdm.app.iview.MvpView; 4 | 5 | import javax.inject.Inject; 6 | 7 | /** 8 | * Created by javalong on 16-12-27. 9 | * presenter基类 10 | */ 11 | public abstract class AppPresenter{ 12 | @Inject 13 | protected V mvpView; 14 | 15 | public AppPresenter(V mvpView) { 16 | this.mvpView = mvpView; 17 | } 18 | 19 | public abstract void attach(); 20 | public abstract void detach(); 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/retrofit/ResponseMessageBean.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.retrofit; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONException; 5 | import org.json.JSONObject; 6 | 7 | import java.io.Serializable; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * @author ygh 13 | * 2015/4/27 14 | *

15 | * 请求数据内容 16 | */ 17 | public class ResponseMessageBean implements Serializable { 18 | public Object moreInfo = null; 19 | public Object data = null; 20 | public String error = null; 21 | public Integer errorCode = 200;//默认为200 是成功 22 | 23 | 24 | public static final String ERROR_CODE="errorCode"; 25 | public static final String MORE_INFO="moreInfo"; 26 | public static final String DATA="data"; 27 | public static final String ERROR="error"; 28 | 29 | /** 30 | * @return 31 | * @author ygh 32 | *

33 | * 2015/4/27 34 | *

35 | * 解析参数,主要的解析步骤还是需要在具体的requestSuccess方法里做解析。 36 | */ 37 | public static ResponseMessageBean analyseReponse(String response) { 38 | JSONObject jsonObject = null; 39 | try { 40 | jsonObject = new JSONObject(response); 41 | } catch (JSONException e) { 42 | e.printStackTrace(); 43 | } 44 | if(jsonObject==null)return null; 45 | ResponseMessageBean responseMessage = new ResponseMessageBean(); 46 | try { 47 | if (jsonObject.has(ERROR)) { 48 | responseMessage.error = jsonObject.getString(ERROR); 49 | } 50 | if (jsonObject.has(ERROR_CODE)) { 51 | responseMessage.errorCode = jsonObject.getInt(ERROR_CODE); 52 | } 53 | if (jsonObject.has(DATA)) { 54 | responseMessage.data = jsonObject.get(DATA); 55 | } 56 | if (jsonObject.has(MORE_INFO)) { 57 | responseMessage.moreInfo = jsonObject.get(MORE_INFO); 58 | } 59 | jsonObject = null; 60 | } catch (JSONException e) { 61 | e.printStackTrace(); 62 | } 63 | return responseMessage; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/retrofit/RetrofitHelper.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.retrofit; 2 | 3 | 4 | import android.content.Context; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.nio.charset.Charset; 9 | import java.security.KeyManagementException; 10 | import java.security.NoSuchAlgorithmException; 11 | import java.security.SecureRandom; 12 | import java.security.cert.X509Certificate; 13 | import java.util.concurrent.TimeUnit; 14 | 15 | import javax.net.ssl.HostnameVerifier; 16 | import javax.net.ssl.SSLContext; 17 | import javax.net.ssl.SSLSession; 18 | import javax.net.ssl.TrustManager; 19 | import javax.net.ssl.X509TrustManager; 20 | 21 | import okhttp3.Cache; 22 | import okhttp3.Interceptor; 23 | import okhttp3.OkHttpClient; 24 | import okhttp3.Request; 25 | import okhttp3.Response; 26 | import okhttp3.ResponseBody; 27 | import okio.BufferedSource; 28 | import retrofit2.Retrofit; 29 | import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; 30 | 31 | /** 32 | * Created by javalong on 2016/5/29. 33 | * retrofit2 34 | */ 35 | public class RetrofitHelper { 36 | private static ServerApi api; 37 | private static OkHttpClient mOkHttpClient; 38 | private static Context mContext; 39 | private static boolean showError = true; 40 | 41 | /** 42 | * 启动后初始化 43 | */ 44 | public static void init(Context context) { 45 | mContext = context; 46 | initOkHttpClient(); 47 | Retrofit retrofit = new Retrofit.Builder().baseUrl("http://{你的url}"). 48 | addConverterFactory(TWGsonConverterFactory.create()). 49 | addCallAdapterFactory(RxJavaCallAdapterFactory.create()). 50 | client(mOkHttpClient). 51 | build(); 52 | api = retrofit.create(ServerApi.class); 53 | } 54 | 55 | /** 56 | * 重置baseUrl 57 | */ 58 | public static void resetBaseUrl() { 59 | Retrofit retrofit = new Retrofit.Builder().baseUrl("http://{你的url}"). 60 | addConverterFactory(TWGsonConverterFactory.create()). 61 | addCallAdapterFactory(RxJavaCallAdapterFactory.create()). 62 | client(mOkHttpClient). 63 | build(); 64 | api = retrofit.create(ServerApi.class); 65 | } 66 | 67 | 68 | public static ServerApi getApi() { 69 | return api; 70 | } 71 | 72 | /** 73 | * 统一处理原始数据 74 | * 75 | * @param origion 是否需要原生的 不转化的数据 76 | * @param originalResponse 77 | */ 78 | private static Response dealResponseData(Boolean origion, Response originalResponse) { 79 | String jsonString = null; 80 | try { 81 | BufferedSource bufferedSource = originalResponse.body().source(); 82 | jsonString = bufferedSource.readString(Charset.forName("utf-8")); 83 | } catch (Exception e) { 84 | e.printStackTrace(); 85 | } 86 | if (origion != null && origion) { 87 | return onSuccess(originalResponse, jsonString); 88 | } 89 | ResponseMessageBean msgBean = ResponseMessageBean.analyseReponse(jsonString); 90 | if (msgBean == null) return onSuccess(originalResponse, msgBean.data.toString()); 91 | if (msgBean != null && (msgBean.errorCode == 200)) { 92 | showError = true; 93 | if (msgBean.data != null) { 94 | return onSuccess(originalResponse, msgBean.data.toString()); 95 | } else { 96 | return originalResponse.newBuilder().body(null).build(); 97 | } 98 | } else { 99 | onFailed(msgBean); 100 | throw new RuntimeException(msgBean.moreInfo.toString()); 101 | } 102 | } 103 | 104 | /** 105 | * 初始化okHttp 106 | */ 107 | private static void initOkHttpClient() { 108 | if (mOkHttpClient == null) { 109 | synchronized (RetrofitHelper.class) { 110 | Interceptor mRewriteCacheControlInterceptor = new Interceptor() { 111 | @Override 112 | public Response intercept(Chain chain) throws IOException { 113 | Request request = chain.request(); 114 | /** 115 | * 统一设置请求头 116 | */ 117 | Request newRequest = createRequestHeader(request.newBuilder()).build(); 118 | Response originalResponse = chain.proceed(newRequest); 119 | //如果是重定向,那么就执行重定向后返回数据。 120 | if (originalResponse.isRedirect()) { 121 | Request redirectRequest = request.newBuilder().url(originalResponse.header("location")).build(); 122 | originalResponse = chain.proceed(redirectRequest); 123 | } 124 | String origion = newRequest.header("origion"); 125 | originalResponse = dealResponseData(Boolean.parseBoolean(origion),originalResponse); 126 | return originalResponse; 127 | } 128 | }; 129 | 130 | if (mOkHttpClient == null) { 131 | try { 132 | X509TrustManager xtm = new X509TrustManager() { 133 | @Override 134 | public void checkClientTrusted(X509Certificate[] chain, String authType) { 135 | } 136 | 137 | @Override 138 | public void checkServerTrusted(X509Certificate[] chain, String authType) { 139 | } 140 | 141 | @Override 142 | public X509Certificate[] getAcceptedIssuers() { 143 | X509Certificate[] x509Certificates = new X509Certificate[0]; 144 | return x509Certificates; 145 | } 146 | }; 147 | 148 | SSLContext sslContext = null; 149 | try { 150 | sslContext = SSLContext.getInstance("SSL"); 151 | 152 | sslContext.init(null, new TrustManager[]{xtm}, new SecureRandom()); 153 | 154 | } catch (NoSuchAlgorithmException e) { 155 | e.printStackTrace(); 156 | } catch (KeyManagementException e) { 157 | e.printStackTrace(); 158 | } 159 | HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() { 160 | @Override 161 | public boolean verify(String hostname, SSLSession session) { 162 | return true; 163 | } 164 | }; 165 | 166 | // 指定缓存路径,缓存大小100Mb 167 | Cache cache = new Cache(new File(mContext.getCacheDir(), "HttpCache"), 1024 * 1024 * 100); 168 | mOkHttpClient = new OkHttpClient.Builder(). 169 | addInterceptor(mRewriteCacheControlInterceptor). 170 | retryOnConnectionFailure(false). 171 | connectTimeout(30, TimeUnit.SECONDS). 172 | sslSocketFactory(sslContext.getSocketFactory()). 173 | hostnameVerifier(DO_NOT_VERIFY). 174 | cache(cache). 175 | build(); 176 | } catch (Exception e) { 177 | e.printStackTrace(); 178 | } 179 | } 180 | } 181 | } 182 | } 183 | 184 | 185 | private static Response onSuccess(Response originalResponse, String content) { 186 | return originalResponse.newBuilder(). 187 | body(ResponseBody.create(null, content)). 188 | build(); 189 | } 190 | 191 | 192 | /** 193 | * errorCode 不为200 194 | * 195 | * @param msgBean 196 | */ 197 | private static void onFailed(ResponseMessageBean msgBean) { 198 | String alert = ""; 199 | if (msgBean == null) { 200 | return; 201 | } 202 | if (msgBean.errorCode != 200) { 203 | //TODO 自定义错误处理 204 | } 205 | } 206 | 207 | /** 208 | * 统一处理请求头部数据 209 | * 210 | * @return 211 | */ 212 | 213 | private static Request.Builder createRequestHeader(Request.Builder builder) { 214 | builder.header("Content-Type", 215 | "application/x-www-form-urlencoded"); 216 | builder.header("User-Agent", getUserAgent()); 217 | return builder; 218 | } 219 | 220 | 221 | public static String getUserAgent() { 222 | return "{自定义header头}"; 223 | } 224 | 225 | } -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/retrofit/ServerApi.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.retrofit; 2 | 3 | 4 | import retrofit2.http.Field; 5 | import retrofit2.http.FormUrlEncoded; 6 | import retrofit2.http.POST; 7 | import rx.Observable; 8 | 9 | /** 10 | * Created by javalong on 16-11-11. 11 | */ 12 | 13 | public interface ServerApi { 14 | 15 | /** 16 | * 这里只是一个Demo 17 | * 运行会崩溃,请先替换成具体的类型,参数,url 18 | */ 19 | @POST("url") 20 | @FormUrlEncoded 21 | Observable requestUrl(@Field("param") String param); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/retrofit/TWGsonConverterFactory.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.retrofit; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.TypeAdapter; 5 | import com.google.gson.reflect.TypeToken; 6 | 7 | import java.lang.annotation.Annotation; 8 | import java.lang.reflect.Type; 9 | 10 | import okhttp3.RequestBody; 11 | import okhttp3.ResponseBody; 12 | import retrofit2.Converter; 13 | import retrofit2.Retrofit; 14 | 15 | /** 16 | * A {@linkplain Converter.Factory converter} which uses Gson for JSON. 17 | *

18 | * Because Gson is so flexible in the types it supports, this converter assumes that it can handle 19 | * all types. If you are mixing JSON serialization with something else (such as protocol buffers), 20 | * you must {@linkplain Retrofit.Builder#addConverterFactory(Converter.Factory) add this instance} 21 | * last to allow the other converters a chance to see their types. 22 | */ 23 | public final class TWGsonConverterFactory extends Converter.Factory { 24 | /** 25 | * Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and 26 | * decoding from JSON (when no charset is specified by a header) will use UTF-8. 27 | */ 28 | public static TWGsonConverterFactory create() { 29 | return create(new Gson()); 30 | } 31 | 32 | /** 33 | * Create an instance using {@code gson} for conversion. Encoding to JSON and 34 | * decoding from JSON (when no charset is specified by a header) will use UTF-8. 35 | */ 36 | public static TWGsonConverterFactory create(Gson gson) { 37 | return new TWGsonConverterFactory(gson); 38 | } 39 | 40 | private final Gson gson; 41 | 42 | private TWGsonConverterFactory(Gson gson) { 43 | if (gson == null) throw new NullPointerException("gson == null"); 44 | this.gson = gson; 45 | } 46 | 47 | @Override 48 | public Converter responseBodyConverter(Type type, Annotation[] annotations, 49 | Retrofit retrofit) { 50 | TypeAdapter adapter = gson.getAdapter(TypeToken.get(type)); 51 | return new TWGsonResponseBodyConverter<>(gson, adapter, TypeToken.get(type)); 52 | } 53 | 54 | @Override 55 | public Converter requestBodyConverter(Type type, 56 | Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { 57 | TypeAdapter adapter = gson.getAdapter(TypeToken.get(type)); 58 | return new TWGsonRequestBodyConverter<>(gson, adapter); 59 | } 60 | } -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/retrofit/TWGsonRequestBodyConverter.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.retrofit; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.TypeAdapter; 5 | import com.google.gson.stream.JsonWriter; 6 | 7 | import java.io.IOException; 8 | import java.io.OutputStreamWriter; 9 | import java.io.Writer; 10 | import java.nio.charset.Charset; 11 | 12 | import okhttp3.MediaType; 13 | import okhttp3.RequestBody; 14 | import okio.Buffer; 15 | import retrofit2.Converter; 16 | 17 | /** 18 | * Created by javalong on 2016/6/7. 19 | */ 20 | 21 | public class TWGsonRequestBodyConverter implements Converter { 22 | private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8"); 23 | private static final Charset UTF_8 = Charset.forName("UTF-8"); 24 | 25 | private final Gson gson; 26 | private final TypeAdapter adapter; 27 | 28 | TWGsonRequestBodyConverter(Gson gson, TypeAdapter adapter) { 29 | this.gson = gson; 30 | this.adapter = adapter; 31 | } 32 | 33 | @Override 34 | public RequestBody convert(T value) throws IOException { 35 | Buffer buffer = new Buffer(); 36 | Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8); 37 | JsonWriter jsonWriter = gson.newJsonWriter(writer); 38 | adapter.write(jsonWriter, value); 39 | jsonWriter.close(); 40 | return RequestBody.create(MEDIA_TYPE, buffer.readByteString()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/retrofit/TWGsonResponseBodyConverter.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.retrofit; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.TypeAdapter; 5 | import com.google.gson.reflect.TypeToken; 6 | import com.google.gson.stream.JsonReader; 7 | 8 | import java.io.IOException; 9 | 10 | import okhttp3.ResponseBody; 11 | import retrofit2.Converter; 12 | 13 | /** 14 | * Created by javalong on 2016/6/7. 15 | */ 16 | public class TWGsonResponseBodyConverter implements Converter { 17 | 18 | private final Gson gson; 19 | private final TypeAdapter adapter; 20 | private final TypeToken typeToken; 21 | 22 | TWGsonResponseBodyConverter(Gson gson, TypeAdapter adapter, TypeToken typeToken) { 23 | this.gson = gson; 24 | this.adapter = adapter; 25 | this.typeToken = typeToken; 26 | } 27 | 28 | @Override 29 | public T convert(ResponseBody value) throws IOException { 30 | Object obj = checkBasicType(value); 31 | if (obj != null) return (T) obj; 32 | JsonReader jsonReader = gson.newJsonReader(value.charStream()); 33 | try { 34 | return adapter.read(jsonReader); 35 | } finally { 36 | value.close(); 37 | } 38 | } 39 | 40 | /** 41 | * 如果是基本类型就转化后,返回 42 | */ 43 | private Object checkBasicType(ResponseBody value) throws IOException { 44 | String typeName = typeToken.getRawType().getSimpleName(); 45 | if ("String".equals(typeName)) { 46 | return value.string(); 47 | } else if ("Boolean".equals(typeName)) { 48 | return Boolean.parseBoolean(value.string()); 49 | } else if ("Integer".equals(typeName)) { 50 | return Integer.parseInt(value.string()); 51 | } 52 | return null; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/javalong/rrdm/retrofit/TWJavaCallAdapterFactory.java: -------------------------------------------------------------------------------- 1 | package com.javalong.rrdm.retrofit; 2 | 3 | import java.lang.annotation.Annotation; 4 | import java.lang.reflect.ParameterizedType; 5 | import java.lang.reflect.Type; 6 | 7 | import retrofit2.Call; 8 | import retrofit2.CallAdapter; 9 | import retrofit2.Response; 10 | import retrofit2.Retrofit; 11 | import retrofit2.adapter.rxjava.HttpException; 12 | import retrofit2.adapter.rxjava.Result; 13 | import rx.Observable; 14 | import rx.Single; 15 | import rx.Subscriber; 16 | import rx.exceptions.Exceptions; 17 | import rx.functions.Action0; 18 | import rx.functions.Func1; 19 | import rx.subscriptions.Subscriptions; 20 | 21 | /** 22 | * Created by javalong on 2016/6/6. 23 | */ 24 | public class TWJavaCallAdapterFactory extends CallAdapter.Factory { 25 | public static TWJavaCallAdapterFactory create() { 26 | return new TWJavaCallAdapterFactory(); 27 | } 28 | 29 | private TWJavaCallAdapterFactory() { 30 | } 31 | 32 | @Override 33 | public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) { 34 | Class rawType = getRawType(returnType); 35 | boolean isSingle = "rx.Single".equals(rawType.getCanonicalName()); 36 | if (rawType != Observable.class && !isSingle) { 37 | return null; 38 | } 39 | if (!(returnType instanceof ParameterizedType)) { 40 | String name = isSingle ? "Single" : "Observable"; 41 | throw new IllegalStateException(name + " return type must be parameterized" 42 | + " as " + name + " or " + name + ""); 43 | } 44 | 45 | CallAdapter> callAdapter = getCallAdapter(returnType); 46 | if (isSingle) { 47 | // Add Single-converter wrapper from a separate class. This defers classloading such that 48 | // regular Observable operation can be leveraged without relying on this unstable RxJava API. 49 | return makeSingle(callAdapter); 50 | } 51 | return callAdapter; 52 | } 53 | 54 | static CallAdapter> makeSingle(final CallAdapter> callAdapter) { 55 | return new CallAdapter>() { 56 | @Override 57 | public Type responseType() { 58 | return callAdapter.responseType(); 59 | } 60 | 61 | @Override 62 | public Single adapt(Call call) { 63 | Observable observable = callAdapter.adapt(call); 64 | return observable.toSingle(); 65 | } 66 | }; 67 | } 68 | 69 | private CallAdapter> getCallAdapter(Type returnType) { 70 | Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType); 71 | Class rawObservableType = getRawType(observableType); 72 | if (rawObservableType == Response.class) { 73 | if (!(observableType instanceof ParameterizedType)) { 74 | throw new IllegalStateException("Response must be parameterized" 75 | + " as Response or Response"); 76 | } 77 | Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType); 78 | return new ResponseCallAdapter(responseType); 79 | } 80 | 81 | if (rawObservableType == Result.class) { 82 | if (!(observableType instanceof ParameterizedType)) { 83 | throw new IllegalStateException("Result must be parameterized" 84 | + " as Result or Result"); 85 | } 86 | Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType); 87 | return new ResultCallAdapter(responseType); 88 | } 89 | 90 | return new SimpleCallAdapter(observableType); 91 | } 92 | 93 | static final class CallOnSubscribe implements Observable.OnSubscribe> { 94 | private final Call originalCall; 95 | 96 | CallOnSubscribe(Call originalCall) { 97 | this.originalCall = originalCall; 98 | } 99 | 100 | @Override 101 | public void call(final Subscriber> subscriber) { 102 | // Since Call is a one-shot type, clone it for each new subscriber. 103 | final Call call = originalCall.clone(); 104 | 105 | // Attempt to cancel the call if it is still in-flight on unsubscription. 106 | subscriber.add(Subscriptions.create(new Action0() { 107 | @Override 108 | public void call() { 109 | call.cancel(); 110 | } 111 | })); 112 | 113 | try { 114 | Response response = call.execute(); 115 | if (!subscriber.isUnsubscribed()) { 116 | subscriber.onNext(response); 117 | } 118 | } catch (Throwable t) { 119 | Exceptions.throwIfFatal(t); 120 | if (!subscriber.isUnsubscribed()) { 121 | subscriber.onError(t); 122 | } 123 | return; 124 | } 125 | 126 | if (!subscriber.isUnsubscribed()) { 127 | subscriber.onCompleted(); 128 | } 129 | } 130 | } 131 | 132 | static final class ResponseCallAdapter implements CallAdapter> { 133 | private final Type responseType; 134 | 135 | ResponseCallAdapter(Type responseType) { 136 | this.responseType = responseType; 137 | } 138 | 139 | @Override 140 | public Type responseType() { 141 | return responseType; 142 | } 143 | 144 | @Override 145 | public Observable> adapt(Call call) { 146 | return Observable.create(new CallOnSubscribe<>(call)); 147 | } 148 | } 149 | 150 | static final class SimpleCallAdapter implements CallAdapter> { 151 | private final Type responseType; 152 | 153 | SimpleCallAdapter(Type responseType) { 154 | this.responseType = responseType; 155 | } 156 | 157 | @Override 158 | public Type responseType() { 159 | return responseType; 160 | } 161 | 162 | @Override 163 | public Observable adapt(Call call) { 164 | return Observable.create(new CallOnSubscribe<>(call)) // 165 | .flatMap(new Func1, Observable>() { 166 | @Override 167 | public Observable call(Response response) { 168 | if (response.isSuccessful()) { 169 | return Observable.just(response.body()); 170 | } 171 | return Observable.error(new HttpException(response)); 172 | } 173 | }); 174 | } 175 | } 176 | 177 | static final class ResultCallAdapter implements CallAdapter> { 178 | private final Type responseType; 179 | 180 | ResultCallAdapter(Type responseType) { 181 | this.responseType = responseType; 182 | } 183 | 184 | @Override 185 | public Type responseType() { 186 | return responseType; 187 | } 188 | 189 | @Override 190 | public Observable> adapt(Call call) { 191 | return Observable.create(new CallOnSubscribe<>(call)) // 192 | .map(new Func1, Result>() { 193 | @Override 194 | public Result call(Response response) { 195 | return Result.response(response); 196 | } 197 | }) 198 | .onErrorReturn(new Func1>() { 199 | @Override 200 | public Result call(Throwable throwable) { 201 | return Result.error(throwable); 202 | } 203 | }); 204 | } 205 | } 206 | 207 | } 208 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_login.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 |