Android uses Kotlin + REFROFIT + RXJAVA + MVP to implement simple network request packages

tags: Kotlin

Previous Blog We told Kotlin + Retrofit + RXJAVA to implement a simple implementation of network requests. This blog will implement the Simple Package of Kotlin + Retrofit + RxJava + MVP to implement network requests.

The requested URL is: const val base_server_url = "https://www.wanandroid.com"

1. TheBaseActivity code is as follows:

/**
   * @ Author: njb
   * @  : 2020/12/3 17:33
   * @ Description:
 */
abstract class BaseActivity<P : BasePresenter<*>> : AppCompatActivity(), BaseView {
    lateinit var context: Context
    protected var presenter: P? = null
    protected var unbinder: Unbinder? = null

    private var waitDialog: LoadingDialog? = null

    protected abstract val layoutId: Int

    protected abstract fun createPresenter(): P

    protected abstract fun initView()

    protected abstract fun addListener()


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (layoutId != 0) {
            setContentView(layoutId)
        }
        unbinder = ButterKnife.bind(this)
        context = this
        presenter = createPresenter()
        initView()
        addListener()
    }


    /**
           * Open Activity
     *
     * @param cls
     */
    fun startA(cls: Class<*>) {
        val intent = Intent(context, cls)
        startActivity(intent)
    }

    public override fun onPause() {
        super.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        presenter!!.detachView()
        unbinder!!.unbind()
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home -> {
                onBackPressed()
            }
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onBackPressed() {
        super.onBackPressed()
                 // Fragment outlet
        val count = supportFragmentManager.backStackEntryCount
        if (count == 0) {
            super.onBackPressed()
        } else {
            supportFragmentManager.popBackStack()
        }
    }


    /**
     * @param s
     */
    fun showtoast(s: String) {
        Toast.makeText(context, s, Toast.LENGTH_SHORT).show()
    }

    fun showFileDialog() {}

    fun hideFileDialog() {}

    /**
           * Display loading box
     *
     * @param textRes
     * @param color
     */
    fun showWaitDialog(textRes: String, color: Int) {
        if (null == waitDialog) {
            waitDialog = LoadingDialog(this, textRes, color)
        } else {
            waitDialog!!.setShowText(textRes)
            if (!waitDialog!!.isShown) {
                waitDialog!!.showUp()
            }
        }
    }

    /**
           * Display loading box
     */
    fun showWaitDialog() {
        if (null == waitDialog) {
            waitDialog = LoadingDialog(this)
        } else {
            waitDialog!!.setShowText("")
            if (!waitDialog!!.isShown) {
                waitDialog!!.showUp()
            }
        }
    }

    /**
           * Show ProgressBar
     *
           * @Param Textres Needs the word to be prompted
     */
    fun showWaitDialog(textRes: Int) {
        if (null == waitDialog) {
            waitDialog = LoadingDialog(this, textRes)
        } else {
            waitDialog!!.setShowText(textRes)
            if (!waitDialog!!.isShown) {
                waitDialog!!.showUp()
            }
        }
    }

    /**
           * Destroy ProgressBar
     */
    fun dismissWaitDialog() {
        if (null != waitDialog && waitDialog!!.isShown) {
            waitDialog!!.dismiss()
        }
    }


    /**
           * Get View by resource RES
     *
     * @param res
     * @return
     */
    fun getViewByRes(@LayoutRes res: Int): View {
        return LayoutInflater.from(context).inflate(res, null)
    }

    /**
           * Get text for textView
     *
     * @param tv
     * @return
     */
    fun getTV(tv: TextView?): String {
        return tv?.text?.toString()?.trim { it <= ' ' } ?: ""
    }

    override fun showError(msg: String) {
        showtoast(msg)
    }

    override fun onErrorCode(model: BaseResult<Any>) {
        when {
            model.errorCode < 0.toString() -> showtoast(model.errorMsg)
        }
    }

    override fun showLoadingFileDialog() {
        showWaitDialog()
    }

    override fun hideLoadingFileDialog() {
        dismissWaitDialog()
    }

    override fun onProgress(totalSize: Long, downSize: Long) {}

    fun addFragmentToActivity(
        fragmentManager: FragmentManager,
        fragment: Fragment, frameId: Int
    ) {
        val transaction = fragmentManager.beginTransaction()
        if (!fragment.isAdded)
            transaction.add(frameId, fragment)
        fragmentManager.fragments.filter { it.id == fragment.id }.map { transaction.hide(it) }
        transaction.show(fragment)
        transaction.commit()
    }

2. Basepresenter code is as follows:

public  class BasePresenter<V extends BaseView> {

    private CompositeDisposable compositeDisposable;
    public V baseView;

    protected ApiServer apiServer = ApiRetrofit.getInstance().getApiService();

    public BasePresenter(V baseView) {
        this.baseView = baseView;
    }

    /**
           * Release binding
     */
    public void detachView() {
        baseView = null;
        removeDisposable();
    }

    /**
           * Return to View
     *
     * @return
     */
    public V getBaseView() {
        return baseView;
    }


    public void addDisposable(Observable<?> observable, DisposableObserver observer) {
        if (compositeDisposable == null) {
            compositeDisposable = new CompositeDisposable();
        }
        compositeDisposable.add(
                observable.subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribeWith(observer));
    }

    public void removeDisposable() {
        if (compositeDisposable != null) {
            compositeDisposable.dispose();
        }
    }
}

3. The Basefragment code is as follows:

/**
   * @ Author: njb
   * @  : 2020/12/3 17:38
   * @ Description:
 */
abstract class BaseFragment<P : BasePresenter<*>> : Fragment(), BaseView {

    internal var context: Context? = null
    private var dialog: ProgressDialog? = null

         // Control is initialized
    private var isViewCreated: Boolean = false

         // Whether the current Fragment is loaded, if loading data is loaded, no more
    private var isLoadCompleted: Boolean = false
         / / Is not visible
    private var isUIVisible: Boolean = false


    protected var presenter: P? = null

    /**
           * Load layout
     */
    @LayoutRes
    abstract fun getLayoutId(): Int


         // Lazy loading, mandatory subtyver rewriting
    abstract fun loadData()

    abstract fun initView()

    abstract fun addListener()

    abstract fun createPresenter(): P

    abstract fun setTitle()


    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        isUIVisible = isVisibleToUser
        if (isVisibleToUser && isViewCreated && isUIVisible && !isLoadCompleted) {
            isLoadCompleted = true
            loadData()
        }
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        if (isViewCreated && isUIVisible) {

            loadData()
            isLoadCompleted = true
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val rootView = inflater.inflate(getLayoutId(), container, false)
/*        presenter = createPresenter()
        isViewCreated = true

        initView()
        addListener()*/
        return rootView
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        presenter = createPresenter()
        isViewCreated = true
        initView()
        addListener()
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        isUIVisible = !hidden
        isLoadCompleted = !hidden
    }


    override fun onAttach(context: Context) {
        super.onAttach(context)
        this.context = context
    }

    override fun onResume() {
        super.onResume()

    }

    override fun onPause() {
        super.onPause()
    }

    override fun onDestroyView() {
        super.onDestroyView()

        if (presenter != null) {
            presenter!!.detachView()
        }
    }

    /**
           * Open the specified Activity
     *
     * @param cls
     */
    fun startA(cls: Class<*>) {
        val intent = Intent(context, cls)
        startActivity(intent)
    }

    fun setStatusBar(view: View?) {
        if (view == null) {
            return
        }

    }


    /**
     * toast
     *
     * @param msg
     */
    fun showtoast(msg: String) {
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
    }

    /**
           * Show loading animation
     */
    fun showLoadingDialog() {
        if (dialog != null && dialog!!.isShowing) {
            return
        }
        if (null == dialog) {
            dialog = ProgressDialog(context, R.style.AlertDialogStyle)
        }
        dialog!!.setCancelable(false)
        dialog!!.show()

    }

    /**
           * Hidden loading animation
     */
    fun closeLoadingDialog() {
        if (dialog != null && dialog!!.isShowing) {
            dialog!!.dismiss()
        }
    }

    /**
           * Get View by resource RES
     *
     * @param res
     * @return
     */
    fun getViewByRes(@LayoutRes res: Int): View {
        return LayoutInflater.from(context).inflate(res, null)
    }


    /**
           * Get text for textView
     *
     * @param tv
     * @return
     */
    fun getTV(tv: TextView?): String {
        return tv?.text?.toString()?.trim { it <= ' ' } ?: ""
    }


    private fun showFileDialog() {}

    private fun hideFileDialog() {}


    override fun hideLoading() {
        closeLoadingDialog()
    }

    override fun showError(msg: String) {
        showtoast(msg)
    }

    override fun onErrorCode(model: BaseResult<Any>) {
        when {
            model.errorCode < 0.toString() -> showtoast(model.errorMsg!!)
        }
    }

    override fun showLoadingFileDialog() {
        showFileDialog()
    }

    override fun hideLoadingFileDialog() {
        hideFileDialog()
    }

    override fun onProgress(totalSize: Long, downSize: Long) {}

}

4. The BaseObserver code is as follows:

/**
   * @ Author: njb
   * @  : 2020/12/3 17:29
   * @ Description:
 */
abstract class BaseObserver <T> : DisposableObserver<T?>{
    private var view: BaseView?
    private var isShowDialog = false

    constructor(view: BaseView?) {
        this.view = view
    }

    constructor(view: BaseView?, isShowDialog: Boolean) {
        this.view = view
        this.isShowDialog = isShowDialog
    }

    override fun onStart() {
        if (isShowDialog) {
            view!!.showLoading()
        }
    }

    override fun onNext(o: T) {
        onSuccess(o)
    }

    override fun onError(e: Throwable) {
        if (isShowDialog) {
            view!!.hideLoading()
        }
        val be: BaseException
                 Onerror ("Error")
    }

    override fun onComplete() {
        if (isShowDialog) {
            view!!.hideLoading()
        }
    }

    abstract fun onSuccess(o: T)
    abstract fun onError(msg: String?)
}

5.BaseView code is as follows:

/**
 * @ Author: njb
   * @  : 2020/12/3 15:36
   * @ Description:
 */
interface BaseView {
    /**
           * Show Dialog
     */
    fun showLoading()

    /**
           * Display download file Dialog
     */

    fun showLoadingFileDialog()

    /**
           * Hide Download Document Dialog
     */

    fun hideLoadingFileDialog()

    /**
           * Download progress
     * @param totalSize
     * @param downSize
     */

    fun onProgress(totalSize: Long, downSize: Long)

    /**
           * Hide Dialog
     */

    fun hideLoading()

    /**
           * Display error message
     * @param msg
     */
    fun showError(msg: String)

    /**
           * error code 
     */
    fun onErrorCode(baseResult: BaseResult<Any>)
}

6.Apiretrofit code as follows:

/**
   * Author: njb
   * Time: 2016/12 / 27.13: 56
   * Description:
   * Source:
 */
class ApiRetrofit {
    private val retrofit: Retrofit
    private val client: OkHttpClient
    val apiService: ApiServer
    private val TAG = "ApiRetrofit"

    /**
           * Request to access Quest
           * Response interceptor
     */
    private val interceptor = Interceptor { chain ->
        val request = chain.request()
        val startTime = System.currentTimeMillis()
        val response = chain.proceed(chain.request())
        val endTime = System.currentTimeMillis()
        val duration = endTime - startTime
        val mediaType = response.body!!.contentType()
        val content = response.body!!.string()
        Log.e(TAG, "| Response:$content")
        response.newBuilder()
                .body(ResponseBody.create(mediaType, content))
                .build()
    }
    private val headInterceptor = Interceptor { chain ->
        var request = chain.request()

                 // Get the method
        val method = request.method
        if (method == "GET") {
            val httpUrlurl = request.url
            val url = httpUrlurl.toString()
            val index = url.indexOf("?")
            if (index > 0) {
                //url = url + "&APP_KEY=" + AppConstant.APP_KEY;
            } else {
                                 // URL = URL + "? APP_KEY =" + AppConstant.app_key; // Splicing new URL
            }
                         Request = Request.newbuilder (). URL (URL) .build () // Re-build request
        } else if (method == "POST") {
            val requestBuilder = request.newBuilder()

                         // Request to be customized: Unified Add token parameters
            if (request.body!!.contentLength() == 0L) {
                                 // No parameters
                val newFormBody = FormBody.Builder()
                requestBuilder.method(request.method, newFormBody.build())
            } else if (request.body is FormBody) {
                                 // Normal POST
                val newFormBody = FormBody.Builder()
                val oidFormBody = request.body as FormBody?
                for (i in 0 until oidFormBody!!.size) {
                    newFormBody.addEncoded(oidFormBody.encodedName(i), oidFormBody.encodedValue(i))
                }
                requestBuilder.method(request.method, newFormBody.build())
            }
            request = requestBuilder.build()
        }
        chain.proceed(request)
    }

    companion object {
        private var apiRetrofit: ApiRetrofit? = null

        @JvmStatic
        val instance: ApiRetrofit?
            get() {
                if (apiRetrofit == null) {
                    synchronized(Any::class.java) {
                        if (apiRetrofit == null) {
                            apiRetrofit = ApiRetrofit()
                        }
                    }
                }
                return apiRetrofit
            }
    }

    init {
                 Client = okhttpclient.builder () // Add log interceptor
                .addInterceptor(interceptor)
                .addInterceptor(headInterceptor)
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS) //                .sslSocketFactory()
                .build()
        retrofit = Retrofit.Builder()
                .baseUrl(Constant.BASE_SERVER_URL)
                .addConverterFactory(GsonConverterFactory.create())
                                 .addConvertory (SCALARSCONVERTERFAACTORY ()) // supports RXJAVA2
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build()
        apiService = retrofit.create(ApiServer::class.java)
    }
}

