话说MVP是11mvp怎么算算的

PD2 MVP修改器3.2更新支持解锁皮肤(附送一款仅正版使用的成就解锁软件) - 3DMGAME论坛 - Powered by Discuz!
3DMGAME论坛
标题: PD2 MVP修改器3.2更新支持解锁皮肤(附送一款仅正版使用的成就解锁软件)
作者: y123ao6& & 时间:
标题: PD2 MVP修改器3.2更新支持解锁皮肤(附送一款仅正版使用的成就解锁软件) 本帖最后由 y123ao6 于
12:19 编辑
BLT已经更新支持Crimefest,而HOXHUD也自己解决了DLL问题,所以MVP和完美海盗两者都完美运行了
PD2 MVP修改器3.2,此修改器来自unknwoncheat社区
由于文件过大,只提供网盘(因为HoxHUD不支持BLT,目前仅支持PDLG汉化)
下载地址:
如果你想预开启或者预关闭某些功能,可以自行修改MVP\UserConfig\Config_(UnknownCheats).lua
里面的功能,请自行复制粘贴到在线翻译中去
自带说明文本已经已经大致翻译,这个东西的使用方法:解压并放到游戏根目录
作者没考虑到部分笔记本没小键盘,所以要修改按键到lib\Lua\MVP.lua里修改
按键使用的是标准键盘编码和键盘键对应代码,不知道请百度以上两个,然后对着改
在这里红字提个醒:别对MVP.lua进行删除的改造行为,除非你有足够自信,要不然乱改,你就体验到刚进游戏送飞机票的快感
单纯功能修改最好只对MVP\UserConfig\Config_(UnknownCheats).lua 这个设置文档进行,里面有一堆英文注解,你不懂可以用百度,bing,有道等翻译
如果想用完美海盗,请到我另一个帖子()
最后,附送大家一款软件SAM,Steam Achievement Manager
(用过无主之地存档修改器,都应该认识这个网址吧)
功能不用说了,解锁成就(只限正版使用,但不是所有游戏成就都能解锁)
注意,请不要在有VAC保护情况下使用该软件(也就是最好是打开steam之后,就立刻使用该软件操作)
本人亲测非常好用
使用方法:
1.Install Microsoft .NET Framework 3.5 if you do not already have it installed.
请先安装.net 3.5
2.Extract it to a directory that is convenient to you, but not your Steam directory. It's a ZIP file, if you don't know how to extract a ZIP file then you probably
shouldn't be trying to use this tool.
解压压缩包(两个EXE,一个DLL)请不要直接在压缩包内双击EXE使用
3.Run Steam if it is not already running.
如果你没运行steam,请先运行steam
4.Exit any active VAC protected games if any are running. While this tool does not directly interact with any game itself, it is better safe than sorry.
不要打开任何受VAC保护的游戏,如果此时你在运行那些受VAC保护的游戏,请先关闭后再使用SAM,否则你就跟你这号说再见把
5.Run SAM.Picker.exe and do whatever you want in it.
运行SAM.Picker.exe,剩下你懂的(选好你要修改成就,点右上角的store就行了)
作者: li123456asd& & 时间:
作者: ddr213& & 时间:
卧槽楼主居然还在参加抢劫大业
看起来楼主也是个热衷于没事抢个农村信用社做消遣的人啊2333
作者: & & 时间:
能不能吧修改器汉化
作者: abc526411& & 时间:
可以保存技能数么,
作者: h& & 时间:
貌似技能点数不能保存,球正确方式。。
作者: 舞动的神之奇& & 时间:
作者==为什么警卫看见我就知道报警了,明明面具没带==还有如何不滑步。根本没跑步动作
作者: y123ao6& & 时间:
舞动的神之奇 发表于
作者==为什么警卫看见我就知道报警了,明明面具没带==还有如何不滑步。根本没跑步动作 ...
正常,你就算不用也一样会,谁跟你说不戴面具就不会报警的
作者: y123ao6& & 时间:
貌似技能点数不能保存,球正确方式。。
请不要在技能界面直接修改
作者: 舞动的神之奇& & 时间:
y123ao6 发表于
正常,你就算不用也一样会,谁跟你说不戴面具就不会报警的
怎么瞬移?
作者: xiexinsir& & 时间:
能汉化么- -我英语只有4级- -
作者: y123ao6& & 时间:
舞动的神之奇 发表于
怎么瞬移?
这个真没有,虽然MVP更新勤快,但是功能上相对完美海盗少一些
作者: jny54705& & 时间:
有咩有上天 穿墙还有杀死一切人?
作者: BoheDamu& & 时间:
一堆废话。
你就能说点有用的?
比如放在哪里,怎么用。
作者: zczhaocan7924& & 时间:
这个好 感谢分享
作者: 老战友981& & 时间:
在哪啊 你的网盘都是解锁成就的
作者: abc526411& & 时间:
终于能保存技能点了
作者: escape11& & 时间:
能不能弄个关闭修改器所有作弊的按键。。。除了技能点
作者: li123456asd& & 时间:
escape11 发表于
能不能弄个关闭修改器所有作弊的按键。。。除了技能点
把MVP.lua改成
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- POSTREQUIRESCRIPTS:
-- DO NOT EDIT OR REMOVE ANY POST REQUIRES, CAN RESULT IN CRASHES
RegisterScript(&MVP/Main/PostRequire/DLCUnlocker.lua&, 2, &lib/managers/dlcmanager&)
RegisterScript(&MVP/Main/PostRequire/SkillResetFix.lua&, 2, &lib/managers/skilltreemanager&)
作者: 8181597& & 时间:
每次改完技能之后,我把这个删除了,技能就没了。。。但是其他钱包括恶名的技能点都能保存啊,有没有办法让技能也保存啊。。。
作者: abc526411& & 时间:
想问个问题就是这个修改器怎么用,是把解压出来的文件全部覆盖么,我下载了汉化好像 有几个会被替换,怎么用啊
作者: abc526411& & 时间:
文件只要一删除技能点什么都自动重置了会这样是吧
作者: v680& & 时间:
终于能保存技能点了
作者: abc526411& & 时间:
默认会开启一些功能,而且只要一删除修改器就无法保存了
作者: octive& & 时间:
想问个问题就是这个修改器怎么用,是把解压出来的文件全部覆盖么,我下载了汉化好像 有几个会被替换,怎么用啊
作者: y123ao6& & 时间:
本帖最后由 y123ao6 于
18:13 编辑
octive 发表于
想问个问题就是这个修改器怎么用,是把解压出来的文件全部覆盖么,我下载了汉化好像 有几个会被替换,怎么 ...
解压出来东西直接放到游戏目录(老生常谈),不会覆盖汉化,如果你只想用PDLG的汉化,只需在游戏主界面到左下角有一个叫MOD管理器的界面,点击一下,然后把chnmod前面的钩去掉,然后重启游戏即可
怎么用,我已经在帖子里说了,因为文字显示修改会影响到该修改器能不能用,所以内容请暂时自行先脑补一下
作者: y123ao6& & 时间:
<font color="#81597 发表于
每次改完技能之后,我把这个删除了,技能就没了。。。但是其他钱包括恶名的技能点都能保存啊,有没有办法让 ...
没有,因为修改技能点需要阻止反作弊系统运行
作者: y123ao6& & 时间:
abc526411 发表于
默认会开启一些功能,而且只要一删除修改器就无法保存了
大部分都是默认不开启,个别是作者认为你会常用到,所以开启了,剩下的有些是必须开启,要不然你就体验到红名快感
我已经在帖子里明说了,你需要微调,请自行到Config_(UnknownCheats).lua修改
这也是唯一的修改(你可以按键修改,但按键修改不保存到默认设置里)
作者: abc526411& & 时间:
y123ao6 发表于
大部分都是默认不开启,个别是作者认为你会常用到,所以开启了,剩下的有些是必须开启,要不然你就体验到 ...
嗯,谢谢大大指导!
作者: abc526411& & 时间:
还是弱弱的问一句如果我只想保留F9和F10的功能,其他的都给失效,要怎么改代码,我记得一进去好像会标记所有人,包括保安平民,看的的很可怕
作者: 8181597& & 时间:
li123456asd 发表于
把MVP.lua改成
------------------------------------------------------------------------------------ ...
照你的做法,一进别人房间一点准备就闪退。。。
作者: 8181597& & 时间:
y123ao6 发表于
没有,因为修改技能点需要阻止反作弊系统运行
能否只让技能生效呢?其他功能全部关闭。。。
作者: rozenazrael& & 时间:
提示: 作者被禁止或删除 内容自动屏蔽
作者: y123ao6& & 时间:
<font color="#81597 发表于
能否只让技能生效呢?其他功能全部关闭。。。
设置文档手动改
作者: & & 时间:
楼主可不可以把修改器汉化一下,或者你在这个帖子里面截图翻译一下也行,我们可以对照着来用
作者: abc526411& & 时间:
大大能不能告诉我怎么改可以只保留F9和F10的功能,其他都不用,那些键位一不小心就按到。。。。。。
作者: abc526411& & 时间:
慢慢摸索了一下关掉了一些功能,但是那个鼠标中键穿墙的功能在哪里关闭,求解
作者: y123ao6& & 时间:
abc526411 发表于
慢慢摸索了一下关掉了一些功能,但是那个鼠标中键穿墙的功能在哪里关闭,求解 ...
MVP.lua取消对应键盘绑定
按键绑定不能关闭,只能取消
地址在lib\lua\ 里
作者: ocx-v& & 时间:
提示: 作者被禁止或删除 内容自动屏蔽
作者: 恻脸。& & 时间:
想问问用完怎么删除?
作者: zaqwsxedcrfvtgb& & 时间:
解锁dlc是哪一个,
作者: y123ao6& & 时间:
zaqwsxedcrfvtgb 发表于
解锁dlc是哪一个,
& & & & -- DLC UNLOCKER -- (REQUIRES RESTART TO TAKE EFFECT)
& & & & DLC_Unlocker = false, -- Unlock All DLC (Master Control)(Cheater Detected)
作者: y123ao6& & 时间:
恻脸。 发表于
想问问用完怎么删除?
你放进去什么,就删什么,如果你想保留BLT:CSE,只需删除MVP文件夹和lib文件夹里的LUA文件夹
作者: zaqwsxedcrfvtgb& & 时间:
y123ao6 发表于
-- DLC UNLOCKER -- (REQUIRES RESTART TO TAKE EFFECT)
& & & & DLC_Unlocker = false, -- Unlock All DLC (Ma ...
没看懂啊,什么意思
作者: rozenazrael& & 时间:
提示: 作者被禁止或删除 内容自动屏蔽
作者: zaqwsxedcrfvtgb& & 时间:
y123ao6 发表于
-- DLC UNLOCKER -- (REQUIRES RESTART TO TAKE EFFECT)
& & & & DLC_Unlocker = false, -- Unlock All DLC (Ma ...
楼主而且捡起全部包囊也用不了啊
作者: zaqwsxedcrfvtgb& & 时间:
y123ao6 发表于
设置文档手动改
楼主我在MVP\UserConfig\Config_(UnknownCheats).lua看见了你给我发的这串代码。可是进游戏dlc还是未解锁啊,而且捡起全部包囊用不了
作者: y123ao6& & 时间:
zaqwsxedcrfvtgb 发表于
楼主我在MVP\UserConfig\Config_(UnknownCheats).lua看见了你给我发的这串代码。可是进游戏dlc还是未解锁 ...
请把false改为true
作者: y123ao6& & 时间:
zaqwsxedcrfvtgb 发表于
楼主而且捡起全部包囊也用不了啊
你是从哪里看到这个功能的
作者: y123ao6& & 时间:
<font color="#81597 发表于
照你的做法,一进别人房间一点准备就闪退。。。
你不能直接修改MVP.lua,因为那里还有其他重要的主文件注入,比如关闭反作弊功能,部分想要关闭功能请到设置文档修改你,如果你直接照他的做法修改,你就被反作弊直接踢出来了,这就是你为什么一准备就飞出去的缘故
作者: y123ao6& & 时间:
rozenazrael 发表于
能联机使用吗?
当然能,不过我不推荐
作者: y123ao6& & 时间:
zaqwsxedcrfvtgb 发表于
没看懂啊,什么意思
设置文档找这句,然后自己改成true
作者: zaqwsxedcrfvtgb& & 时间:
y123ao6 发表于
你是从哪里看到这个功能的
游戏里按小键盘5里面有啊
作者: zaqwsxedcrfvtgb& & 时间:
今天更新,好像闪退了
作者: y123ao6& & 时间:
zaqwsxedcrfvtgb 发表于
今天更新,好像闪退了
删除HOXHUD等插件,这类插件因为版本更新失效了
如果还闪退,请重新到网盘重新下载
作者: lvpolj& & 时间:
每次改完技能之后,我把这个删除了,技能就没了。。。但是其他钱包括恶名的技能点都能保存啊,有没有办法让技能也保存啊。。。
作者: y123ao6& & 时间:
lvpolj 发表于
每次改完技能之后,我把这个删除了,技能就没了。。。但是其他钱包括恶名的技能点都能保存啊,有没有办法让 ...
因为反作弊系统缘故,要么留保持全技能,要么老实加技能
作者: 飞奔的勇敢者& & 时间:
y123ao6 发表于
删除HOXHUD等插件,这类插件因为版本更新失效了
如果还闪退,请重新到网盘重新下载 ...
请问游戏中加入其他人的房间没有问题,自己创建房间开始游戏会闪退。这怎么解决?
作者: killer314& & 时间:
本帖最后由 killer314 于
09:25 编辑
请教下游戏删除&&平台重新下载官方最新版本无任何插件& &下载网盘内BLT-CSE-Chnmod-MVP 覆盖安装后 启动游戏立即闪退& &下载PD2 MVP v3.1 Hook 3.0.5&&覆盖后 能进入游戏&&自建房间开始游戏后立即闪退同58楼 下载PD2 MVP v3.1 Hook 3.2.1覆盖后启动游戏立即闪退 讲PD2 MVP v3.1 Hook 3.0.5内IPHLPAPI.dll文件复制进游戏后能进入游戏&&自建房间开始游戏后立即闪退& &还有就是发现无法与任何一汉化兼容&&使用PD2 MVP v3.1 Hook 3.0.5进入游戏后发现只要有汉化 就无法启动MVP 但是汉化能进游戏 能自建房间
以解决&&问题还是出在IPHLPAPI.dll&&复制也个最原始的IPHLPAPI.dll后 能显示汉化和启动MVP 也无弹出&&现在哈有一个问题是 有谢多天任务 最后一个任务显示黑屏 不知是汉化问题还是MVP问题
作者: shan113006& & 时间:
为啥修改器是英文啊
作者: 痛苦de轮回2& & 时间:
进游戏闪退啊 是什么鬼?
作者: 闪了个辰& & 时间:
怎么关闭DLC解锁啊
作者: abc526411& & 时间:
是不是想要保存技能树等一些相关设置就不能删除修改器的文件对么
作者: Franken_Stein& & 时间:
进去玩屏幕一直黑的。。。。不是挑出 就是一直黑屏
作者: 嚣张的火药& & 时间:
<font color="#81597 发表于
每次改完技能之后,我把这个删除了,技能就没了。。。但是其他钱包括恶名的技能点都能保存啊,有没有办法让 ...
怎么删除啊。。= =求教啊&&我就改了个钱&&不想用了&&不知道怎么删除
作者: & & 时间:
一堆废话。
你就能说点有用的?
比如放在哪里,怎么用。
作者: 佐辰& & 时间:
LZ求解有最新的吗?
作者: jny54705& & 时间:
网盘里的Hook 压缩包是干嘛的
作者: Aliceivy& & 时间:
最近的海盜船修改器 好像一直都不好用了呢 ~ 9.8的話 也不太好呢 因爲.... 衹要用了9.8的修改器 進入游戲 很多功能不好用 而且&&已經加好的技能點會被全部重置
作者: y123ao6& & 时间:
Aliceivy 发表于
最近的海盜船修改器 好像一直都不好用了呢 ~ 9.8的話 也不太好呢 因爲.... 衹要用了9.8的修改器 進入游戲&&...
0.99已经出来了,不过我账户是普通会员,所以耐心等吧,大概也就等一两个星期,才会放出普通版
基本上第一天出开发版,第二天上会员版,大概最少一两个星期才有普通版
作者: soap.& & 时间:
用了的话 除了武装押运全都黑屏。。
去哪个论坛下载一个新版的 结果都进不去游戏= =
作者: Aliceivy& & 时间:
y123ao6 发表于
0.99已经出来了,不过我账户是普通会员,所以耐心等吧,大概也就等一两个星期,才会放出普通版
基本上第 ...
【撲到 y123桑懷裏】
作者: rozenazrael& & 时间:
提示: 作者被禁止或删除 内容自动屏蔽
作者: sl& & 时间:
请问在主菜单没事一进游戏就黑屏是什么情况?
作者: lboyue& & 时间:
一进游戏就黑屏什么情况
作者: & & 时间:
楼主,游戏前段时间更新了,现在进游戏闪退怎么办?
作者: 幻影迷踪& & 时间:
话说LZ能不能给个修改器发下邮箱啊& & 那个网盘东西好多 一个一个试不知道是哪个 ╮(╯▽╰)╭ & & 真心看不懂啊↑↑↑& &只是要个正版修改器滴,,,,
作者: hangzhilong& & 时间:
刷了一堆面具和武器配件,进了好多人游戏,都被踢是什么情况,我是在删了作弊器的情况下进的游戏,有人可以告诉我为什么吗
作者: 西風の翼& & 时间:
怎么解锁枪的配件,楼主求教
作者: zczhaocan7924& & 时间:
感谢楼主一直在更新
作者: zhumingxi929& & 时间:
楼主 请问这个修改器支持xp吗?
作者: ---随遇而安_丶& & 时间:
我就想知道怎么修改移动速度和回复对讲机速度- -
作者: y123ao6& & 时间:
zhumingxi929 发表于
楼主 请问这个修改器支持xp吗?
不知道,自行测试,这个貌似不支持
作者: 3310794& & 时间:
求教LZ如何修改经验金钱或者技能点
实在找不到
作者: 橘红Joker/db& & 时间:
想请教一下LZ,我是STEAM平台玩的 可是每次我开房间作弊完。最后总结的时候都会闪退游戏。我朋友也用了你的补丁,可是他没这个问题。应该怎么解决呀
作者: lnliuy& & 时间:
能不能吧修改器汉化
作者: shuqi_007& & 时间:
能不能弄个关闭修改器所有作弊的按键。。。除了技能点
作者: kof000weixing& & 时间:
一堆废话。
你就能说点有用的?
比如放在哪里,怎么用。
作者: hkhyh& & 时间:
能不能弄个关闭修改器所有作弊的按键。。。除了技能点
作者: gaogaofan& & 时间:
怎么使用你怎么不说? 我就搞不懂了
作者: 贝(多)芬& & 时间:
这个修改器不能解锁DLC吗??
作者: y2982103& & 时间:
能汉化么- -我英语只有4级- -
作者: 贝(多)芬& & 时间:
抱歉我找到了DLCunlocker了
作者: 富兰克林V5& & 时间:
abc526411 发表于
终于能保存技能点了
怎么保存的啊?怎么用,你用的是哪个版本的,我就想保存个技能点和天赋。。。。。。。。。。帮帮我
作者: wdsr& & 时间:
终于能保存技能点了
作者: Have丨been& & 时间:
我只用了MVP,玩了几局发现总结钱和经验的界面直接被跳过去了,一出来就是翻牌,一看经验也没涨,怎么办啊
作者: 蹲在板凳上& & 时间:
想问个问题就是这个修改器怎么用,是把解压出来的文件全部覆盖么,我下载了汉化好像 有几个会被替换,怎么用啊
作者: 骷髅不笑& & 时间:
这是关于崩溃的日志文件,楼主能查出原因吗?非常感谢!!!
18:55 上传
点击文件名下载附件
30.73 KB, 下载次数: 4
作者: 活动扳手& & 时间:
终于能保存技能点了
作者: Kigurumi~& & 时间:
装了之后怎么卸载啊?
欢迎光临 3DMGAME论坛 (/)
Powered by Discuz! X3.2话说这个MVP是怎么算的,才杀了八个人_王者荣耀吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:2,905,643贴子:
话说这个MVP是怎么算的,才杀了八个人
想当年多少大腿魔法兵的...
百合CP或者后宫系的两个...
话说日本有农历吗?
3D双端东方魔幻网游「大青云」勾魂公测,穿越逆转,封神故事,全新演绎!
贴吧热议榜
使用签名档&&
保存至快速回贴2506人阅读
android(79)
在上家干了快2年辞职后在家休息了快一个月了,说实在的不上班的感觉爽(睡觉睡到自然醒,游戏玩到手抽筋)。哈哈,又是快到一年过中秋的时候了,好久没有更新博客了,今天顺便撸一篇。
话说MVP的模式已经问世好几年了,为什么很多公司还是不愿意接受呢?说实在的我就还是喜欢自己的mvc,不喜欢看见mvp庞大的架构,所以前公司的项目呢也不曾使用过mvp(同事也不接受这种模式),毕竟项目架构不是特别复杂的话使用mvp显示不出他的优势,相反给人的感觉是实现一个界面多出了很多的代码。
然而现在最火的应该是mvvm模式了毕竟是数据双向绑定,让我想起了angularjs估计效率很高,但是mvp我们还是要知道的(毕竟还是不错的)。
mvp产生的原因
原生的 MVC 框架遇到大规模的应用,就会变得代码难读,不好维护,无法测试的囧境。因此,Android 开发方面也有很多对应的框架来解决这些问题。
构建框架的最终目的是增强项目代码的 可读性 , 维护性 和 方便测试 ,如果背离了这个初衷,为了使用而使用,最终是得不偿失的
从根本上来讲,要解决上述的三个问题,核心思想无非两种:一个是 分层 ,一个是 模块化 。两个方法最终要实现的就是解耦,分层讲的是纵向层面上的解耦,模块化则是横向上的解耦。下面我们来详细讨论一下 Android 开发如何实现不同层面上的解耦。
解耦的常用方法有两种: 分层 与 模块化
横向的模块化对大家来可能并不陌生,在一个项目建立项目文件夹的时候就会遇到这个问题,通常的做法是将相同功能的模块放到同一个目录下,更复杂的,可以通过插件化来实现功能的分离与加载。
纵向的分层,不同的项目可能就有不同的分法,并且随着项目的复杂度变大,层次可能越来越多。
对于经典的 Android MVC 框架来说,如果只是简单的应用,业务逻辑写到 Activity 下面并无太多问题,但一旦业务逐渐变得复杂起来,每个页面之间有不同的数据交互和业务交流时,activity 的代码就会急剧膨胀,代码就会变得可读性,维护性很差。
总的来说:项目大了我们便于修改和测试,代码重用性高。
MVC和MVP的区别?
从上图我们知道mvc和mvp的结构了:
MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负 责显示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会从直接Model中读取数据而不是通过 Controller。
在MVC里,View是可以直接访问Model的!从而,View里会包含Model信息,不可避免的还要包括一些业务逻辑。 在MVC模型里,更关注的Model的不变,而同时有多个对Model的不同显示,及View。所以,在MVC模型里,Model不依赖于View,但是 View是依赖于Model的。不仅如此,因为有一些业务逻辑在View里实现了,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的。
1、模型与视图完全分离,我们可以修改视图而不影响模型
2、可以更高效地使用模型,因为所以的交互都发生在一个地方——Presenter内部
3、我们可以将一个Presener用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)
未使用MVP程序是这样的:
使用MVP后是这样的:
MVP入门的代码实现(入门级别的实现)
网上很多的例子都是使用登录模块来进行mvp的讲解,但是我们只要知道MVP的流程不管怎么玩还是可以的。
package com.losileeya.mvpsimpledemo.
import android.os.H
import android.os.L
- User: Losileeya ()
- Time: 11:33
- 类描述:
public class UserModel {
private Handler handler=new Handler(Looper.getMainLooper());
- model层业务逻辑处理
- username
- password
- callBack
login(final String username,final
String password,final
CallBack callBack){
handler.postDelayed(new Runnable() {
public void run() {
if(username.equals("123")&&password.equals("123"))
callBack.onSuccess();
callBack.onFilure("帐号或者密码错误");
代码很简单就是一个登录方法的处理,正常情况就里就是调服务器登录接口,我们这里就用延时操作来模拟网络请求。这里对用户名密码做了一个判断,如果用户名为123密码为123就去成功的回调,否则返回“帐号或密码错误”。
public interface CallBack {
* model处理逻辑:成功回调
void onSuccess();
* model处理逻辑:失败回调
void onFilure(String fail);
CallBack就是我们对model的逻辑的具体处理,提供这个插座去做你具体的实现逻辑。
public interface LoginView {
* 显示进度条
进度条加载内容
void showLoding(String msg);
* 隐藏进度条
hideLoding();
* 显示登录的结果
void showResult(String result);
* 显示加载错误
* err 错误内容
void showErr(String err);
* 获得界面上用户名的值
String getUsername();
* 获得界面上密码的值
String getPassword();
我们把登录模块的ui逻辑作为一个接口的形式来处理,方便我们的activity处理的时候来进行界面显示,以及把它交给Presenter层来处理具体的ui展示逻辑。
一部份是给Presenter提供数据的(View-&Presenter)
getPassword
getUsername
另一部份是从Presenter接收数据用来显示的(Presenter-&View)
hideLoading
showResult
showLoading
说白了就是数据与UI的交互。
这一层就是mvp的核心,把view层和model层建立起来联系:
public class LoginPresenter {
private UserModel userM
private LoginView loginV
public LoginPresenter(UserModel userModel, LoginView loginView) {
this.userModel = userM
this.loginView = loginV
public void login(){
loginView.showLoding("正在登录中...");
userModel.login(loginView.getUsername(), loginView.getPassword(), new CallBack() {
public void onSuccess() {
loginView.hideLoding();
loginView.showResult("登录成功");
public void onFilure(String fail) {
loginView.hideLoding();
loginView.showErr(fail);
就一个登录方法,在login方法被调用时,LoginPresenter会从loginView获取到用户输入的用户名和密码,并以此为参数调用userModel的login方法,然后通过回调把结果返回给loginView。
Activity(View 层也就是loginView的实现)
public class LoginActivity extends AppCompatActivity implements LoginView, View.OnClickListener {
private LoginPresenter loginP
private ProgressDialog progressD
private EditT
private EditT
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initView();
loginPresenter = initPresenter();
public LoginPresenter initPresenter() {
return new LoginPresenter(new UserModel(), this);
public void showLoding(String msg) {
progressDialog.setMessage(msg);
if(!progressDialog.isShowing())
progressDialog.show();
public void hideLoding() {
if(progressDialog.isShowing())
progressDialog.dismiss();
public String getUsername() {
return username.getText().toString().trim();
public String getPassword() {
return password.getText().toString().trim();
public void showResult(String result) {
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
public void showErr(String err) {
Toast.makeText(this, err, Toast.LENGTH_SHORT).show();
protected void onDestroy() {
if (loginPresenter != null) {
loginPresenter = null;
super.onDestroy();
private void initView() {
username = (EditText) findViewById(R.id.username);
password = (EditText) findViewById(R.id.password);
login = (Button) findViewById(R.id.login);
progressDialog =new ProgressDialog(this);
login.setOnClickListener(this);
public void onClick(View v) {
switch (v.getId()) {
case R.id.login:
loginPresenter.login();
代码可以看出逻辑清晰,只需要提供一下view 层的方法需要我们传入一个Presenter来处理登录的逻辑。我们只需要记住要初始化Presenter并且在view销毁的时候释放资源。
上面代码我们可以看出还是有很多需要优化的地方,接下来我们就来重新封装我们的mvp。
MVP的高级封装(从入门到放弃)
鉴于装逼和简化解耦的需求,我们需要封装一下mvp的架构,容我喝口奶压压惊。
当然装逼我们就摆脱不了泛型的支持,哈哈,泛型真的是封装中的利器,是应该需要好好的学习。
Model层的封装
我们 以前都是直接使用UserModel类,这样呢不利于扩展,所以呢我们先抽取一个IUserModel的接口,便于我们对代码逻辑更加清晰的梳理,也对代码的维护性有好处。
public interface IUserModel {
登录逻辑处理
* username
* password
* callBack
void login(String username,String password,CallBack
callBack);
我们只需要简单的抽取成接口好了,加个代码的实现是不是看起来更加的逻辑清楚:
public class UserModel implements IUserModel {
private Handler handler=new Handler(Looper.getMainLooper());
* model层业务逻辑处理
* username
* password
* callBack
public void login(final String username, final String password, final CallBack callBack) {
handler.postDelayed(new Runnable() {
public void run() {
if(username.equals("123")&&password.equals("123"))
callBack.onSuccess();
callBack.onFailure("帐号或者密码不正确");
请注意:我们这里为了刷新Ui所以都使用了handler,这里是处理数据的逻辑,项目中换成其他的网络框架也好,handler在这里只是业务的需要。
我们就给view提供了一个接口,显然是可以继续扩展的,因为每次一个view我们就得写一个接口,而且view的显示还是有一些公用的方法,如果我们不去抽取就显得代码又重复无法很好的体现代码的复用性和低耦合。
在这里 我需要新建一个base的包,用于放一下通用的类和接口来降低耦合度:
public interface BaseMvpView {
* 显示进度条
进度条加载内容
void showLoding(String msg);
* 隐藏进度条
void hideLoding();
* 显示加载错误
* err 错误内容
void showErr(String err);
再来看下LoginView的写法:
public interface LoginView extends BaseMvpView{
* 获得界面上用户名的值
String getUsername();
* 获得界面上密码的值
String getPassword();
* 显示登录的结果
void showResult(String result);
是不是显得清爽多了。
Presenter层(最难的)
由于presenter层是联系view和model层,所以封装相对来说困难的多。入门的代码在处理Presenter的时候还是有很多的问题的,比如view销毁了,然后presenter层没有销毁还在调用view层的方法就会导致空指针异常。
所以我们就的做如下修改:
public interface Presenter&V extends BaseMvpView& {
* presenter和对应的view绑定
void attachView(V mvpView);
* presenter与view解绑
void detachView();
写一个基础接口Presenter它接收BaseMvpView的子类,有两个方法,attachView,detachView分别用于与MvpView建立与断开连接,然后我们再来写一个BaseMvpPresenter来具体操作。
public class BaseMvpPresenter&V extends BaseMvpView& implements Presenter&V& {
public void attachView(V mvpView) {
this.mvpView = mvpV
public void detachView() {
mvpView = null;
* 判断 view是否为空
boolean isAttachView(){
return mvpView != null;
* 返回目标view
V getMvpView(){
return mvpV
* 检查view和presenter是否连接
public void checkViewAttach(){
if(! isAttachView()){
new MvpViewNotAttachedException();
* 自定义异常
public static
MvpViewNotAttachedException extends RuntimeException{
MvpViewNotAttachedException(){
super("请求数据前请先调用 attachView(MvpView) 方法与View建立连接");
这个类用来判断view是否和presenter建立连接,并且提供方法让我们获得目标view便于presenter来处理相关逻辑。
具体的LoginPresenter我们也就好实现了:
为了便于梳理项目流程,我们还是提供一个基础接口:
public interface ILoginPresenter {
* presenter login
void login();
以上代码只不过是为了让我们更加清晰的看清业务逻辑。下面才是LoginPresenter:
public class LoginPresenter extends BaseMvpPresenter&LoginView& implements ILoginPresenter{
private UserModel userM
public LoginPresenter(UserModel userModel) {
this.userModel = userM
public void login() {
checkViewAttach();
final LoginView loginView=getMvpView();
loginView.showLoding("正在登录中...");
userModel.login(loginView.getUsername(), loginView.getPassword(), new CallBack() {
public void onSuccess() {
loginView.hideLoding();
loginView.showResult("登录成功");
public void onFailure(String fail) {
loginView.hideLoding();
loginView.showResult(fail);
逻辑很简单,调用login方法,里面我们 需要先检查view和presenter是否已经建立连接,建立联系后我们再来获取目标的view来进行view逻辑的操作,同时我们通过model层来进行相关的业务处理逻辑,并且把处理结果传递给ui层。
然后我们初步的优化已经差不多了:(Activity具体使用)
在activity的onCreate方法中我们记得实例化presenter
presenter = new LoginPresenter(new UserModel());
在activity的onCreate方法中我们记得绑定View
presenter.attachView(this);
3.在activity的onDestroy方法中presenter
presenter.detachView();
显然我们还有优化的空间。
话说当Activity会在很多情况下被系统重启:当用户旋转屏幕、在后台时内存不足、改变语言设置、attache 一个外部显示器等。
我们如何控制presenter的生命周期呢:
1.将Presenter保存在一个地方,再次onCreate时还原
我见到的最多的就是这个方案,不过具体的实现方法千差万别。
最简单最naive的实现方式,就是在Activity/Fragment中保留对Presenter的静态引用。这样我们可以再手机旋转时保留Presenter对象,但整个Applicaiton中只能有一个同样的Activity/Fragment-Presenter实例组合。但当一个ViewPager中有多个相同的Fragment时,这种方法就行不通了。
2.另一个方式就是调用Fragment的setRetainInstance(true)方法。
设置Fragment的这个属性可以保证Fragment不会被destroy,这样Presenter就随之被保留。但这种方式仍有局限,对一个子Fragment或是Activity这样就不起作用。
3.最后一种方式就是使用单例缓存机制并通过标识符来存储一个Presenter类的不同实例。
为了保留Presenter,Activity/Fragment需要在onSaveInstanceState()中传递Presenter实例的标识符。这里的问题是如何实现这种逻辑以及何时将Presenter从单例缓存中移除。
Loader是Android框架中提供的在手机状态改变时不会被销毁的工具。Loader的生命周期是是由系统控制的,只有在向Loader请求数据的Activity/Fragment被永久销毁时才会被清除,所以也不需要自己写代码来清空它。
一般Loader是用来在后台加载数据的,而且是用它的子类CursorLoader或AsyncTaskLoader,尤其是CursorLoader,直接就绑定了Content Provider和数据库。当然如果写个类继承Loader基类的话也不需要开启后台线程。
自定义loader:
public class PresenterLoder&P extends Presenter& extends Loader&P& {
final PresenterFactory&P&
public PresenterLoder(Context context, PresenterFactory&P& factory) {
super(context);
this.factory =
* 在Activity的onStart()调用之后
protected void onStartLoading() {
if(presenter != null){
deliverResult(presenter);
forceLoad();
* 在调用forceLoad()方法后自动调用,我们在这个方法中创建Presenter并返回它。
protected void onForceLoad() {
presenter = factory.crate();
deliverResult(presenter);
* 会在Loader被销毁之前调用,我们可以在这里告知Presenter以终止某些操作或进行清理工作。
protected void onReset() {
presenter = null;
PresenterFactory:这个接口可以隐藏创建Presenter所需要的参数。通过这个接口我们可以调用各种构造器,这样可以避免写一堆PresenterLoader的子类来返回不同类型的Presenter。
public interface PresenterFactory&P extends Presenter&{
P crate();
上诉代码只是创建一个presenter而已。
Activity的实现
从初级的代码我们知道activity里面的登录请求的进度条是可以抽取为通用的方法,这里再次封装一个BaseMvpActivity
public class BaseMvpActivity&P extends Presenter&V&,V extends BaseMvpView& extends AppCompatActivity implements BaseMvpView,LoaderManager.LoaderCallbacks&P&{
private final int BASE_LODER_ID = 1000;
private ProgressDialog progressD
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
progressDialog = new ProgressDialog(this);
getSupportLoaderManager().initLoader(BASE_LODER_ID,null,this);
protected void onStart() {
super.onStart();
presenter.attachView((V)this);
public void showLoding(String msg) {
progressDialog.setMessage(msg);
if (! progressDialog.isShowing())
progressDialog.show();
public void hideLoding() {
if (progressDialog.isShowing())
progressDialog.dismiss();
public void showErr(String err) {
Toast.makeText(this, err, Toast.LENGTH_SHORT).show();
public Loader&P& onCreateLoader(int id, Bundle args) {
return null;
public void onLoadFinished(Loader&P& loader, P data) {
presenter =
public void onLoaderReset(Loader&P& loader) {
presenter = null;
protected void onDestroy() {
presenter.detachView();
super.onDestroy();
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
onStart()方法执行时会创建Loader或重新连接到一个已经存在的Loader。在这里我们在onLoadFinished()里创建并传递Presenter对象。由于这些代码都是同步的,所以当onStart()方法执行完后Presenter也可以正常工作了。
其他方法都差不多,从原来的activity搬过来的,你会疑问为什么我们的onCreateLoader是空实现,因为这是我们的baseActivity肯定不会
创建具体的presenter得留给他的子类去实现。
LoginActivity的具体实现:
public class LoginActivity extends BaseMvpActivity&LoginPresenter, LoginView& implements LoginView, View.OnClickListener {
private EditT
private EditT
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initView();
* 创建LoginPresenter实例
public Loader&LoginPresenter& onCreateLoader(int id, Bundle args) {
return new PresenterLoder&&(this, new PresenterFactory&LoginPresenter&() {
public LoginPresenter crate() {
return new LoginPresenter(new UserModel());
public String getUsername() {
return username.getText().toString().trim();
public String getPassword() {
return password.getText().toString().trim();
public void showResult(String result) {
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
private void initView() {
username = (EditText) findViewById(R.id.username);
password = (EditText) findViewById(R.id.password);
login = (Button) findViewById(R.id.login);
login.setOnClickListener(this);
public void onClick(View v) {
switch (v.getId()) {
case R.id.login:
presenter.login();
看到没有,我们在这里实现了了onCreateLoader,在这里产生LoginPresenter
哈哈,整个LoginActivity又变干净了有木有,大部份Presenter,Loaders都放在了BaseActivity中。LoginActivity里只要实现onCreateLoader就行了。
写到这里也就差不多了,再来看下效果吧:
more links:
讲再多都是扯淡,还得自己动手写一下.
demo 传送门:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:207644次
积分:3398
积分:3398
排名:第7882名
原创:94篇
转载:21篇
评论:232条
文章:12篇
阅读:39539
阅读:4643
阅读:24782
文章:15篇
阅读:45155

我要回帖

更多关于 11平台mvp怎么算 的文章

 

随机推荐