Android(安卓)MVP设计架构:Model层数据传递到View层
16lz
2021-01-26
一个常见的场景:处于UI的View层点击了下载的Button按钮,然后转入到Presenter层,此时当然会在Presenter层里面触发Model层的下载任务代码模块。但是,View层UI控件需要实时显示下载进度怎么办?
要知道只有Model层才真正知道下载进度,Presenter层对进度一无所知。对于这种情况有两种方法把
需要在Presenter层的函数里面,当在调用Model层的下载请求时候实现一个回调函数(假设它叫做Callback),然后在Presenter层的匿名Callback内部类实现里面实时调用View的进度更新即可。如代码:
架构建模:
package zhangphil.demo;public interface Model { R request(T t, Callback callback);}
package zhangphil.demo;public interface View { void progress(T t);}
package zhangphil.demo;public interface Presenter { void action(T t); void progress(int i);}
package zhangphil.demo;public interface Callback { R call(T t);}
模型实现:
package zhangphil.demo;import android.os.SystemClock;import java.util.concurrent.CompletableFuture;public class LoadModel implements Model { private Presenter presenter; public LoadModel(Presenter presenter) { this.presenter = presenter; } @Override public Object request(String s, final Callback callback) { CompletableFuture.runAsync(new Runnable() { @Override public void run() { for (int i = 0; i <= 100; i++) { SystemClock.sleep(100); if (callback != null) callback.call(i); } } }); return null; }}
package zhangphil.demo;public interface LoadView extends View { void status(T t);}
package zhangphil.demo;public class LoadPresenter implements Presenter { private LoadView view; private Model model; public LoadPresenter(LoadView view) { this.view = view; model = new LoadModel(this); } @Override public void action(String s) { model.request(s, new Callback() { @Override public Object call(Integer i) { updateProgress(i); return null; } }); } @Override public void progress(int i) { } private void updateProgress(int i) { view.progress(i); if (i > 0 && i < 100) { view.status("下载中..."); } if (i == 100) { view.status("下载完成"); } }}
测试:
package zhangphil.demo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity implements LoadView { private TextView progress,status; private Button button; private Presenter presenter; private AppCompatActivity activity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); activity = this; setContentView(R.layout.activity_main); progress = findViewById(R.id.progress); button = findViewById(R.id.button); status=findViewById(R.id.status); presenter = new LoadPresenter(this); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { presenter.action("https://zhangphil.blog.csdn.net/"); } }); } @Override public void status(final String s) { activity.runOnUiThread(new Runnable() { @Override public void run() { status.setText(s); } }); } @Override public void progress(final Integer i) { activity.runOnUiThread(new Runnable() { @Override public void run() { progress.setText(i + " %"); } }); }}
另外一种方案,不使用Callback回调,直接在Model层调用Presenter层预设的更新函数,在此函数里面进一步触发View的更新,如:
package zhangphil.demo;public interface Model { R request(T t);}
package zhangphil.demo;public interface View { void progress(T t);}
package zhangphil.demo;public interface Presenter { void action(T t); void progress(int i);}
框架模型实现:
package zhangphil.demo;import android.os.SystemClock;import java.util.concurrent.CompletableFuture;public class LoadModel implements Model { private Presenter presenter; public LoadModel(Presenter presenter) { this.presenter = presenter; } /** * 模拟下载。 * * @param s * @return */ @Override public Object request(String s) { CompletableFuture.runAsync(new Runnable() { @Override public void run() { for (int i = 0; i <= 100; i++) { SystemClock.sleep(100); presenter.progress(i); } } }); return null; }}
package zhangphil.demo;public interface LoadView extends View { void status(T t);}
package zhangphil.demo;public class LoadPresenter implements Presenter { private LoadView view; private Model model; public LoadPresenter(LoadView view) { this.view = view; model = new LoadModel(this); } @Override public void action(String s) { model.request(s); } @Override public void progress(int i) { updateProgress(i); } private void updateProgress(int i) { view.progress(i); if (i > 0 && i < 100) { view.status("下载中..."); } if (i == 100) { view.status("下载完成"); } }}
测试:
package zhangphil.demo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity implements LoadView { private TextView progress, status; private Button button; private Presenter presenter; private AppCompatActivity activity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); activity = this; setContentView(R.layout.activity_main); progress = findViewById(R.id.progress); button = findViewById(R.id.button); status = findViewById(R.id.status); presenter = new LoadPresenter(this); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { presenter.action("https://zhangphil.blog.csdn.net/"); } }); } @Override public void status(final String s) { activity.runOnUiThread(new Runnable() { @Override public void run() { status.setText(s); } }); } @Override public void progress(final Integer i) { activity.runOnUiThread(new Runnable() { @Override public void run() { progress.setText(i + " %"); } }); }}
更多相关文章
- 关于android版本spice协议tls端口链接方式的bug问题
- Android使用AsyncTask实现可以断点续传的DownloadManager功能
- Android(安卓)4.1 Audio系统变化说明
- Android(安卓)APP升级(兼容Android7.0报错,Android8.0不能自动安装
- Android新手入门2016(4)--Android(安卓)SDK下载代理设置
- [置顶] 【通知】▁▂▃ Himi 著作《Android游戏编程之从零开始》
- BitmapFactory类的decodeStream方法在网络超时或较慢的时候无法
- Android免Root权限Hook系统函数修改程序运行时内存指令逻辑
- Android源代码下载过程中无法下载repo的解决方法