介绍
ImgurDner是一款实验性的Android应用程序,可从imgur.com下载热门图像。它采用流行的MVP或Model View&Presenter模式构建。
背景
虽然使用设计模式不是开发移动应用程序的先决条件,但是诸如MVC或MVP之类的架构模式有助于实现代码关注点的分离:将负责视图的模块与用于业务逻辑的模块区分开来; 在GUI和后端数据之间建立有效的通信通道。此外,单元测试变得更容易,代码的可读性和维护性也得到显着增强。
使用代码
为了进行点对点演示,作者保持代码简单,以便读者可以专注于代码的架构方面,以掌握对Android编程中MVP模式的使用的理解。
在MVP模式中,Presenter充当视图和模型之间的“中间人”。它与View模块建立双向通信:根据Model请求从View获取输入; 同时,从模型中检索结果并通过View的方法直接更新GUI(这是MVC模式中MVP的一个显着特征)。
该项目包含五个主要的java文件:
- DownloadActivity和DownloadFragment,这两个文件是View模块(虽然它主要是Fragment的工作.Android建议使用片段覆盖活动来实现UI目的);
- DownloadContract,一个托管View子接口和Presenter接口的接口;
- DownloadPresenter,演示者界面的实现,充当View和Model之间的联络人
- ImgurService,一个符合Retrofit HTTP客户端框架协议的Inteface类,用于轻松和异步Web服务访问。
DownloadActivity.java负责创建Presenter的实例并将引用传递给片段组件; activity类还负责将片段(View实现)传递给Presenter。通过完成这两个步骤,视图和演示者现在可以进行双向通信。需要注意的是,MVP和MVC模式之间的一个区别在于,MVP演示者可以通过视图引用来操纵UI呈现。
@Override protected void onCreate(Bundle savedInstanceState) { ... //retrieve the reference to the fragment DownloadFragment downloadFragment = (DownloadFragment)getSupportFragmentManager().findFragmentById(R.id.contentFrame); if(downloadFragment == null){ downloadFragment = DownloadFragment.newInstance(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.contentFrame, downloadFragment); transaction.commit(); } //crate a presenter downloadPresenter = new DownloadPresenter(downloadFragment); //pass the view reference to the presenter downloadFragment.setPresenter(downloadPresenter); //pass the presenter reference to the view } ...
在MVP模式中使用Contract接口是一种常见做法,它由两个子接口组成。
- 查看界面。普通的Android Fragment类将实现此接口。
- Presenter界面,包括基本演示者的功能。任何具体的Presenter类至少会实现此接口。
public interface DownloadContract { interface View extends BaseView<presenter> { } interface Presenter extends BasePresenter { } } public interface BasePresenter { void start(); } public interface BaseView<T> { void setPresenter(T presenter); }</presenter>
具体的Presenter类可以很好地从Web服务中获取数据。在这种情况下,我们使用imgur.com的API来访问其丰富的图像存储库。
为了访问imgur的webservice,我们使用Retrofit HTTP客户端框架。简要步骤如下所示:
首先,我们使用Web服务的URL定义接口
public interface ImgurService { String URL = "https://api.imgur.com/3/gallery/hot/viral/0.json"; @Headers({ "Authorization: Client-ID XXXXXXXXX", "User-Agent: XXXXXXXXXXXXXXXXXXXXXXXXX" }) @GET("/") void getAllImages(Callback<Image> cb); }
然后我们按照Retrofit的编码约定检索数据,一旦成功,演示者调用View的方法来更新UI:
ImgurService restInterface = new RestAdapter.Builder().setEndpoint(ImgurService.URL).build().create(ImgurService.class); restInterface.getAllImages(new retrofit.Callback<Image>() { @Override public void success(Image model, retrofit.client.Response response) { List<Datum> images = model.getData(); for(Datum img : images){ Log.d(TAG, img.getLink()); } List<Datum> jpgImgs = Stream.of(images).filter(p -> p.getLink().contains(".jpg")||p.getLink().contains(".gif")).collect(Collectors.toList()); ImageRepo.newInstance().setImages(jpgImgs); ((DownloadFragment)mDownloadView).updateUI(); ((DownloadFragment)mDownloadView).stopSpin(); } @Override public void failure(RetrofitError error) { Log.e(TAG, error.getMessage()); } });
需要注意的是:Datum或Image等类是从JSON流(imgur的Web服务使用的数据格式)转换而来的Java类。处理java对象比为开发人员解析原始JSON流要舒服。这种JSON < - > Java对象转换称为编组/解组,可以通过Jackson等技术实现。
等一下,这里我有一个更好的主意,请按照以下两个简单的步骤:
-
使用HTTP客户端实用程序,我最喜欢的是postman来获取JSON中的数据
-
从上面的结果中获取一个数据单元并将其粘贴到此在线实用程序中,以便可以读取其模式以生成一堆Java类,只需单击一下即可。
兴趣点
- MVP模式用于分离关注点;
- 该应用程序从imgur的webservice获取图像数据;
- 改造HTTP客户端框架用于数据获取目的;
- 毕加索图像库用于图像渲染。
如何使用代码
这很容易。启动Android Studio,加载下载的源并单击“运行”
项目源码及演示apk下载:链接: https://pan.baidu.com/s/1JiMSoKEl9DiOnDzIxGQO7w 密码: 1jrz