android中MVP模式

作者: wervy | 来源:发表于2019-12-27 14:38 被阅读0次

    我们之前在项目中都是MVC模式,网络请求和展示数据都是在Activity页面上,比如像:

    /**
     * Created by sww on 16/6/16.
     */
    public class AudioActivity extends FragmentActivity implements View.OnClickListener {
    
        private RecyclerView rvAudio;
    
        private String isbn;
        private String bookName;
        private String officialAudioUrl;
        private String bookImgUrl;
        private int recordPageNo = 1;
        private int sortType = 0;
        private boolean isFirstTime = true;
        private AudioAdapter audioAdapter;
        private LoadMoreRecyclerViewAdapter audioLoadMoreRecyclerViewAdapter;
    
        private static final int PAGE_SIZE = 10;
        private ArrayList<UserAudio> userAudioArrayList = new ArrayList<UserAudio>();
        public static final String ISBN = "isbn";
        public static final String BOOK_NAME = "book_name";
        public static final String OFFICIAL_AUDIO_URL = "official_audio_url";
        public static final String BOOK_IMG_URL = "book_img_url";
    
        private static final String GET_AUDIO_URL = "taleteling/get-list";
        private static final String ADD_AUDIO_PLAY_COUNT = "taleteling/play";
        private static final String AUDIO_LIKE_URL = "taleteling/like";
        private static final String TAG = "AudioActivity";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_audio);
            isbn = getIntent().getStringExtra(ISBN);
            bookName = getIntent().getStringExtra(BOOK_NAME);
            officialAudioUrl = getIntent().getStringExtra(OFFICIAL_AUDIO_URL);
            bookImgUrl = getIntent().getStringExtra(BOOK_IMG_URL);
            initView();
            getRecordData(AudioActivity.this, sortType, false);
        }
    
        private void initView() {
            RelativeLayout rlAudioTitle = (RelativeLayout) findViewById(R.id.rl_audio_title);
            rlAudioTitle.setOnClickListener(this);
            ImageButton backImg = (ImageButton) findViewById(R.id.btn_back);
            backImg.setOnClickListener(this);
            ImageView recordImg = (ImageView) findViewById(R.id.record_img);
            recordImg.setOnClickListener(this);
            rvAudio = (RecyclerView) findViewById(R.id.rv_audio);
            rvAudio.setLayoutManager(new LinearLayoutManager(this));
    
            initRecyclerView(rvAudio);
    
            audioAdapter.setOnChangeDataListener(new AudioAdapter.OnChangeDataListener() {
                @Override
                public void onChangeData(int sortType) {
                    changeDataSource(sortType);
                }
    
                @Override
                public void onAddAudioPlayCount(int audioNo) {
                    addAudioPlayCount(AudioActivity.this, audioNo);
                }
    
                @Override
                public void onLikeAudio(UserAudio userAudio, int position) {
                    audioLike(AudioActivity.this, userAudio, position);
                }
            });
        }
    
        private void initRecyclerView(RecyclerView recyclerView) {
            LinearLayoutManager layoutManager = new LinearLayoutManager(this);
            layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
            recyclerView.setLayoutManager(layoutManager);
            recyclerView.setHasFixedSize(true);
            audioAdapter = new AudioAdapter(AudioActivity.this, officialAudioUrl, bookImgUrl, userAudioArrayList, true);
            audioLoadMoreRecyclerViewAdapter = new LoadMoreRecyclerViewAdapter(this, audioAdapter,
                    new LoadMoreRecyclerViewAdapter.RequestToLoadMoreListener() {
                        @Override
                        public void onAfterLoadMoreRequested() {
                            if (isFirstTime) {
                                isFirstTime = false;
                            } else {
                                Utils.TLog(TAG, "audio onAfterLoadMoreRequested");
                                getRecordData(AudioActivity.this, sortType, true);
                            }
                        }
    
                        @Override
                        public void onBeforeLoadMoreRequested() {
    
                        }
                    });
            recyclerView.setAdapter(audioLoadMoreRecyclerViewAdapter);
        }
    
        private void changeDataSource(int sortType) {
            this.sortType = sortType;
            getRecordData(AudioActivity.this, sortType, false);
        }
    
        private void getRecordData(final Context context, int sortType, final boolean getMore) {
            String currentTime = String.valueOf(Utils.getCurrentTimeMillis());
            HashMap<String, String> hashMap = new HashMap<String, String>();
            hashMap.put("time", currentTime);
            hashMap.put("ISBN", isbn);
            hashMap.put("SortType", String.valueOf(sortType));
            recordPageNo = getMore ? recordPageNo + 1 : 1;
            hashMap.put("PageIndex", String.valueOf(recordPageNo));
            hashMap.put("PageSize", String.valueOf(PAGE_SIZE));
            com.google.gson.JsonObject jsonObject = RequestUtil.generateRequestJson(hashMap);
            List<NameValuePair> nameValuePairs = RequestUtil.generateRequestNameValuePair(hashMap);
    
            ApiClient.postBusinessWithToken(context, GET_AUDIO_URL, nameValuePairs, jsonObject, currentTime, new TextHttpResponseHandler() {
    
                @Override
                public void onSuccess(int statusCode, Header[] headers, String responseString) {
                    Utils.TLog(TAG + "---getRecordData---", responseString);
                    try {
                        JSONObject response = new JSONObject(responseString);
                        String responseCode = response.getString(RequestUtil.RESPONSE_CODE);
                        String message = response.getString(RequestUtil.RESPONSE_MESSAGE);
                        if (responseCode.equals(RequestUtil.RESPONSE_CORRECT_CODE)) {
                            if (!getMore) {
                                userAudioArrayList.clear();
                            }
                            if (!response.getString(RequestUtil.RESPONSE_RESULT).equals(RequestUtil.RESPONSE_RESULT_NULL)) {
                                JSONObject jsonObject = response.getJSONObject(RequestUtil.RESPONSE_RESULT);
                                parseAudioJson(jsonObject);
                                audioAdapter.notifyDataSetChanged();
                                JSONArray jsonArray = jsonObject.getJSONArray("TValues");
                                audioLoadMoreRecyclerViewAdapter.onDataReadyAfter(jsonArray.length() >= PAGE_SIZE);
                            } else {
                                audioLoadMoreRecyclerViewAdapter.onDataReadyAfter(false);
                            }
                        } else {
                            Utils.ToastError(context, message);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
    
                @Override
                public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
                    Utils.TLog(TAG, responseString);
                    audioLoadMoreRecyclerViewAdapter.onDataReadyAfter(false);
                }
            });
        }
    
        private void parseAudioJson(JSONObject jsonObject) {
            try {
                JSONArray jsonArray = jsonObject.getJSONArray("TValues");
                int length = jsonArray.length();
                for (int i = 0; i < length; i++) {
                    UserAudio userAudio = new UserAudio();
                    JSONObject userAudioJson = jsonArray.getJSONObject(i);
                    userAudio.setUserAudioNo(userAudioJson.optInt("SysNo"));
                    userAudio.setPlayCount(userAudioJson.optInt("PlayCount"));
                    userAudio.setLikeCount(userAudioJson.optInt("LikeCount"));
                    userAudio.setIsLiked(userAudioJson.optBoolean("Liked"));
                    userAudio.setRank(userAudioJson.optInt("Ranking"));
                    userAudio.setUserNickName(userAudioJson.optString("UserNickName"));
                    userAudio.setISBN(userAudioJson.optString("BookISBN"));
                    userAudio.setBookName(userAudioJson.optString("BookName"));
                    userAudio.setUserHeadPicUrl(userAudioJson.optString("UserPortrait"));
                    userAudio.setIsSelfAudio(userAudioJson.optBoolean("SelfFlag"));
                    userAudio.setBookImgUrl(userAudioJson.optString("BookFrontCover"));
                    userAudio.setAudioTitle(userAudioJson.optString("Title"));
                    userAudio.setAudioDes(userAudioJson.optString("Description"));
                    userAudio.setAudioCreateDate(userAudioJson.optLong("CreateDate"));
                    userAudio.setAudioTime(userAudioJson.optInt("RecordingDate"));
                    userAudio.setAudioTime(userAudioJson.optInt("RecordingDate"));
                    List<String> audioList = new ArrayList<String>();
                    JSONArray audioArray = userAudioJson.getJSONArray("AudioList");
                    int audioLength = audioArray.length();
                    for (int j = 0; j < audioLength; j++) {
                        audioList.add(audioArray.optString(j));
                    }
                    userAudio.setAudioUrlList(audioList);
                    userAudioArrayList.add(userAudio);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    
        private void addAudioPlayCount(final Context context, int audioNo) {
            String currentTime = String.valueOf(Utils.getCurrentTimeMillis());
            HashMap<String, String> hashMap = new HashMap<String, String>();
            hashMap.put("time", currentTime);
            hashMap.put("SysNo", String.valueOf(audioNo));
            com.google.gson.JsonObject jsonObject = RequestUtil.generateRequestJson(hashMap);
            List<NameValuePair> nameValuePairs = RequestUtil.generateRequestNameValuePair(hashMap);
    
            ApiClient.postBusinessWithToken(context, ADD_AUDIO_PLAY_COUNT, nameValuePairs, jsonObject, currentTime, new TextHttpResponseHandler() {
    
                @Override
                public void onSuccess(int statusCode, Header[] headers, String responseString) {
                    //增加播放次数的请求不处理返回结果
                }
    
                @Override
                public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
                    Utils.TLog(TAG, responseString);
                }
            });
        }
    
        private void audioLike(final Context context, final UserAudio userAudio, final int position) {
            String currentTime = String.valueOf(Utils.getCurrentTimeMillis());
            HashMap<String, String> hashMap = new HashMap<String, String>();
            hashMap.put("time", currentTime);
            hashMap.put("SysNo", String.valueOf(userAudio.getUserAudioNo()));
            com.google.gson.JsonObject jsonObject = RequestUtil.generateRequestJson(hashMap);
            List<NameValuePair> nameValuePairs = RequestUtil.generateRequestNameValuePair(hashMap);
    
            ApiClient.postBusinessWithToken(context, AUDIO_LIKE_URL, nameValuePairs, jsonObject, currentTime, new TextHttpResponseHandler() {
    
                @Override
                public void onSuccess(int statusCode, Header[] headers, String responseString) {
                    try {
                        JSONObject response = new JSONObject(responseString);
                        String responseCode = response.getString(RequestUtil.RESPONSE_CODE);
                        if (responseCode.equals(RequestUtil.RESPONSE_CORRECT_CODE)) {
                            if (response.getString(RequestUtil.RESPONSE_RESULT).equals(RequestUtil.RESPONSE_RESULT_TRUE)) {
                                Utils.ToastSuccess(AudioActivity.this, "点赞成功");
                                userAudio.setIsLiked(true);
                                int likeCount = userAudio.getLikeCount();
                                userAudio.setLikeCount(likeCount + 1);
                                audioAdapter.notifyItemChanged(position);
                            }
                        } else {
                            String message = response.getString(RequestUtil.RESPONSE_MESSAGE);
                            Utils.ToastError(AudioActivity.this, message);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
    
                @Override
                public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
                    Utils.TLog(TAG, responseString);
                }
            });
        }
    
        private void startBookRecord() {
            Intent intent = new Intent();
            intent.putExtra(RecordActivity.BOOKISBN, isbn);
            intent.putExtra(RecordActivity.BOOKNAME, bookName);
            intent.putExtra(RecordActivity.BOOKPICURL, bookImgUrl);
            intent.setClass(this, RecordActivity.class);
            startActivity(intent);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            audioAdapter.audioPlayer.stop();
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_back:
                    finish();
                    break;
                case R.id.record_img:
                    startBookRecord();
                    break;
                case R.id.rl_audio_title:
                    rvAudio.smoothScrollToPosition(0);
                    break;
                default:
                    break;
            }
        }
    }
    
    

    这样显得Activity代码特别多,看起来很头痛,维护起来很麻烦

    为什么在项目使用MVP模式,当然是它有很多优点

    1 代码层次分明

    2 view和Model分开,便于维护

    使用MVP模式,代码结构如下:


    image.png

    先封装几个Base类

    BaseView
    public interface BaseView {
    
        /**
         * UI 业务逻辑,加载Loading
         */
        void showLoading();
        void hideLoading();
    }
    
    
    BasePersenter
    /**
     * T 对应着Activity的UI抽象接口 视图
     * @param <V>
     */
    public abstract class BasePersenter<V> {
    
        protected WeakReference<V> mViewRef; //iew持有activity的引用,防止内存泄漏,使用弱引用
    
        public abstract void fectch();
    
        public void attachView(V view){
            mViewRef = new WeakReference<>(view);
            Log.i("++++++++-------attach","" + mViewRef.get());
        }
    
        /**
         * 解绑
         */
        public void detach(){
            Log.i("++++++++-------detach","" + mViewRef.get());
            if (mViewRef != null){
                mViewRef.clear();
                mViewRef = null;
            }
        }
    }
    
    
    BaseActivity
    
    public abstract class BaseActivity<V, T extends BasePersenter<V>> extends AppCompatActivity {
    
        protected T mPresent;
        protected FontIconView backIcon;
    
        public enum Status {
            NAVIGATION, STATUS, Default
        }
    
        @Override
        protected void onCreate( Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.i("-------","-------onCreate");
            backIcon = (FontIconView) findViewById(R.id.back_font);
            mPresent = createPresent();
            mPresent.attachView((V) this);
    //        setStatusBar(getStatusBarColor());
            if (backIcon != null) {
                backIcon.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        onBackPressed();
                    }
                });
            }
        }
        /**
         * Android 6.0 以上设置状态栏颜色
         */
        protected void setStatusBar(@ColorInt int color) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    
                // 设置状态栏底色颜色
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
                getWindow().setStatusBarColor(color);
    
                // 如果亮色,设置状态栏文字为黑色
                if (isLightColor(color)) {
                    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                } else {
                    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
                }
            }
    
        }
    
        /**
         * 判断颜色是不是亮色
         *
         * @param color
         * @return
         */
        private boolean isLightColor(@ColorInt int color) {
            return ColorUtils.calculateLuminance(color) >= 0.5;
        }
    
        /**
         * 获取StatusBar颜色,默认白色
         *
         * @return
         */
        protected @ColorInt
        int getStatusBarColor() {
            return getResources().getColor(R.color.white);
        }
    
    
        protected abstract T createPresent();
    }
    

    一个模块中View层代码

    interface DcOrderListView {
        fun success(list: List<DcOrderListBean>)
        fun fail(result: String)
    }
    

    一个模块中Model层代码

    interface IDcActivityListListener<T> {
    
    
        fun  success(t:T)
        fun fail(result:String)
    }
    
    interface IDcActivityList<T> {
    
        fun loadListData(context: Context, paramsUtil: RequestBody, listener: IDcActivityListListener<T>)
    
    
    }
    
    Model层的实现类
    class DcOrderListImpl:IDcActivityList<List<DcOrderListBean>> {
    
    
    
        override fun loadListData(context: Context, paramsUtil: RequestBody, listener: IDcActivityListListener<List<DcOrderListBean>>) {
    
            DcApiLoader(context).agentCoreServiceFind(paramsUtil,object :Observer<CommonBean<List<DcOrderListBean>>>{
                override fun onComplete() {
                }
    
                override fun onSubscribe(d: Disposable) {
                }
    
                override fun onNext(t: CommonBean<List<DcOrderListBean>>) {
    
                    if (ActivityConstant.BLYA_SUCCESS_CODE.equals(t.code)){
                        listener.success(t.data)
                    }else {
                        listener.fail(t.message)
                    }
    
                }
    
                override fun onError(e: Throwable) {
    
                    listener.fail("系统异常")
                }
    
            })
    
        }
    }
    

    P层代码

    class DcOrderListPresenter(dcOrderListView: DcOrderListView): BasePersenter<DcOrderListView>() {
    
        var viewModel = DcOrderListImpl()
        var dcOrderListView = dcOrderListView
    
        override fun fectch() {
            TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        }
    
        fun loadData(context: Context, param: RequestBody){
            viewModel.loadListData(context,param,object : IDcActivityListListener<List<DcOrderListBean>>{
                override fun success(t: List<DcOrderListBean>) {
    
                    dcOrderListView.success(t)
                }
    
                override fun fail(result: String) {
    
                    dcOrderListView.fail(result)
    
                }
    
            })
        }
    
    
    }
    
    Activity的代码,就简介多了
    class MyDcActivity : BaseActivity<DcOrderListView,DcOrderListPresenter>(),DcOrderListView {
    
        private lateinit var titleText:TextView
        private lateinit var recyclerView: RecyclerView
        private lateinit var dcOrderListPresenter: DcOrderListPresenter
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_my_dc)
            initView()
        }
    
        private fun initView(){
    
            titleText = findViewById(R.id.title_text) as TextView
            recyclerView = findViewById(R.id.recycleView) as RecyclerView
            titleText.text = "我的代采"
    
        }
    
         @RequiresApi(Build.VERSION_CODES.KITKAT)
        private fun initData(){
    
            var map = ArrayMap<String,String>()
            map["page"] = "1"
            map["limit"] = "10"
    
            var util = NetParamsUtil(map)
            presenter.agentFind(this,util.param())
    
        }
    
        override fun createPresent(): DcOrderListPresenter {
    
            dcOrderListPresenter = DcOrderListPresenter(this)
            return dcOrderListPresenter
        }
    
        override fun success(list: List<DcOrderListBean>) {
    
    
        }
    
        override fun fail(result: String) {
    
    
        }
    
    
    }
    

    相关文章

      网友评论

        本文标题:android中MVP模式

        本文链接:https://www.haomeiwen.com/subject/vehdoctx.html