如何使用MVP+RxJava+Retrofit获取请求的网络接口,把请求到的网络数据在屏幕上显示出来

289 阅读2分钟

步骤:

打开Android Studio,新建一个项目取名为MVPDemo。demo的功能很简单,就是点击按钮调用上面的那个测试接口,将请求下来的信息显示在屏幕上。

工程的目录结构:

图片.png

在build.gradle中添加如下依赖:

compile 'com.squareup.retrofit2:retrofit:2.1.0'  //添加Retrofit库
compile 'com.squareup.retrofit2:converter-gson:2.1.0'  //返回的数据为json类型
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' //使Rxjava与retrofit结合使用
compile 'io.reactivex:rxandroid:1.2.0' //引入RxAndroid

RetrofitHelper用于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;
    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://wanandroid.com/wenda/comments/问答id/json")
                .client(client)
                .addConverterFactory(factory)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    }
    public RetrofitService getServer(){
        return mRetrofit.create(RetrofitService.class);
    }
}

RetrofitService代码:

public interface RetrofitService {
    @GET("book/search")
    Observable<Book> getSearchBooks(@Query("q") String name,
                                    @Query("tag") String tag,
                                    @Query("start") int start,
                                    @Query("count") int count);
}

manager中DataManager更方便的调用了RetrofitService 中定义的方法:

public class DataManager {
    private RetrofitService mRetrofitService;
    public DataManager(Context context){
        this.mRetrofitService = RetrofitHelper.getInstance(context).getServer();
    }
    public  Observable<Book> getSearchBooks(String name,String tag,int start,int count){
        return mRetrofitService.getSearchBooks(name,tag,start,count);
    }
}

presenter主要用于网络的请求以及数据的获取,view就是将presenter获取到的数据进行展示。首先看view,创建两个接口类View和BookView,其中View是空的,主要用于和Android中的View区别开来:

public interface View {
}

让BookView继承自View :

public interface BookView extends View {
    void onSuccess(Book mBook);
    void onError(String result);
}

定义一个基础Presenter进行网络请求:

public interface Presenter {
    void onCreate();

    void onStart();//暂时没用到

    void onStop();

    void pause();//暂时没用到

    void attachView(View view);

    void attachIncomingIntent(Intent intent);//暂时没用到
}

BookPresenter具体实现代码:

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);
        mCompositeSubscription = new CompositeSubscription();
    }

    @Override
    public void onStart() {

    }

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

    @Override
    public void pause() {

    }

    @Override
    public void attachView(View view) {
        mBookView = (BookView)view;
    }

    @Override
    public void attachIncomingIntent(Intent intent) {
    }
    public void getSearchBooks(String name,String tag,int start,int count){
        mCompositeSubscription.add(manager.getSearchBooks(name,tag,start,count)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Book>() {
                    @Override
                    public void onCompleted() {
                        if (mBook != null){
                            mBookView.onSuccess(mBook);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        mBookView.onError("请求失败!!");
                    }

                    @Override
                    public void onNext(Book book) {
                        mBook = book;
                    }
                })
        );
    }
}

可以调用这个接口方法来进行网络的请求了

先写一下页面的布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:orientation="vertical"
    android:paddingTop="@dimen/activity_vertical_margin">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MVP+Retrofit+RxJava" />
    <Button
        android:id="@+id/button"
        android:onClick="getFollowers"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="请求"/>
</LinearLayout>

界面一共两个控件如下:
Button:点击时进行网络请求
TextView:用于显示请求下来的数据

Activity中代码:

public class MainActivity extends AppCompatActivity {

    private TextView text;
    private Button button;
    private BookPresenter mBookPresenter = new BookPresenter(this);
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView)findViewById(R.id.text);
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mBookPresenter.getSearchBooks("问答id", null, 0, 1);
            }
        });
        mBookPresenter.onCreate();
        mBookPresenter.attachView(mBookView);
    }

    private BookView mBookView = new BookView() {
        @Override
        public void onSuccess(Book mBook) {
            text.setText(mBook.toString());
        }

        @Override
        public void onError(String result) {
            Toast.makeText(MainActivity.this,result, Toast.LENGTH_SHORT).show();
        }
    };
    @Override
    protected void onDestroy(){
        super.onDestroy();
        mBookPresenter.onStop();
    }
}

最后在AndroidManifest中添加网络权限:

<uses-permission android:name="android.permission.INTERNET"/>