MVP的简单封装
MVP框架的耦合性很低,应用于大型项目时条例清晰,方便单元测试 6666
整理下自己写的一个简单的MVP+Rxjava+retrofit的框架
M层请求数据 P层为M与V传递信息类似于中介 V层处理逻辑代码
各种依赖
compile 'com.squareup.retrofit2:retrofit:2.3.0'
// Json依赖(根据需要选择)
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
// 字符串依赖(根据需要选择)
compile 'com.squareup.retrofit2:converter-scalars:2.3.0'
// RxJava2支持(根据需要选择)
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
compile 'io.reactivex.rxjava2:rxjava:2.0.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
首先先写一个Constant类 保存一些 常用且不变的的属性与一些常用的小工具提高代码的复用性
public class Constant {
public static String SYSTEM_SHARE_NAME="config";
//这是我自己本机的一个服务器的接口
public static final String LINK_MAIN = "http://169.254.157.229/mobile/";
public static SharedPreferences mSharedPreferences;
public static SharedPreferences.Editor mSharedPreferencesEditor;
public static Gson gson;
//初始化
public static void init(Context context) {
mSharedPreferences = context.getSharedPreferences(Constant.SYSTEM_SHARE_NAME, Activity.MODE_PRIVATE);
mSharedPreferencesEditor = mSharedPreferences.edit();
gson=new Gson();
}
//gson封装
public static <T> T GsonToBean(String gsonString, Class<T> cls) {
T t = null;
if (gson != null) {
t = gson.fromJson(gsonString, cls);
}
return t;
}
}
然后就可以写网络请求了 这里我是用的Rxjava+Retrofit结合的网络框架
首先 先把retrofit需要用到的API接口类写出来
就是简单的一个get 与一个简单的post
public interface Api {
@GET("index.php")
Observable<String> getTest(@QueryMap Map<String,String> map);
@FormUrlEncoded
@POST("index.php")
Observable<String> postTest(@FieldMap Map<String,String> map);
}
之后将Httputil类写出
public class HttpUtil {
private static Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.LINK_MAIN)
.addConverterFactory(ScalarsConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
//get封装
public static void get(Observer<String> observer, Map<String,String> map){
Api api = retrofit.create(Api.class);
Observable<String> observable = api.getTest(map);
observable.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(observer);
}
//post封装
public static void post(Observer<String> observer, Map<String,String> map){
Api api = retrofit.create(Api.class);
Observable<String> observable = api.postTest(map);
observable.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(observer);
}
}
返回类型这里我用的String
之后会在Prenter层里面进行转换Bean
这样Api接口与Httputil类就可以少些很多很多
在Presenter层中封装一个BasePresenter来抽出一些公共的Present方法
public class BasePresenter<T extends IBaseView>{
private T t;
//关联activity
public void attach(T t){
this.t=t;
}
public IBaseView getiBaseView() {
return t;
}
//取消关联activity
public void detach(){
if(this.t!=null){
t=null;
}
}
}
presenter层中利用rxjava接收到网络请求的数据 然后用Gson类将Json转换为Bean
最后将转换完成的Bean回调到Activity
public class TestPreseneter extends BasePresenter<IBaseView<ClassBean>>{
public <T>void get(Map<String,String> map, final Class<T> cla) {
HttpUtil.get(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String value) {
Log.e("json", value );
T t = Constant.GsonToBean(value, cla);
getiBaseView().onData(t);
}
@Override
public void onError(Throwable e) {
getiBaseView().onError(e);
}
@Override
public void onComplete() {
}
}, map);
}
}
activity接收数据
这里我的activity继承的是我自己cv的一个Baseactivity :)
public class MainActivity extends BaseAvtivity implements IBaseView<ClassBean> {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void initUI() {
}
@Override
protected void initData() {
TestPreseneter t=new TestPreseneter();
t.attach(this);
HashMap<String, String> m = new HashMap<>();
m.put("act","goods_class");
m.put("op","goods_detail");
m.put("gc_id","4");
t.get(m,ClassBean.class);
}
@Override
protected void initListener() {
}
@Override
public void onData(ClassBean classBean) {
showShort(classBean.getCode()+"");
}
@Override
public void onError(Throwable throwable) {
Log.e("onerror", throwable.toString() );
}
}
public abstract class BaseAvtivity extends AppCompatActivity{
/** 用来保存所有已打开的Activity */
private static Stack<Activity> listActivity = new Stack<Activity>();
/** 提示信息 **/
private Toast mToast;
/** 记录上次点击按钮的时间 **/
private long lastClickTime;
/** 按钮连续点击最低间隔时间 单位:毫秒 **/
public final static int CLICK_TIME = 500;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置activity为无标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 将activity推入栈中
listActivity.push(this);
// 初始化ui
initUI();
// 初始化数据
initData();
// 事件监听
initListener();
}
/** 初始化ui **/
protected abstract void initUI();
/** 初始化数据 **/
protected abstract void initData();
/** 初始化监听 **/
protected abstract void initListener();
@Override
protected void onSaveInstanceState(Bundle outState) {
saveInstanceState(outState);
super.onSaveInstanceState(outState);
}
/** 保存activity状态 **/
protected void saveInstanceState(Bundle outState) {
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
public void onBack(View v) {
finish();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
// 从栈中移除当前activity
if (listActivity.contains(this)) {
listActivity.remove(this);
}
}
/********************** activity跳转 **********************************/
public void openActivity(Class<?> targetActivityClass) {
openActivity(targetActivityClass, null);
}
public void openActivity(Class<?> targetActivityClass, Bundle bundle) {
Intent intent = new Intent(this, targetActivityClass);
if (bundle != null) {
intent.putExtras(bundle);
}
startActivity(intent);
}
public void openActivityAndCloseThis(Class<?> targetActivityClass) {
openActivity(targetActivityClass);
this.finish();
}
public void openActivityAndCloseThis(Class<?> targetActivityClass, Bundle bundle) {
openActivity(targetActivityClass, bundle);
this.finish();
}
/***************************************************************/
/** 验证上次点击按钮时间间隔,防止重复点击 */
public boolean verifyClickTime() {
if (System.currentTimeMillis() - lastClickTime <= CLICK_TIME) {
return false;
}
lastClickTime = System.currentTimeMillis();
return true;
}
/** 收起键盘 */
public void closeInputMethod() {
// 收起键盘
View view = getWindow().peekDecorView();// 用于判断虚拟软键盘是否是显示的
if (view != null) {
InputMethodManager inputmanger = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
inputmanger.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
/**
* 获取string
*
* @param mRid
* @return
*/
public String getStringMethod(int mRid) {
return this.getResources().getString(mRid);
}
/**
* 获取demin
*
* @param mRid
* @return
*/
protected int getDemonIntegerMethod(int mRid) {
return (int) this.getResources().getDimension(mRid);
}
/**
* 关闭所有(前台、后台)Activity,注意:请已BaseActivity为父类
*/
protected static void finishAll() {
int len = listActivity.size();
for (int i = 0; i < len; i++) {
Activity activity = listActivity.pop();
activity.finish();
}
}
/***************** 双击退出程序 ************************************************/
private long exitTime = 0;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (KeyEvent.KEYCODE_BACK == keyCode) {
// 判断是否在两秒之内连续点击返回键,是则退出,否则不退出
if (System.currentTimeMillis() - exitTime > 2000) {
Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
// 将系统当前的时间赋值给exitTime
exitTime = System.currentTimeMillis();
} else {
finishAll();
}
return true;
}
return super.onKeyDown(keyCode, event);
}
// short吐司
public void showShort(String text) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}
// long吐司
public void showLong(String text) {
Toast.makeText(this, text, Toast.LENGTH_LONG).show();
}
}