UGank项目的理解分析
来源:互联网 发布:照片大小修剪软件 编辑:程序博客网 时间:2024/06/05 11:58
通过Github开源项目学习知识,是一种非常好的学习方式。下面我们就来看看一个非常流行的框架App,它采用了最火的OkHttp+Rxjava+Retrofit来搭建网络框架,并且完全遵守Metarial design 新特性,还有项目采用了MVP模式,是真正的学习干货,在此声明,博客只是个人学习记录的方式。
UGank下载地址
/**业务操作父类,定义两个基本的操作*/public interface BasePresenter { void subscribe(); void unsubscribe();}/**定义一个类,里面有两个接口,一个涉及界面操作,一个涉及业务操作**/public class LauncherContract { interface View extends BaseView { void goHomeActivity(); void loadImg(String url); } interface Presenter extends BasePresenter { }}
定义一个业务实现类,来实现业务接口。
/** * LauncherPresenter * Presenter的具体实现类 */public class LauncherPresenter implements LauncherContract.Presenter { /** *这是一个接口,用来操作UI */ private LauncherContract.View mLauncherView; /** * 通过构造传递接口对象 * @param view */ public LauncherPresenter(LauncherContract.View view) { mLauncherView = view; } /** * 操作业务逻辑 */ @Override public void subscribe() { if (!ConfigManage.INSTANCE.isShowLauncherImg()) { mLauncherView.goHomeActivity(); return; } String imgCacheUrl = ConfigManage.INSTANCE.getBannerURL(); if (!TextUtils.isEmpty(imgCacheUrl)) { mLauncherView.loadImg(imgCacheUrl); } else { mLauncherView.goHomeActivity(); } } /** * Activity销毁时的业务操作 */ @Override public void unsubscribe() { }}
然后界面Activity实现业务接口的Ui操作接口,并且持有一个业务操作接口实现类对象。
/** * LauncherActivity * SplashActivity实现了Ui操作接口 */public class LauncherActivity extends AppCompatActivity implements LauncherContract.View { @BindView(R.id.img_launcher_welcome) AppCompatImageView mImageView; // 记录该 Activity 是否在前台显示 private boolean isResume; /** * 创建了一个业务操作的对象,通过传参把界面对象传入 */ private LauncherContract.Presenter mLauncherPresenter = new LauncherPresenter(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setContentView(R.layout.activity_launcher); ButterKnife.bind(this);//绑定View对象 mLauncherPresenter.subscribe();//执行业务操作 } /** * UI界面操作,加载显示Logo妹子 * @param url */ @Override public void loadImg(String url) { try { Picasso.with(this).load(url).into(mImageView, new Callback() { @Override public void onSuccess() { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { if (!isResume) { finish(); return; } goHomeActivity(); } }, 1200); } @Override public void onError() { goHomeActivity(); } }); } catch (Exception e) { goHomeActivity(); } } @Override protected void onResume() { super.onResume(); isResume = true; } @Override protected void onPause() { super.onPause(); isResume = false; } @Override public void goHomeActivity() { Intent intent = new Intent(LauncherActivity.this, HomeActivity.class); startActivity(intent); // Activity 切换淡入淡出动画 overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); finish(); } @Override public void onBackPressed() { // 禁掉返回键 } /** * Activity销毁时的业务逻辑 */ @Override protected void onDestroy() { super.onDestroy(); mLauncherPresenter.unsubscribe(); }}
通过实现接口的形式,来分离UI和业务之间的耦合,然后在Presenter层来反操作Ui,去实现业务。
然后我们看看网络框架工具类。
/** * 网络层 * 封装OkHttp和Retrofit+RxJava搭建网络框架 */public class NetWork { private static GankApi gankApi; //使用Retrofit封装请求 private static OkHttpClient okHttpClient = new OkHttpClient();// 创建OkHttpClient实例 //使用Gson解析的解析工厂类,来自Retrofit包 private static Converter.Factory gsonConverterFactory = GsonConverterFactory.create(); //使用RxJava来创建观察者对象的工厂类,来自Retrofit包 private static CallAdapter.Factory rxJavaCallAdapterFactory = RxJavaCallAdapterFactory.create(); public static GankApi getGankApi() { if (gankApi == null) { Retrofit retrofit = new Retrofit.Builder().client(okHttpClient) .baseUrl("http://gank.io/api/") .addConverterFactory(gsonConverterFactory) .addCallAdapterFactory(rxJavaCallAdapterFactory) .build(); gankApi = retrofit.create(GankApi.class); } return gankApi; }}/** * gank.io 接口 * 使用注解来定义网络接口和需要的传参,和Model层实现链接 */public interface GankApi { /** android、ios、前端等数据接口 */ @GET("data/{category}/{number}/{page}") Observable<CategoryResult> getCategoryDate(@Path("category") String category, @Path("number") int number, @Path("page") int page); /** *首页Banner的妹子图接口 */ @GET("random/data/福利/{number}") Observable<CategoryResult> getRandomBeauties(@Path("number") int number); /** 搜索框接口 */ @GET("search/query/{key}/category/all/count/{count}/page/{page}") Observable<SearchResult> getSearchResult(@Path("key") String key, @Path("count") int count, @Path("page") int page);}
项目总共三个接口,妹子图通过FloatingActionButton来获取下一张,底部的Fragement数据通过传参的不同,返回不同的数据集合进行展示,还有一个查询接口来查询数据。下面看看最主要的数据获取的Presenter。
/** * CategoryPresenter * 首页所有的Fragment的数据,通过 View层的(mCategoryView.getCategoryName()来改变数据展示 */public class CategoryPresenter implements CategoryContract.Presenter { private int mPage = 1;//数据的页数 private CategoryContract.View mCategoryView;//View层的对象引用 @NonNull private CompositeSubscription mSubscriptions;//统一的事件回调监听器 public CategoryPresenter(CategoryContract.View androidView) { mCategoryView = androidView; mSubscriptions = new CompositeSubscription(); //创建统一的事件回调监听器 } /** * 加载数据 */ @Override public void subscribe() { getCategoryItems(true); } /** * 清空订阅器 */ @Override public void unsubscribe() { mSubscriptions.clear(); } @Override public void getCategoryItems(final boolean isRefresh) { if (isRefresh) { mCategoryView.showSwipeLoading(); mPage = 1; } else { mPage += 1; } Subscription subscription = NetWork.getGankApi() .getCategoryDate(mCategoryView.getCategoryName(), GlobalConfig.PAGE_SIZE_CATEGORY, mPage) .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<CategoryResult>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { mCategoryView.hideSwipeLoading(); //隐藏加载框 mCategoryView.getCategoryItemsFail(mCategoryView.getCategoryName() + " 列表数据获取失败。"); } @Override public void onNext(CategoryResult androidResult) { if (isRefresh) {//是否刷新 mCategoryView.setCategoryItems(androidResult); mCategoryView.hideSwipeLoading(); mCategoryView.setLoading(); } else { mCategoryView.addCategoryItems(androidResult); //添加数据 } } }); mSubscriptions.add(subscription);//添加订阅 }}
可以看出,网络数据获取发生在Presenter层,然后通过拿到View层的一个引用去操作UI展示,每一个业务或者Ui的更改,都会对应一个接口定义的一个抽象方法,然后通过实现的方式去实现业务逻辑。
FloatingActionButton 完全解析
Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar
0 0
- UGank项目的理解分析
- 对于项目中handler用法的分析与理解
- 关于项目中的http和https的分析和理解
- 项目基线的理解
- 对项目的理解
- 傅里叶分析的理解
- 数据类型的分析理解
- 模拟项目一(2)&前台界面的理解和分析
- (1)android入门函数理解,tutorial-android项目的MyApplication类分析
- 项目的架构分析
- 项目需求的分析
- 项目的架构分析
- 项目需求文档的理解
- 项目管理的兵法理解
- 项目管理的通俗理解
- Maven 项目的 classpath 理解
- 对Jsecode项目的理解
- 绑定变量的分析理解
- QT之鼠标滑过按钮,按钮改变颜色,离开之后,按钮恢复原先颜色
- Android Studio真机测试中遇到的问题:Session 'app': Error Installing APKs
- AH00072: make_sock: could not bind to address [::]:443 Aphache启动报443端口占用
- 排序算法--选择排序算法
- matlab2010b支持svmlib
- UGank项目的理解分析
- StackOverflowError异常处理
- iOS实现RTMP视频直播 IJKMediaFramework框架编译
- 《c++ primer》 第12章 动态内存 学习笔记
- 数字证书原理,公钥私钥加密原理
- 限制文字
- redisson实现分布式锁原理
- Ubuntu ssh免密码登陆
- iOS面试题----中软