mvp+retrofit+rxjava


引用

"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",
View Code

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);
    }

}
View Code
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);
}
View Code
/**創建並配置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;
        }
    }



}
View Code
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;
    }

}
View Code

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();

}
View Code
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);
    }

}
View Code

 /**

* 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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM