EasyGank源码分析:从项目启动到网络请求的完整执行流程

发布时间:2026/7/14 12:49:08
EasyGank源码分析:从项目启动到网络请求的完整执行流程 EasyGank源码分析从项目启动到网络请求的完整执行流程【免费下载链接】EasyGank The project build framework based on the Rx series and MVP pattern.项目地址: https://gitcode.com/gh_mirrors/ea/EasyGankEasyGank是一个基于Rx系列和MVP模式构建的Android项目框架通过本文你将了解其从应用启动到网络请求的完整执行流程掌握MVP架构在实际项目中的应用方式。项目整体架构概览EasyGank采用经典的MVPModel-View-Presenter架构模式代码结构清晰主要分为以下几个核心模块视图层View位于app/src/main/java/com/camnter/easygank/views/目录包含所有Activity和Fragment** presenter层**位于app/src/main/java/com/camnter/easygank/presenter/目录处理业务逻辑模型层Model位于app/src/main/java/com/camnter/easygank/model/目录负责数据获取和处理数据层位于app/src/main/java/com/camnter/easygank/data/目录管理网络请求和本地缓存应用启动流程解析1. Application初始化应用的入口点是EasyApplication类它继承自Application并在AndroidManifest.xml中注册。其主要职责包括public class EasyApplication extends Application { private static EasyApplication ourInstance new EasyApplication(); public boolean log true; public Gson gson; Override public void onCreate() { super.onCreate(); ourInstance this; Logger.init(); // 初始化日志工具 this.initGson(); // 初始化Gson解析器 this.initReservoir(); // 初始化本地缓存 } private void initGson() { this.gson new GsonBuilder().setDateFormat(GankApi.GANK_DATA_FORMAT).create(); } private void initReservoir() { try { Reservoir.init(this, CACHE_DATA_MAX_SIZE, this.gson); } catch (Exception e) { e.printStackTrace(); } } }EasyApplication使用单例模式通过getInstance()方法提供全局访问点同时初始化了Gson和Reservoir本地缓存库为整个应用提供基础服务。2. 主界面启动应用启动后会进入MainActivity它继承自BaseDrawerLayoutActivity实现了MainView接口public class MainActivity extends BaseDrawerLayoutActivity implements MainView, MainAdapter.OnClickListener { Override protected void initData() { this.presenter new MainPresenter(); // 创建Presenter实例 this.presenter.attachView(this); // 绑定View this.gankType GankType.daily; this.mainAdapter new MainAdapter(this, this.gankType); this.mainRv.setAdapter(this.mainAdapter); this.refreshData(this.gankType); // 刷新数据 } }在initData()方法中MainActivity创建了MainPresenter实例并与其绑定然后初始化适配器并开始刷新数据完成了MVP模式中View与Presenter的关联。MVP架构核心交互流程1. View与Presenter的绑定MainActivity通过以下代码与MainPresenter建立联系this.presenter new MainPresenter(); this.presenter.attachView(this);MainPresenter继承自BasePresenter后者实现了Presenter接口提供了MVP模式的基础方法public class BasePresenterV extends MvpView implements PresenterV { protected V mMvpView; protected DataManager mDataManager; protected CompositeSubscription mCompositeSubscription; Override public void attachView(V mvpView) { this.mMvpView mvpView; this.mDataManager DataManager.getInstance(); this.mCompositeSubscription new CompositeSubscription(); } Override public void detachView() { this.mMvpView null; if (this.mCompositeSubscription ! null) { this.mCompositeSubscription.unsubscribe(); } } }2. 数据请求流程当用户需要获取数据时MainActivity会调用Presenter的相应方法private void refreshData(int gankType) { this.presenter.setPage(1); new Handler().post(() - MainActivity.this.refresh(true)); switch (gankType) { case GankType.daily: this.presenter.getDaily(true, GankTypeDict.DONT_SWITCH); break; // 其他类型数据请求... } }MainPresenter的getDaily()方法实现数据请求逻辑public void getDaily(final boolean refresh, final int oldPage) { this.mCompositeSubscription.add(this.mDataManager.getDailyDataByNetwork(this.currentDate) .subscribe(new SubscriberListGankDaily() { Override public void onCompleted() { // 完成处理 } Override public void onError(Throwable e) { // 错误处理 } Override public void onNext(ListGankDaily dailyData) { // 刷新缓存 if (refresh) MainPresenter.this.reservoirUtils.refresh(GankType.daily , dailyData); // 通知View更新 if (MainPresenter.this.getMvpView() ! null) MainPresenter.this.getMvpView().onGetDailySuccess(dailyData, refresh); } })); }3. 数据响应与UI更新当Presenter获取到数据后通过MainView接口通知View更新UI// MainPresenter.java MainPresenter.this.getMvpView().onGetDailySuccess(dailyData, refresh); // MainActivity.java (实现MainView接口) Override public void onGetDailySuccess(ListGankDaily dailyData, boolean refresh) { if (refresh) { this.emptyCount 0; this.mainAdapter.clear(); this.mainAdapter.setList(dailyData); } else { this.mainAdapter.addAll(dailyData); } this.mainAdapter.notifyDataSetChanged(); this.refresh(false); }这种方式实现了业务逻辑与UI展示的分离符合MVP模式的设计思想。网络请求实现细节1. DataManager数据管理DataManager是数据获取的统一入口封装了网络请求和本地缓存操作public class DataManager { private static DataManager ourInstance; private GankService mGankService; private DataManager() { this.mGankService GankApi.getGankService(); } public static DataManager getInstance() { if (ourInstance null) { ourInstance new DataManager(); } return ourInstance; } public ObservableListGankDaily getDailyDataByNetwork(MainPresenter.EasyDate currentDate) { return Observable.just(currentDate) .flatMapIterable(MainPresenter.EasyDate::getPastTime) .flatMap(this::getDailyDataByEasyDate) .filter(gankDaily - gankDaily ! null) .toList(); } }2. Retrofit网络请求项目使用Retrofit进行网络请求相关代码位于app/src/main/java/com/camnter/easygank/gank/目录// GankApi.java public class GankApi { public static final String GANK_API_URL http://gank.io/api/; public static final String GANK_DATA_FORMAT yyyy-MM-ddTHH:mm:ss.SSZ; public static final int DEFAULT_DATA_SIZE 10; public static final int DEFAULT_DAILY_SIZE 7; private static GankService gankService; public static GankService getGankService() { if (gankService null) { Retrofit retrofit new Retrofit.Builder() .baseUrl(GANK_API_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); gankService retrofit.create(GankService.class); } return gankService; } } // GankService.java public interface GankService { GET(day/{year}/{month}/{day}) ObservableGankDaily getDailyData( Path(year) int year, Path(month) int month, Path(day) int day ); GET(data/{type}/{count}/{page}) ObservableGankData getGankData( Path(type) String type, Path(count) int count, Path(page) int page ); }3. RxJava异步处理项目大量使用RxJava进行异步操作和线程调度例如在MainPresenter的getDaily()方法中this.mCompositeSubscription.add(this.mDataManager.getDailyDataByNetwork(this.currentDate) .subscribeOn(Schedulers.io()) // 订阅在IO线程 .observeOn(AndroidSchedulers.mainThread()) // 观察在主线程 .subscribe(new SubscriberListGankDaily() { // 回调处理... }));通过CompositeSubscription管理订阅关系确保在适当的时候取消订阅避免内存泄漏。数据缓存策略EasyGank使用Reservoir库实现本地数据缓存在EasyApplication中初始化private void initReservoir() { try { Reservoir.init(this, CACHE_DATA_MAX_SIZE, this.gson); } catch (Exception e) { e.printStackTrace(); } }在MainPresenter中数据请求成功后会更新缓存// 刷新缓存 if (refresh) MainPresenter.this.reservoirUtils.refresh(GankType.daily , dailyData);当网络请求失败时会尝试从缓存中读取数据if (refresh) { Type resultType new TypeTokenListGankDaily() {}.getType(); MainPresenter.this.reservoirUtils.get(GankType.daily , resultType, new ReservoirGetCallbackListGankDaily() { Override public void onSuccess(ListGankDaily object) { // 有缓存显示缓存数据 if (MainPresenter.this.getMvpView() ! null) MainPresenter.this.getMvpView().onGetDailySuccess(object, refresh); } Override public void onFailure(Exception e) { MainPresenter.this.switchFailure(oldPage, e); } }); }这种缓存策略提高了应用的离线可用性和响应速度。总结与最佳实践通过对EasyGank源码的分析我们可以总结出以下几点MVP架构的最佳实践职责分离View只负责UI展示Presenter处理业务逻辑Model管理数据接口定义通过接口明确View和Presenter的通信契约生命周期管理在Activity/Fragment的生命周期方法中绑定和解绑Presenter异步处理使用RxJava处理异步操作避免阻塞主线程数据缓存实现网络请求与本地缓存的结合提升用户体验EasyGank项目展示了如何在Android应用中优雅地实现MVP架构通过RxJava和Retrofit的结合构建了一个响应式、可维护的应用框架。开发者可以借鉴其设计思想在自己的项目中实践MVP模式提高代码质量和开发效率。要开始使用EasyGank项目只需执行以下命令克隆仓库git clone https://gitcode.com/gh_mirrors/ea/EasyGank【免费下载链接】EasyGank The project build framework based on the Rx series and MVP pattern.项目地址: https://gitcode.com/gh_mirrors/ea/EasyGank创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考