7.ApiServer: Here is WANANDROIDAPI as an example

interface ApiServer {
         // Home Article list
    @GET("/article/list/{page}/json")
    fun articleList(@Path("page") page:Int) : Observable<BaseResult<ArticleListBean>>

    @GET("/article/list/{page}/json")
    fun articleLists(@Path("page") page:Int) : Call<List<ArticleListBean>>

         // Home Advertising
    @GET("/banner/json")
    fun banner():Observable<BaseListResult<BannerBean>>

         // Search hot words
    @GET("/hotkey/json")
    fun hotkey(): Observable<BaseListResult<HotkeyBean>>

         // System interface
    @GET("/tree/json")
    fun tree(): Observable<BaseListResult<KnowledgeBean.DataBean>>

         // article under the knowledge system
    @GET("article/list/{page}/json")
    fun article(@Path("page") page: Int,@Query("cid") cid: Int): Observable<BaseResult<ArticleListBean>>

         // Navigation
    @GET("/navi/json")
    fun navi():Observable<BaseListResult<NavigationBean.DataBean>>

         //category 
    @GET("/project/tree/json")
    fun projectTree(): Observable<BaseListResult<ProjectTitleBean.DataBean>>

         // list under project classification
    @GET("/project/list/{page}/json")
    fun projectList(@Path("page") page: Int,@Query("cid") cid:Int): Observable<BaseBean<ProjectListBean>>

