android Robospice的工作原理是什么
android Robospice的工作原理是什么
这篇文章主要讲解了“android Robospice的工作原理是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“android Robospice的工作原理是什么”吧!
一些现有的解决方案
Robospice 比起 AsyncTask 的确好太多了,但是依然存在一些问题。比如下面这段常见代码,通过Robospice在Activity中发起一个请求的过程。你并不需要细读,只要有个大概的概念就好:
FollowersRequestrequest=newFollowersRequest(user);lastRequestCacheKey=request.createCacheKey();spiceManager.execute(request,lastRequestCacheKey,DurationInMillis.ONE_MINUTE,newRequestListener<FollowerList>{@OverridepublicvoidonRequestFailure(SpiceExceptione){//Onsuccess}@OverridepublicvoidonRequestSuccess(FollowerListlistFollowers){//Onfailure}});
然后是请求的具体代码:
publicclassFollowersRequestextendsSpringAndroidSpiceRequest<FollowerList>{privateStringuser;publicFollowersRequest(Stringuser){super(FollowerList.class);this.user=user;}@OverridepublicFollowerListloadDataFromNetwork()throwsException{Stringurl=format("https://api.github.com/users/%s/followers",user);returngetRestTemplate().getForObject(url,FollowerList.class);}publicStringcreateCacheKey(){return"followers."+user;}}
存在的问题
你需要为每个请求都做上述的处理,代码会显得很臃肿:
- 对于你的每种请求你都需要继承SpiceRequest写一个特定的子类。
- 同样的,对于每种请求你都需要实现一个RequestListener来监听。
- 如果你的缓存过期时间很短,用户就需要花较长时间等待你的每个请求结束。
- RequestListener持有了Activity的隐式引用,那么是不是还需要内存泄露的问题。
综上,这并不是一个很好的解决方案。
五步,让程序简洁而健壮
在我开始开发Candyshop的时候,我尝试了其他的方法。我试图通过混合一些拥有有趣特性的库来构造一个简单而健壮的解决方案。这是我用到的库的列表:
* AndroidAnnotations用来处理后台任务,EBean等等……
* Spring RestTemplate用来处理 REST(含状态传输)的网络请求,这个库和AndroidAnnotations配合的非常好。
* SnappyDB这个库主要用来将一些 Java 对象缓存到本地文件中。
* EventBus 通过 Event Bus 来解耦处理 App 内部组建间的通讯。
下图就是我将要详细讲解的整体架构:
第一步 一个易于使用的缓存系统
你肯定会需要一个持久化的缓存系统,保持这个系统尽可能简单。
@EBeanpublicclassCache{publicstaticenumCacheKey{USER,CONTACTS,...}public<T>Tget(CacheKeykey,Class<T>returnType){...}publicvoidput(CacheKeykey,Objectvalue){...}}
第二步 一个符合REST的Client
这里我通过下面的例子来说明。记得要确保你使用 REST API 放在同一个地方。
@Rest(rootUrl="http://anything.com")publicinterfaceCandyshopApi{@Get("/api/contacts/")ContactsWrapperfetchContacts();@Get("/api/user/")UserfetchUser();}
第三步 应用级的事件总线(Event Bus)
在程序最初的时候就初始化Event bus对象,然后应用的全局都可以访问到这个对象。在Android中, Application初始化是一个很好的时机。
publicclassCandyshopApplicationextendsApplication{publicfinalstaticEventBusBUS=newEventBus();...}
第四步 处理那些需要数据的Activity
对于这一类的Activity,我的处理方式和Robospice非常类似,同样是基于Service解决。不同的是,我的Service并不是Android提供的那个,而是一个常规的单例对象。这个对象可以被App的各处访问到,具体的代码我们会在第五步进行讲解,在这一步,我们先看看这种处理Activity代码结构是怎么样的。因为,这一步可以看到的是我们简化效果***烈的部分!
@EActivity(R.layout.activity_main)publicclassMainActivityextendsActivity{//Injecttheservice@BeanprotectedAppServiceappService;//Onceeverythingisloaded…@AfterViewspublicvoidafterViews(){//…requesttheuserandhiscontacts(returnsimmediately)appService.getUser();appService.getContacts();}/*TheresultofthepreviouscallswillcomeaseventsthroughtheEventBus.We'llprobablyupdatetheUI,soweneedtouse@UiThread.*/@UiThreadpublicvoidonEvent(UserFetchedEvente){...}@UiThreadpublicvoidonEvent(ContactsFetchedEvente){...}//Registertheactivityintheeventbuswhenitstarts@OverrideprotectedvoidonStart(){super.onStart();BUS.register(this);}//Unregisteritwhenitstops@OverrideprotectedvoidonStop(){super.onStop();BUS.unregister(this);}}
一行代码完成对用户数据的请求,同样也只需要一行代码来解析请求所返回的数据。对于通讯录等其他数据也可以用一样的方式来处理,听起来不错吧!
第五步单例版的后台服务
正如我在上一步说的那样,这里使用的Service并不是Android提供的Service类。其实,一开始的时候,我考虑使用Android提供的Services,不过***还是放弃了,原因还是为了简化。因为 Android提供的Services通常情况下是为那些在没有Activity展示情况下但还需要处理的操作提供服务的。另一种情况,你需要提供一些功能给其他的应用。这其实和我的需求并不完全相符,而且用单例来处理我的后台请求可以让我避免使用复杂的借口,譬如:ServiceConnection,Binder等等……
这一部分可以探讨的地方就多了。为了方便理解,我们从架构切入展示当Activity调用getUser()和getContacts()的时候究竟发生了什么。
你可以把下图中每个serial当作一个线程:
正如你所看到的,这是我非常喜欢的模式。大部分情况下用户不需要等待,程序的视图会立刻被缓存数据填充。然后,当抓取到了服务端的***数据,视图数据会被新数据替代掉。与此对应的是,你需要确保你的Activity
可以接受多次同样类型的数据。在构建Activity
的时候记住这一点就没有任何问题啦。
下面是一些示例代码:
//AsIsaid,asimpleclass,withasingletonscope@EBean(scope=EBean.Scope.Singleton)publicclassAppService{//(Explainedlater)publicstaticfinalStringNETWORK="NETWORK";publicstaticfinalStringCACHE="CACHE";//Injectthecache(step1)@BeanprotectedCachecache;//Injecttherestclient(step2)@RestServiceprotectedCandyshopApicandyshopApi;//Thisiswhattheactivitycalls,it'spublic@Background(serial=CACHE)publicvoidgetContacts(){//TrytoloadtheexistingcacheContactsFetchedEventcachedResult=cache.get(KEY_CONTACTS,ContactsFetchedEvent.class);//Ifthere'ssomethingincache,sendtheeventif(cachedResult!=null)BUS.post(cachedResult);//Thenloadfromserver,asynchronouslygetContactsAsync();}@Background(serial=NETWORK)privatevoidgetContactsAsync(){//Fetchthecontacts(networkaccess)ContactsWrappercontacts=candyshopApi.fetchContacts();//CreatetheresultingeventContactsFetchedEventevent=newContactsFetchedEvent(contacts);//Storetheeventincache(replaceexistingifany)cache.put(KEY_CONTACTS,event);//PosttheeventBUS.post(event);}}
似乎每个请求之中的代码还是有点多!实际上,这是我为了更好说明才进行了展开。不难发现,这些请求都遵守了类似的模式,所以你可以很容易的构造一个 Helper 来简化他们。比如 getUser()可以是这样的:
@Background(serial=CACHE)publicvoidgetUser(){postIfPresent(KEY_USER,UserFetchedEvent.class);getUserAsync();}@Background(serial=NETWORK)privatevoidgetUserAsync(){cacheThenPost(KEY_USER,newUserFetchedEvent(candyshopApi.fetchUser()));}
那么serial是用来做什么的? 让我们看看文档是怎么说的:
默认情况下,所有@Background的匿名方法都是并行执行的。但是如果两个方法使用了同样名字的serial则会顺序运行在同一个线程中,一个接着一个执行。
虽然把网络请求放在一个线程中顺序执行可能会导致性能下降,但是这使得“先POST然后GET获得数据”的那类事务处理起来非常容易,这是个特性值得为此牺牲一些性能。退一步讲,如果你真的发现性能不可接受,还是可以很容易使用多个serial来解决。现在版本的Candyshop中,我同时使用了四个不同的serial。
感谢各位的阅读,以上就是“android Robospice的工作原理是什么”的内容了,经过本文的学习后,相信大家对android Robospice的工作原理是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是恰卡编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!
推荐阅读
-
android(如何快速开发框架 小米note开发版MIUI,安卓6.0,怎么安装Xposed框架)
稳定版,你必须先根除。你上网搜索安卓可以叫别人s框架,对方可以把框架做成jar包,把这个jar包加载到项目目录的libs文件中使...
-
android(studio 虚拟机启动不了 android studio可以当模拟器用吗)
androidstudio可以当模拟器用吗?AmdCUP引导模拟器有点复杂。雷电模拟器上的抖音怎么登录不上?不是,闪电模拟调用...
-
从实践中学习手机抓包与数据分析(android 手机抓包app)
android手机抓包app?netcapture抓包精灵app(手机抓包工具)又名sslcapture,是什么专业的安卓手机抓...
-
android(studio全局搜索 android studio怎么看app界面)
androidstudio怎么看app界面?在设备桌面点击运用直接进入到App界面,就也可以参与其他你的操作了。android-...
-
怎么把android框架源代码拉到本地(android studio如何运行别人的源代码)
androidstudio如何运行别人的源代码?androidstudio点击刚建在列表中你选择导入module,导入即可在用...
-
android(studio2022年使用教程 怎么安装Android studio详细教程)
怎么安装Androidstudio详细教程?androidstudio中haxm直接安装的方法追加:1、简单的方法打开Andr...
-
怎么使用Android基准配置文件Baseline Profile方案提升启动速度
-
HTML5如何实现禁止android视频另存为
-
学java好还是学php好?
-
Android如何实现多点触控功能