引用
"retrofit" : "com.squareup.retrofit2:retrofit:2.0.1", "retrofit-adapter" : "com.squareup.retrofit2:adapter-rxjava:2.0.1", "retrofit-converter" : "com.squareup.retrofit2:converter-gson:2.0.1", "gson" : "com.google.code.gson:gson:2.6.2", "rxjava" : "io.reactivex:rxjava:1.1.2", "rxandroid" : "io.reactivex:rxandroid:1.1.0", "okhttp" : "com.squareup.okhttp3:okhttp:3.2.0", "okhttp-urlconnection" : "com.squareup.okhttp3:okhttp-urlconnection:3.2.0", "okhttp-logging" : "com.squareup.okhttp3:logging-interceptor:3.2.0", "okhttp-cookie" : "com.github.franmontiel:PersistentCookieJar:v0.9.3",
Retrofit
import com.google.gson.Gson; import com.google.gson.GsonBuilder; import java.util.concurrent.TimeUnit; import okhttp3.OkHttpClient; import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; /**用于辅助初始化retrofit**/ public class RxService { private static final long DEFAULT_TIMEOUT = 20L; final static Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") .serializeNulls()// 调用serializeNulls方法,改变gson对象的默认行为,null值将被输出 .create(); //addInterceptor:设置应用拦截器,可用于设置公共参数,头信息,日志拦截等 //addNetworkInterceptor:网络拦截器,可以用于重试或重写,对应与1.9中的setRequestInterceptor。 //setLevel NONE(不记录) BASIC(请求/响应行) HEADER(请求/响应行 + 头) BODY(请求/响应行 + 头 + 体) //cookieJar:保持在同一个会话里面 //TimeUnit.SECONDS秒做单位 private static OkHttpClient okHttpClient = new OkHttpClient.Builder() .addNetworkInterceptor(new HttpLoggingInterceptor() .setLevel(HttpLoggingInterceptor.Level.HEADERS)) .addInterceptor(new HttpLoggingInterceptor() .setLevel(HttpLoggingInterceptor.Level.BODY)) .cookieJar(App.getInstance().getCookieJar()) .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS) .build(); private static Retrofit retrofit = null; private RxService() {} // private final static RxService rxService = new RxService(); public static <T> T createApi(Class<T> clazz,String url) { retrofit = new Retrofit.Builder() .baseUrl(url) .client(okHttpClient) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build(); return retrofit.create(clazz); } public static <T> T createApi(Class<T> clazz) { retrofit = new Retrofit.Builder() .baseUrl(Config.BASE_DEFAULT) .client(okHttpClient) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build(); return retrofit.create(clazz); } }
import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.POST; import rx.Observable; /** * Created by JDD on 2016/4/8. */ public interface ILoginService { @FormUrlEncoded @POST(LoginSingleService.URL) Observable<UsersEntity> login(@Field("token") String token, @Field("userName") String userName, @Field("userPassword") String userPassword); }
/**创建并配置retrofit service**/ public class LoginSingleService { public static final String URL = "login.do"; protected static final Object monitor = new Object(); static ILoginService sJokeSingleton = null; // public static final int meizhiSize = 10; // public static final int gankSize = 5; //测试service public static ILoginService getLoginSingleton() { synchronized (monitor) { if (sJokeSingleton == null) { sJokeSingleton = RxService.createApi(ILoginService.class); } return sJokeSingleton; } } }
Presenter
import android.util.Log; import rx.Observer; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; public class LoginPresenter implements ILoginPresenter { public Subscription login(final String username,final String pwd, final CallBack callBack) { if (username == null || pwd == null || username.equals("") || pwd.equals("")){ callBack.Error(STATUS.NULL_ERROR); return null; } //观察者Subscription Subscription s = LoginSingleService.getLoginSingleton()//事件源,被观察者Observable .login("21341234",username,pwd) .subscribeOn(Schedulers.io())//指定观察者运行的线程 .map(entity -> entity.getData()) .observeOn(AndroidSchedulers.mainThread())//指定订阅者运行的线程 .subscribe(new Observer<UserEntity>() {//订阅subscriber @Override public void onCompleted() { Log.e("onNext","onCompleted"); callBack.End(); } @Override public void onError(Throwable e) { Log.e("onNext","onError "+e.getMessage()); callBack.Error(STATUS.ERROR); } @Override public void onNext(UserEntity entity) { STATUS status; if (entity != null) { status = STATUS.SUCCESS; Log.e("onNext","hello "+entity.getName()); App.getInstance().setUserEntity(entity); App.getInstance().setPerson(entity,pwd); } else status = STATUS.ERROR; callBack.Success(status); } }); return s; } }
Main
import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import rx.Subscription; import rx.subscriptions.CompositeSubscription; /** * Created by LiuZhen on 2016/5/11. */ public abstract class BaseActivity extends AppCompatActivity { private final static String TAG = "BaseActivity"; private CompositeSubscription mCompositeSubscription; protected Context context; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getLayoutId()); this.context = BaseActivity.this; } public CompositeSubscription getCompositeSubscription() { if (this.mCompositeSubscription == null) { this.mCompositeSubscription = new CompositeSubscription(); } return this.mCompositeSubscription; } /**使CompositeSubscription持有订阅**/ public void addSubscription(Subscription s) { if (this.mCompositeSubscription == null) { this.mCompositeSubscription = new CompositeSubscription(); } this.mCompositeSubscription.add(s); } @Override protected void onDestroy() { super.onDestroy(); if (this.mCompositeSubscription != null) { this.mCompositeSubscription.unsubscribe();//取消所有的订阅 } } protected abstract int getLayoutId(); }
import android.os.Bundle; import android.widget.TextView; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; public class MainActivity extends BaseActivity { private TextView username; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EventBus.getDefault().register(this); username = (TextView) findViewById(R.id.username); username.setText(App.getInstance().getPerson().getName()+" hello"); } @Override protected int getLayoutId() { return R.layout.activity_main; } @Subscribe(threadMode = ThreadMode.MAIN) public void onEvent() { Toasts.showShort("刷新UI",context); } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } }
/**
* Retrofit精髓就在三点。
* 1、动态代理,用注解来生成请求参数;
* 2、适配器模式的应用,请求返回各种CallAdapter,可扩展到RxJava、Java8,还有任何你自己写的Adapter;
* 3、Converter,你可以把请求的响应用各种Converter转成你的需求上.
**/
rxjava有点得注意的就是如果对于涉及了 Activity 或 Fragment 的处理不仔细的话,AsyncTasks 可能会造成内存泄露。不幸的是,使用 RxJava 不会魔术般的缓解内存泄露危机,调用的 Observable.subscribe() 的返回值是一个 Subscription 对象。
Subscription 类只有两个方法,unsubscribe() 和 isUnsubscribed()。为了防止可能的内存泄露,在你的 Activity 或 Fragment 的 onDestroy 里,用 Subscription.isUnsubscribed() 检查你的 Subscription 是否是 unsubscribed。
如果调用了 Subscription.unsubscribe() ,Unsubscribing将会对 items 停止通知给你的 Subscriber,并允许垃圾回收机制释放对象,防止任何 RxJava 造成内存泄露。如果你正在处理多个 Observables 和 Subscribers,所有的 Subscription 对象可以添加到 CompositeSubscription,然后可以使用 CompositeSubscription.unsubscribe() 方法在同一时间进行退订(unsubscribed)