         //log in 
    @POST("/user/login")
    @FormUrlEncoded
    fun login(@Field("username") username: String, @Field("password") password:String):Observable<BaseBean<LoginBean>>

         // Register
    @POST("/user/register")
    @FormUrlEncoded
    fun register(@Field("username") username: String, @Field("password") password: String, @Field("repassword") repassword: String) : Observable<BaseBean<RegisterBean>>

         // Collect articles list
    @GET("/lg/collect/list/0/json")
    fun collect():Observable<BaseBean<*>>

         // Collection of articles
    @POST("/lg/collect/1165/json")
    @FormUrlEncoded
    fun collectLg(@Path("id") id:Int):Observable<BaseBean<*>>

         / / Collection of external articles
    @POST("/lg/collect/add/json")
    @FormUrlEncoded()
    fun collectadd():Observable<BaseBean<*>>

         // Remove
    @POST("/lg/uncollect_originId/2333/json")
    @FormUrlEncoded
    fun uncollect(@Path("id") id:Int):Observable<BaseBean<*>>

         //my collection 
    @POST("/lg/uncollect/2805/json")
    @FormUrlEncoded
    fun mycollect(@Path("id") id: Int,@Path("orignId") orignId:Int ) :Observable<BaseBean<*>>

         / / Collection website list
    @GET("/lg/collect/usertools/json")
    fun usertools():Observable<BaseBean<*>>


         // Collection website
    @POST("/lg/collect/addtool/json")
    @FormUrlEncoded
    fun addcollect(@Path("name") name: Int,@Path("link") link: Int):Observable<BaseBean<*>>

         // Edit Collection Website
    @POST("/lg/collect/updatetool/json")
    @FormUrlEncoded
    fun updatetool(@Path("id") id: Int,@Path("name") name:Int,@Path("link") liml:Int):Observable<BaseBean<*>>

         // Delete the collection website
    @POST("/lg/collect/deletetool/json")
    @FormUrlEncoded
    fun deletetool(@Path("id") id: Int):Observable<BaseBean<*>>

         //search for 
    @POST("/article/query/{page}/json")
    @FormUrlEncoded
    fun query(@Path("page") page: Int, @Field("k") k:String):Observable<BaseBean<SearchBean>>

         // Add a TODO
    @POST("/lg/todo/add/json")
    @FormUrlEncoded
    fun add(@Path("title") title:Int,@Path("content") content:Int,@Path("date") date:Int,@Path("type") type: Int):Observable<BaseBean<*>>

         / / Update a TODO content
    @POST("/lg/todo/update/83/json")
    @FormUrlEncoded
    fun update(@Path("id") id: Int,@Path("title") title: Int,@Path("content") content: Int,@Path("date") date: Int,
               @Path("status") status: Int,@Path("type") type: Int):Observable<BaseResult<*>>

