android開發學習 ------- Retrofit+Rxjava+MVP網絡請求的實例

http://www.jianshu.com/p/7b839b7c5884   推薦 ,照着這個敲完 , 測試成功 , 推薦你們都去看一下 。 json

下面貼一下我照着這個敲完的代碼:api

Book實體類 - 用於封裝網絡請求返回的數據; 這個藉助GsonFormat 插件,注意若實體類有實體,必定要手動實現toString();網絡

public interface RetrofitService {
    /**
     //拼接一個URL而後進行網絡請求
     //這裏咱們拼接的URL就是 完整URL:https://api.douban.com/v2/book/search?q=xxx&tag=&start=0&count=1;
     //每一個URL前面都是以http://www.jianshu.com/開頭,咱們把這個不變的部分,也叫作baseUrl提出來,放到另外一個地方,在下面咱們會提到
     */

    //將返回值call改成observable
    @GET("book/search")
    Observable<Book> getSearchBook(@Query("q") String name,
                                   @Query("tag") String tag,
                                   @Query("start") int start,
                                   @Query("count") int count
                             );

/**
 * 在每一個入參前還多了一個註解。好比第一個入參@Query("q") String name,Query表示把你傳入的字段拼接起來
 * 這個url須要幾個入參你就在這個方法中定義幾個入參,每一個入參前都要加上Query註解
 *
 * @GET("book/search")
   Call<Book> getSearchBook(@Query("q") String name);//name由調用者傳入
   @GET("book/search?q=name")
   Call<Book> getSearchBook();
  **********************************************************
   若是入參比較多,就能夠把它們都放在Map中
   @GET("book/search")
   Call<Book> getSearchBook(@QueryMap Map<String, String> options);
   ***********************************************************
   用於替換url中某個字段
 @GET("group/{id}/users")
 Call<Book> groupList(@Path("id") int groupId);
 *******************************************************
 指定一個對象做爲HTTP請求體
 @POST("users/new")
 Call<User> createUser(@Body User user);
 它會把咱們傳入的User實體類轉換爲用於傳輸的HTTP請求體,進行網絡請求
 **********************************************************
 傳送表單數據
 @FormUrlEncoded
 @POST("user/edit")
 Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
 */
}
/**
 * Created by lemon on 2017/11/20.
 * 主要用於Retrofit的初始化:
 */

public class RetrofitHelper {
    private Context mCntext;
    OkHttpClient client = new OkHttpClient();
    GsonConverterFactory factory = GsonConverterFactory.create(new GsonBuilder().create());
    private static RetrofitHelper instance = null;
    private Retrofit mRetrofit = null;

    //靜態方法getInstance用於獲取自身RetrofitHelper的實例化,而且只會實例化一次。
    public static RetrofitHelper getInstance(Context context){
        if (instance == null){
            instance = new RetrofitHelper(context);
        }
        return instance;
    }
    private RetrofitHelper(Context mContext){
        mCntext = mContext;
        init();
    }

    private void init() {
        resetApp();
    }

    private void resetApp() {
        mRetrofit = new Retrofit.Builder()
                .baseUrl("https://api.douban.com/v2/")
                .client(client)
                // 由於接口返回的數據不是咱們須要的實體類,咱們須要調用addConverterFactory方法進行轉換。
                // 因爲返回的數據爲json類型,因此在這個方法中傳入Gson轉換工廠
                .addConverterFactory(factory)
                //支持RXJava
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    }

    //建立RetrofitService的實體類
    //getServer方法就是爲了獲取RetrofitService接口類的實例化。
    public RetrofitService getServer(){
        return mRetrofit.create(RetrofitService.class);
    }

}
/**
 * Created by lemon on 2017/11/20.
 * 這個是和其餘層直接調用的接口
 * 讓你更方便的調用RetrofitService 中定義的方法:
 */

public class DataManager {

    private RetrofitService mRetrofitService;

    // 在它的構造方法中,咱們獲得了RetrofitService 的實例化
    // 這樣,把RetrofitService 中定義的方法都封裝到DataManager 中,
    // 之後不管在哪一個要調用方法時直接在DataManager 中調用就能夠了,
    // 而不是重複創建RetrofitService 的實例化,再調用其中的方法。
    public DataManager(Context context){
        this.mRetrofitService = RetrofitHelper.getInstance(context).getServer();
    }

    public Observable<Book> getSearchBooks(String name, String tag, int start, int count){
        return mRetrofitService.getSearchBook(name,tag,start,count);
    }
}
/**
 * Created by lemon on 2017/11/20.
 * presenter主要用於網絡的請求以及數據的獲取,view就是將presenter獲取到的數據進行展現。
 */

public interface Presenter {
    void onCreate();

    void onStart();//暫時沒用到

    void onStop();

    void pause();//暫時沒用到

    /*
    用於綁定咱們定義的View.也就是,你想把請求下來的數據實體類給哪一個View就傳入哪一個View
     */
    void attachView(BookView view);

    void attachIncomingIntent(Intent intent);//暫時沒用到


}
public class BookPresenter implements Presenter {

    private DataManager manager;
    private CompositeSubscription mCompositeSubscription;
    private Context mContext;
    private BookView mBookView;
    private Book mBook;


    public BookPresenter (Context mContext){
        this.mContext = mContext;
    }

    @Override
    public void onCreate() {
        manager = new DataManager(mContext);
        /**
         * CompositeSubscription是用來存放RxJava中的訂閱關係的。
         * 注意請求完數據要及時清掉這個訂閱關係,否則會發生內存泄漏。
         * 可在onStop中經過調用CompositeSubscription的unsubscribe方法來取消這個訂閱關係,
         * 不過一旦調用這個方法,那麼這個CompositeSubscription也就沒法再用了,要想再用只能從新new一個。
         */
        mCompositeSubscription = new CompositeSubscription();
    }

    @Override
    public void onStart() {

    }

    @Override
    public void onStop() {
        if (mCompositeSubscription.hasSubscriptions()){
            mCompositeSubscription.unsubscribe();
        }
    }

    @Override
    public void pause() {

    }

    //想把請求下來的數據實體類給哪一個View就傳入哪一個View
    //在attachView中,咱們把BookView傳進去。也就是說咱們要把請求下來的實體類交給BookView來處理。
    @Override
    public void attachView(BookView view) {
        mBookView = view;
    }

    @Override
    public void attachIncomingIntent(Intent intent) {

    }

    /**
     * 名字和入參都和請求接口RetrofitService中的方法相同。這個方法也就是請求的具體實現過程。
     */
    public void getSearchBook(String name,String tag,int start,int count){
        mCompositeSubscription.add(manager.getSearchBooks(name, tag, start, count)
                .subscribeOn(Schedulers.io())  //請求數據的事件發生在IO線程
                .observeOn(AndroidSchedulers.mainThread())  //請求完成後在主線程更新UI
                .subscribe(new Observer<Book>() {
                    @Override
                    public void onCompleted() {
                        //全部的事件都完成,可作這些操做
                        if(mBook != null){
                            mBookView.onSuccess(mBook);
                        }
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        //請求過程當中發生錯誤
                        throwable.printStackTrace();
                        mBookView.onError("請求失敗!!");
                    }

                    @Override
                    public void onNext(Book book) {
                        //這裏的BOOK就是咱們請求接口返回的實體類
                        mBook = book;
                    }
                })
        );
    }
}
/**
 * Created by lemon on 2017/11/20.
 * View是空的,主要用於和Android中的View區別開來
 */

public interface View {
}
public interface BookView extends View {
    /**
     * 若是presenter請求成功,將向該方法傳入請求下來的實體類,
     * 也就是Book,view拿到這個數據實體類後,就能夠進行關於這個數據的展現或其餘的一些操做
     * @param mBook
     */
    void onSuccess(Book mBook);

    /**
     * 若是請求失敗,就會向這個view傳入失敗信息,你能夠彈個Toast來提示請求失敗
     * @param result
     */
    void onError(String result);
}
public class BookActivity extends AppCompatActivity {

    private TextView text ;
    private Button btn ;
    private BookPresenter mBookPresenter = new BookPresenter(this);

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_message);
        text = (TextView) findViewById(R.id.text);
        btn = (Button) findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mBookPresenter.getSearchBook("xxx",null,0,1);
            }
        });
        mBookPresenter.onCreate();
        mBookPresenter.attachView(mBookView);
    }


    private BookView mBookView = new BookView() {
        @Override
        public void onSuccess(Book mBook) {
            Log.e("log","mbook"+mBook.toString());
            text.setText(mBook.toString());
        }

        @Override
        public void onError(String result) {
            Toast.makeText(BookActivity.this,result, Toast.LENGTH_SHORT).show();
        }
    };


    @Override
    protected void onDestroy() {
        super.onDestroy();
        mBookPresenter.onStop();
    }
}
相關文章
相關標籤/搜索