首页 文章 精选 留言 我的

精选列表

搜索[android studio],共10000篇文章
优秀的个人博客,低调大师

《Android的设计与实现:卷I》——第3章 3.4.5解析Action

3.4.5 解析Action 1.parse_action 解析Action首先从parse_action函数开始,代码如下:static void parse_action(struct parse_state state, int nargs, charargs){ struct action act; ……//省略错误处理内容 act = calloc(1, sizeof(act)); act->name = args[1]; list_init(&act->commands); /将Action的指针节点放入action_list中/ list_add_tail(&action_list, &act->alist); return act;}从parse_action函数的代码可以看出,解析Action的过程与解析Service的过程十分相似。首先给新创建的Action分配存储空间,然后将Action的指针节点放入一个action_list列表中。这里又涉及两个重要的数据类型:action结构体和action_list链表。action_list与service_list都是由list_declare宏声明,即static list_declare(action_list)。action结构体定义在/system/core/init/init.h中,代码如下:struct action { /这个指针节点所在的链表存储了所有Action的指针节点 / struct listnode alist; /这个指针节点所在的链表存储了所有即将执行的Action的指针节点/ struct listnode qlist; /这个指针节点所在的链表存储了所有要触发的Action的指针节点/ struct listnode tlist; unsigned hash; const charname; /Action对应的Command/ struct listnode commands; struct command current;}; 2.parse_line_action 熟悉了Action的存储形式,接着分析Action的解析过程。定位到parse_line_action函数,该函数位于init_parser.c中,代码如下:static void parse_line_action(struct parse_state state, int nargs, charargs){ struct command cmd; /通过state结构体得到当前Action的引用/ struct action *act = state->context; int (func)(int nargs, charargs); int kw, n; /依然是根据关键字匹配,不过这次匹配的是Command / kw = lookup_keyword(args[0]); n = kw_nargs(kw); ……//省略错误处理内容 cmd = malloc(sizeof(cmd) + sizeof(char) nargs); cmd->func = kw_func(kw);//获取Command对应的指令函数 cmd->nargs = nargs; memcpy(cmd->args, args, sizeof(char)nargs); /将Command加入Action的Command列表/ list_add_tail(&act->commands, &cmd->clist); parse_line_action函数的执行过程很清晰,要比parse_line_service简单很多。这里涉及一个重要的数据类型struct command。command结构体定义在/system/core/init/init.h中,代码如下:struct command{ / list of commands in an action / struct listnode clist; / command对应的执行函数/ int (func)(int nargs, charargs); int nargs; char args[1];};至此,init.rc的解析过程便告一段落。接下来开始分析Action和Service的执行阶段。

优秀的个人博客,低调大师

Android架构那些事之第三方库的隔离

在进入主题之前我们先说一下app客户端为什么需要有一个好的架构。 我们都知道一个好的架构会使我们的开发变得事半功倍。 设计架构的目的在于使我们的客户端易于扩展、方便单元测试、可复用。 做到使模块之间低耦合,模块内部高内聚。 我们在开发的过程中会不可避免的引用一些第三方库,比如网络请求库、图片加载库等等。就拿我们的图片加载库来说,程序中不会只有一个地方来引用到此库,可能有N个类会用到此库来显示图片。比如我们现在使用Universal-Image-Loader来展示客户端需要的图片,客户端总共有10个类使用该来显示图片。迭代了两个版本后老板突然说APP经常出现显示图片出现OOM的问题,我们需要将Universal-Image-Loader换成更高效的Picasso来显示图片。 听到这个需求我们的第一反应是"天哪,鬼知道项目里有多少个地方引用了ImageLoader库,我们得改多少代码,万一改代码的时候引发了其他的bug怎么办"。 问题来了我们应该如何避免这种“牵一发而动全身”的囧况。 好了,我们先来看下我们平常是怎么在项目中引用图片加载库的。 before.png 上图是我们大多数人的做法。那么我们怎么才能做到换了一个第三方加载库而是这四个引用类不做改动呢。 下面看下我们重新新设计之后的引用流程图 after.png 从上图我们能看到我们通过一个中间层来引用“第三方图片加载库”。这样做的好处是不管第三方图片加载库你换成Picasso还是Glide我们改变的只是这个中间层,其他的我们一行代码都不需要改动。 如果当时你是这样设计的当老板让你把Universal-Image-Loader换成Picasso时你一行代码也不用改动只需要扩展一个类就可以了。好了话不多说 我们来看代码如何设计。 我这里是使用代理模式来实现代码与图片加载库的隔离的。 首先抽象一个ImageLoader接口 ** *图片加载器功能接口; *添加或者替换新的图片加载器实现该接口即可 */publicinterfaceImageLoader{/** *InitImageLoader */ voidinit(Contextcontext);/** *ShowImage * *@paramimageUrl *@paramimageView *@paramdefaultImage */ voiddisplayImage(StringimageUrl,ImageViewimageView,intdefaultImage); } 我们当前是使用UniversalImageLoader来展示项目中的图片我们就建一个UniversalImageLoader类来实现上面的接口 publicclassUniversalImageLoaderimplementsImageLoader{privatefinallongdiscCacheLimitTime=3600*24*15L;privatecom.nostra13.universalimageloader.core.ImageLoaderimageLoader=com.nostra13.universalimageloader.core.ImageLoader.getInstance();@Override publicvoidinit(Contextcontext){if(!imageLoader.isInited()){ ImageLoaderConfigurationconfig=newImageLoaderConfiguration.Builder( context) .threadPriority(Thread.NORM_PRIORITY) .denyCacheImageMultipleSizesInMemory() .memoryCache(newWeakMemoryCache()) .memoryCacheSize((2*1024*1024)) .memoryCacheSizePercentage(13) .discCacheFileNameGenerator(newMd5FileNameGenerator()) .discCache(newLimitedAgeDiskCache(StorageUtils .getCacheDirectory(context), discCacheLimitTime)) .tasksProcessingOrder(QueueProcessingType.LIFO).build(); com.nostra13.universalimageloader.core.ImageLoader.getInstance().init(config); } }@Override publicvoiddisplayImage(Stringuri,ImageViewimg,intdefault_pic){ DisplayImageOptionsoptions=newDisplayImageOptions.Builder() .showImageOnLoading(default_pic) .showImageForEmptyUri(default_pic).showImageOnFail(default_pic) .cacheInMemory(true).cacheOnDisc(true) .bitmapConfig(Bitmap.Config.RGB_565) .displayer(newSimpleBitmapDisplayer()).build(); imageLoader.displayImage(uri,img,options); } 接下来我们写一个代理类来帮我们实现图片加载的任务 /** *图片加载代理类,所有的图片操作都通过该代理类去实现; *如果要改变图片加载框架,只需要在该类里替换相应的图片加载框架即可,客户端所有引用的图片操作都不需要修改 */publicclassImageLoaderProxyimplementsImageLoader{privateImageLoaderimageLoader;//代理对象 privatestaticImageLoaderProxyimageLoaderProxy;publicstaticImageLoaderProxygetInstance(){if(imageLoaderProxy==null){ imageLoaderProxy=newImageLoaderProxy(); }returnimageLoaderProxy; }publicImageLoaderProxy(){ imageLoader=newUniversalImageLoader(); }@Override publicvoidinit(Contextcontext){ imageLoader.init(context); }@Override publicvoiddisplayImage(StringimageUrl,ImageViewimageView,intdefaultImage){ imageLoader.displayImage(imageUrl,imageView,defaultImage); } } 这样客户端所有需要显示图片的地方只需要调用代理类的图片显示方法即可 ImageLoaderProxy.getInstance().displayImage(); 当老板让我们换成Picasso来完成图片加载时 ,我们只需增加一个 PicassoImageLoader类然后将代理类中的这行代码 imageLoaderProxy = new UniversalImageLoader();换成imageLoaderProxy = new PicassoImageLoader()即可。 怎么样我们只改动一行代码就替换了一个图片加载库方便吧。 本文作者:佚名 来源:51CTO

优秀的个人博客,低调大师

《Android和PHP开发最佳实践》一第3章 PHP开发准备

第3章 PHP开发准备 通过本章,读者将快速地学会如何使用PHP语言进行服务端开发。当然,如果你之前已经有过一些服务端开发的基础,学习本章内容将会更加轻松;然而,如果你以前一直专注于客户端开发,则更需要仔细阅读本章的内容,因为本章将通过讲解PHP语言引领你进入服务端开发的世界,并理解一些服务端开发通用的方法和思路。本章首先会给大家介绍PHP的开发基础,以及一些面向对象编程的技巧;然后紧接着给大家介绍PHP开发环境(Xampp)的搭建和一些其他主要的与之配套的服务端组件(Apache和MySQL)的基础管理;最后还会介绍一个强大的基于Zend Framework和Smarty类库的PHP框架:Hush Framework,本书核心的“微博实例”正是采用这个PHP框架,并使用了其中的MVC分层开发的思路进行开发的。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册