         / / Delete a TODO
    @POST("/lg/todo/delete/83/json")
    @FormUrlEncoded
    fun delete(@Path("id") id: Int, @Path("status") status: Int):Observable<BaseResult<*>>

         // Unfinished TODO list
    @POST("/lg/todo/listnotdo/")
    @FormUrlEncoded
    fun listnotdo(@Path("type") type: Int,@Path("page")page: Int):Observable<BaseResult<*>>

         / / Toto list
    @POST("/lg/todo/listdone/")
    @FormUrlEncoded
    fun listdone(@Path("type") type:Int,@Path("page") page:Int):Observable<BaseResult<*>>

         // only update the completion status Todo
    @POST("/lg/todo/done/80/json")
    @FormUrlEncoded
    fun done(@Path("id") id:Int):Observable<BaseResult<*>>
}

8. Create a View inherited in BaseVew, then create a Presether Inherited in BasePresenter, then inherited in the Activity in BaseActivity, if Fragment is inherited in BaseFragment, the specific implementation code is as follows:

(1) ATRICLISTVIEW: Article list View

/**
   * @ Author: njb
   * @  : 2020/12/3 17:50
   * @ Description:
 */
interface ArticleListView : BaseView {
    fun onLoadArtList(date: ArticleListBean)
    fun onLoadFriend(date: HotkeyBean)
}

(2) HomePresenter: Article list Presener

/**
   * @ Author: njb
   * @  : 2020/12/3 17:48
   * @ Description:
 */
class HomePresenter(baseView: ArticleListView) : BasePresenter<ArticleListView>(baseView) {
    /**
           * Article list 
     */
    fun articleList( page: Int) {
        addDisposable(apiServer.articleList(page),object :BaseObserver<BaseResult<ArticleListBean>>(baseView){
            override fun onSuccess(o: BaseResult<ArticleListBean>) {
                baseView!!.onLoadArtList(o.data!!)
            }

            override fun onError(msg: String?) {
                baseView!!.showError(msg!!)
            }

        })

    }
}

(3) ACTIVITY code:

Use Presener !!. Articles, ArticleList (1) initiating a request, here you only need to pass the parameters, you can see that the network request operation has been put in the PresermTer, and Activity does not make requests and logic operations, just responsible for initiating the request and then according to according to according to according to Returns the result to display the data to do appropriate processing, etc.

class MainActivity : BaseActivity<HomePresenter>(), (ArticleListView) {

    override val layoutId: Int
        get() = R.layout.activity_main

    override fun createPresenter(): HomePresenter {
        return HomePresenter(this)
    }

    override fun initView() {
        presenter!!.articleList(1)
    }

    override fun addListener() {
        startA(HomeActivity::class.java)
    }

    override fun onLoadArtList(date: ArticleListBean) {
        Log.d("--data--", date.datas.toString())
    }

    override fun onLoadFriend(date: HotkeyBean) {
    }

    override fun showLoading() {

    }

    override fun hideLoading() {
    }

}

(4) Article list entity class: ArticlelistBean

class ArticleListBean {
    var datas: MutableList<DatasBean>? = null
    class DatasBean {
        /**
         * apkLink :
         * author : Jetictors
         * chapterId : 232
                   * ChapterName: Getting Started and Knowledge Point
         * collect : false
         * courseId : 13
         * desc :
         * envelopePic :
         * fresh : true
         * id : 3226
         * link : http://www.cnblogs.com/Jetictors/tag/Kotlin/
                   * nicedate: 4 hours ago
         * origin :
         * projectLink :
         * publishTime : 1533522956000
         * superChapterId : 232
         * superChapterName : Kotlin
         * tags : []
                   * Title: Kotlin series articles
         * type : 0
         * userId : -1
         * visible : 1
         * zan : 0
         */

        Var APKLINK: STRING? = null // article URI
        var author: String? = null          //
        var chapterId: Int = 0              //
        var chapterName: String? = null
        var isCollect: Boolean = false
        var courseId: Int = 0
        var desc: String? = null
        var envelopePic: String? = null
        var isFresh: Boolean = false
        var id: Int = 0
        var link: String? = null
        var niceDate: String? = null
        var origin: String? = null
        var projectLink: String? = null
        var publishTime: Long = 0
        var superChapterId: Int = 0
        var superChapterName: String? = null
        var title: String? = null
        var type: Int = 0
        var userId: Int = 0
        var visible: Int = 0
        var zan: Int = 0
        var tags: List<*>? = null
        var isSelect: Boolean  = false
    }
}

9. The request results are as follows: You can see the interface data successfully obtained by the following screenshots.

10. So far, Kotlin + Retrofit + RXJAVA + MVP's simple package network request has been completed, the next article summarizes the simple use and encapsulation of Kotlin + Retrofit + RXJAVA + MVVM, followed by JetPack implementation. Welcome friends They came to beat, if there is a problem, I will correct it in time.

 

Intelligent Recommendation

Android build MVP+Retrofit+RxJava network request framework (1)

Previously, the company's project used the MVP+Retrofit+RxJava framework for network requests, so I am writing an article today to summarize. I believe many people have heard of MVP, Retrofit, and RxJ...

Android MVP framework+RxJava+Retrofit+cecycleView, request network data and load

These days, I often use the MVP framework to write projects. Today, I will use the MVP framework for everyone. RxJava+Retrofit requests network data, and recycleView loads, and Fresco images load. MVP...

Android uses MVP to implement network loading data

1. Network loading interface Second.view layer Three.Model layer (processing data, here is the network encapsulation class) 4. Presenter layer Five. In the Activity layer...

Android development model RxJava+Retrofit+MVP (kotlin)

  It is divided into two parts. The first part is the use of RxJava+Retrofit network request, and the other part is MVP mode combined with network request. First, the use of RxJava+Retrofit Intro...

Use Kotlin+RXJAVA+RETROFIT to make an ultra -simple package on the network request

Dependent configuration kotlin version Implementation         In order to make the code in Activity and Fragment simple, and reduce the code invasion caused by business or data acc...

More Recommendation

Retrofit+okhttp+rxjava+MVP for network request

Pilot dependence Then the retrofit tool class Followed by the address class Api Then the interface of the stitched address Followed by MVP M layer First write an M layer interface IModel. Here are som...

Retrofit+RXJAVA+MVP Network Request Framework

First write a tool class: @GET Observable get(@Url String url); Network Request Encapsulation: MVP framework; Write three interfaces: IModel void get(String url,Class aClass,NewCallBack newCallBack); ...

Retrofit + Rxjava + MVP network request frame

preface: before jacketed request based MVP of the network frame, is okhttp package, due later retrofit, rxJava popular, it is used to change a part of Interpretation: retrofit: a request frame again o...

Retrofit+Rxjava+MVP encapsulated network request framework

Dependency required by network request Model interface includes two methods that can be implemented Model class to start processing data An entity class of Presenter can be inherited Presenter is resp...

Copyright  DMCA © 2018-2026 - All Rights Reserved - www.programmersought.com  User Notice

Top