任何问题请联系WX:uu16853

买模板送网站采集器 让你轻松放开双手运营网站!

购买更多有优惠!

Unknown URL content://这类Uri错误解析 Android开发技术

   有时候在Android数据库操作Uri时可能遇到类似Caused by: java.lang.IllegalArgumentException: Unknown URL content://xxx 这样的错误,出现 Unknown URL content 这样的关键词主要是,Uri前部分存在,而后面部分的数据不存在造成的,而出现类似 ActivityThread: Failed to find provider info for xxx 这样的是这个Uri根本就不存在,由于Android系统上系统的内置provider的content名称经常改变在不同版本的固件上可能出现这些问题,希望大家注意。

CursorWindow查询大数据方法 Android开发技术

  对于Android SQLite的Cursor出错,Android123在 SQLite出错提示CursorWindow need to grow: mSize 一文中介绍过,从Android源码可以看到framework中限制大小为#define MAX_WINDOW_SIZE (1024 * 1024)  即1MB的数据量,一般的数据库类型Integer和Text相对好些,遇到单个较大的二进制Blob类型可能会显得比较吃力。解决方法Android开发网建议大家从源头分析   Cursor c=getContentResolver.query(null,null,null,null) ,如果这四个参数都为空的话,限制较少,内存占用较大,这里我们可以通过第二个参数限制查询部分字段即可,当然分段查询,比如第一次从记录0-500,第二次查询从501-1000,对于计算数量,SQLite支持rawQuery方法,select count(*) form cwj_tables 这样的SQL语句,可以直接获取出某个表的记录数量,都比较方便。

Android开发做哪方面好? Android开发技术

  很多网友转型Android开发或准备做一个Android开发者,到底做哪方面的好呢? 下面是Android123给大家的一些建议:   1. 过去是J2EE、J2SE的开发者,这类传统的Java开发者可以考虑继续做Android应用开发,如果会SSH,可以做更好的服务性客户端等等。   2. 过去时J2ME的开发者,大部分可能都是做游戏出身的,考虑Android游戏开发相对比较理想。   3.  过去是C\C++程序员或有些基础,可以考虑Android应用开发,熟悉后可以做一些更深入的应用通过NDK,Android NDKr5还对STL部分特性做了支持,比较实用。   4. 过去是WinCE、Maemo或硬件相关的,可以考虑ROM定制,移植方面的,对于Android Framework层的学习是主要的。   5. 过去搞硬件的、单片机的可以试试Android ADK,有关ADK是什么Android开发网在以前的文章中介绍过,可以做出一些硬件配件来。   到底是做应用薪水高还是底层呢? 这里Android123就形势而言应用挂广告,尤其是游戏效果会远比做底层和内核的好,国内较著名的愤怒的小鸟就是一个比较典型的例子,相对而言用户看到的是应用,做底层的只能比较低调了,但做一款内核级的应用还是不错的。

Android Market排名算法及规则 (转) Android开发技术

  很多国内的Android开发者可能在Market上有软件发布,对于Market的SEO今天Android123从国内翻译较好和分析较仔细的一片文章中整理得来的,原文为 众所周知,做搜索出身的Google,旗下的Market的排名肯定是依据一个形同( A×a% + B×b% + C×c%)的公式计算出来的数值,进行排名的。开发者可根据其排名规则,对自己的产品设计和研发以及推广进行指导。    1. 排名公式里有哪些指标?   指标A、B、C到底是什么?权重a、b、c究竟是多少?这些问题的答案,应该是每个App开发者和运营者都渴望了解的。知道了这个答案之后,有些“聪明”的人就会像当年SP的从业者一样,去刷那些权重大的指标、从而拉升产品的排名了。网上关于此问题的讨论很多都是不了了之、无疾而终。相对较深入的一篇文章《Android Market App Rankings》,也只是在猜想是基于“安装量”的增长和留存。可惜,该作者离正确答案就差一步了…… 也许你已经等得不耐烦了,哈哈。现在就说说我的结论吧。指标A=“总安装/总下载”,即下载转安装的转换率;B=“评分/5”,即产品得分比上Market的满分;C=“留存安装/总安装”,即安装的留存率。不要急着问我a、b、c等于多少,准确数值只有Google知道、而且可以调,我只能告诉你它们加起来等于100,还有就是b>max(a,c)(为什么?下面耐心看)。   依据这个推断公式,就是说如果每个下载的用户都安装了、而且都给了5分、并且一直都没有卸载——OK.不论a、b、c是多少,你的产品得了满分,它就是No.1!   2. 为什么是它们?   在告诉你为什么是A、B、C之前,我先告诉你为什么不是D、E、F……   先看个数据,Android Market-通信-免费-TOP25:     去掉了产品名称,我们可以看到更纯的数据。   首先,我们可以肯定的排除排名是按“下载次数”排序的,下载次数1万+的产品(第9位)居然排到了下载次数500万+(第11位)的前面。试想第11位的产品在喊:“这是为什么?它哪点比我好???”——答案:请看“评分”。啊?它是5分!没错,第9位的产品评分得了满分。哦,排除了D的同时,我们收获了B。   其次,我们可以排除“评分人数”。原因就是,在“下载次数”和“评分”都同等量级的情况下,比对了若干样本,都无章可循——实在跟“评分人数”不相干。E被干掉了。   再次,要排除的是“加速度”。很多人在猜测会有一个“加速度”指标,或者新增下载的、或是新增安装的。大家的这种猜测是源自于“鼓励新产品”,但是这是一种过于激进的想法。Market这么大盘子是要鼓励推陈出新的,但“保护”新产品的同时也得“爱护”那些确实有实力的老产品。过大的用户基数,肯定会拖慢老牛产品的“加速度”,如果这么做的话每天的TOP10都是面目全非的(App Store的排名规则里就有“加速度”,所以TOP榜天天易容)。所以,“加速度”也不是真正的公平。   排除了D、E、F,收获了B。那A和C是从哪来的?   休息一下,问个题外话?我们一般是怎么评判一个物品的“好”“坏”的?是不是有以下部分组成?有一样东西摆在你面前,勾起了你试用的欲望。试用之后,你可能爱不释手,继续用吧。路遥知马力,又用了一段时间,你又有了新的评判。如果这个东西实在是太好了,那你就会与它形影不离……回归到我们判断一个物品的标准的本质,无非就是是否“接受它”、是否“肯定它”、是否“留着它”。 言归正传,用户是否“接受”一个App——下载只是“抬头”,安装才是“点头”。如果单以“安装”为指标,又会让老产品滚雪球,有失公平。所以,A(下载转安装的转化率)浮出水面了。“安装”做分母,“下载”做分子。一方面,排名在前的产品下载量越高、安装量就有可能越高的同时,如果产品不够好“下载量”越高就可能成了拖后腿的那个分母,上面举例的第11位产品就是个例子(庞大的下载量下,安装量无法保持同步增长,所以让其难堪重负,排名下落——剧透下,第11位是曾经“通信”下排名第1的产品KakaoTalk)。另一方面,只要A(还有B、C)足够好,也让一些新产品可以冒出头来。   B(评分)刚才已经分析到了,这里需要补充一点的是:评分不是一次性的。我们会发现在Market里“评分”是可以多次修改的,这样的目的就是鞭策产品要持续的“好”,用户一直掌握着产品的“生杀大权”。另外,就是为什么前文说到b大于a和c,原因就是纵观TOP100,评分低于4分的只有两个;TOP25,评分低于4的是零个;TOP10,评分低于4.5的只有一个(避免出现App Store里《小姐日记》这样低分却长期占据高排位的现象)——一言以蔽之:要想在前排就坐,产品首先得让用户觉得“好”。   该说说C(安装留存率)的出处。说白了就是控制流失率,如果“总安装”很高、但是“留存安装”很少,那也不能称之为“好”产品。所以,安装留存率就是另一个全面衡量产品优劣的指标。   3. 它们到底是多少?   前文已经说到b比a和c都大,那a和c孰大孰小呢?这个取决于Android Market的策略,如果“a比c大”意味着“更看重新增”(任何一个店铺先开张的时候,都会最看重这个)、如果“c比a大”意味着“更看重留存”(对于一个已经把客流吃透的老店,会更看重这个)——所以,这个真是可以调的,取决于Android Market发展到哪个阶段和运营管理者的自我认识。   4. 感言   Android Market如果真是我想象的这样排名,可谓新老兼顾,攻防兼备。   说它新老兼顾,是因为它让新鲜的好的新产品既能快速冒出来、也能让它经得起时间的推敲,或昙花一现或源远流长。说它攻守兼备,是因为这样会把盘子越做越大,而且也防止了“刷”(能刷上去,但是刷上去之后如果产品不够好,会让产品跌得更惨),把盘子越做越牢。这样公平的规则,也为Android Market的应用量新增速度已超过App Store提供了另一个有力的支持。高!实在是高! Android Market排名规则这个隐形的裁判告诉我们:持续地把产品做好,才是正道!

Android 3.1和iOS 5以及WP7.1 Mango对比 Android开发技术

  很多开发者对Android 3.1、iOS 5和Windows Phone 7.1 Mango之间新特性的对比还不是很清楚。下面Android123就三大平台的最新版开发特性作对比:    目前就发布时间来看 Android 3.1已经发布,iOS 5还要过几个月等iPhone 4S上市,而WP7的芒果估计要到9月份了   1. NFC移动支付,目前Android 2.3开始就支持NFC,而iOS 5仍然没有动作,而可怜的Windows Phone 7.1 Mango似乎还不知道NFC是何物。   2. ADK开发,对于周边硬件的开发,Google Android提供了ADK开发包,我们可以当做是一个USB的扩展辅助,帮助Android识别其他设备的USB通讯协议,如果哪天Google整出个类似DDK那就更有意思了,而iOS似乎只对知名厂商提供支持和授权,WP7.1这些还看不到任何迹象,最终应该还是只有OEM能开发吧。   3. 多任务支持,Android与生俱来就支持多任务,这似乎也是Linux的优势,而iOS从4开始支持伪多任务,就是让当前线程挂起处于休眠状态,处理完其他任务后再唤醒,这样iPhone一直无法挂QQ,不过Windows Phone 7.1开始支持多任务和Android一样,可以挂QQ了。   4. 来电控制,Android提供了开放的API,可以开发来电防火墙,显示归属地,或者是处理自己的应用当来电时保存状态,挂断电话后的状态做处理,而iOS必须越狱并使用非官方SDK方式实现,目前Windows Phone Mango对电话方面没有任何支持,而早期的Windows Mobile我们可以方便的处理RIL层,似乎微软现在封闭了。   5. 高性能计算,Android从1.5开始支持NDK,可以使用C/C++开发性能敏感的算法或3D GL图像相关的显示,从NDKr5开始支持精简的C++ STL标准库,iOS使用的Objective-C也可以很好的支持ISO C和C++,不过目前WP7只能用C#或VB.NET这样托管语言编写,而早期的Windows Mobile是支持Dot Net Framework和Native C开发的,似乎高端的体验度要大打折扣了。   6. 界面定制,Android可以很轻松灵活的更换界面主题,而iOS的封闭官方是不允许的,WP7由于界面比较简洁功能较单一,并不是很有竞争力,至少Android变身iOS和WP7的界面来说很轻松,而桌面的Widget小插件的趋势和优势已经显现出来。微软作为小插件的领跑者早在Windows Vista推出了Gadget的侧边栏小插件开发接口,但这一概念似乎在Windows Phone上荡然无存。   7. 固件升级,Android目前的固件升级是比较头疼的,由于厂商较多,改变的更多,硬件的限制不是很严格导致固件不统一,目前Google不开放Android honeycomb的代码也是防止山寨厂商推出低配的平板降低Android […]

微软推出Android转WP7白皮书和API对照表 Android开发技术

   很多国内网友看好微软下一代Windows Phone开发,同时微软也将PC、游戏机和移动设备的Metro UI应用于下一代的Windows 8系统,再推出了iPhone转WP7的白皮书后,目前Android转Windows Phone 7开发的白皮书以及API映射对照表目前已经可以浏览,不过从对照来看WP7 Mango的API完善度只有Android 1.0的十分之一不到是可以替代的,目前都3.1了,等Mango发布时估计IceCream Sandwich都发布了,也就是说微软Windows Phone 7 Mango的能开发的调用的API十分少,大大限制了开发者的设计功能,不过用WP7做一些RSS阅读器,写点玩具类的应用还是可以的。   PDF格式Windows Phone 7 Guide for Android Application Developers 下载 (4MB)   Android API和Windows Phone 7的API对照表,目前显示的是Android 2.3姜饼版的API,在线阅读 http://wp7mapping.interoperabilitybridges.com/Home/Library?source=Android      目前总体来看微软似乎在Windows Phone 7上的两宗罪,归结为不支持Native开发,API十分不完善或者说就是封闭,相对于iOS和Android来说威胁甚微。

Android框架层学习指导 Android开发技术

  很多Android开发者可能觉得仅仅了解Java层还不够,这里Android123结合源码帮助大家如何了解Android Framework层。    首先Android开发网提示大家需要了解哪些前置知识,首先要有C++基础,如果你只会C,可能对于C++ STL标准库,以及模板和泛型的理解会吃力很多,同时要有OOP的思想否则看Android这样的大工程可能无法很好的组织,这点可以通过h文件画出UML图来快速了解整个结构。   1. 首先我们从Android GIT源码托管站点下载Framework层的源码,在base.git包   2. 对于Android来说,Google内部使用C++有些类似STL,因为部分用到了只是再次封装,这里建议大家直接看base中的include目录下的utils里的文件,比如说String8.h、String16.h、Vector.h、KeyedVector.h以及TypeHelpers.h   这里String8和String16和STL中的String相比,提供了更多的辅助方法,相比标准库更完善些,其中有些类似uint8_t、uint_16t和uint32_t这里我们可以理解为VC中的char、short和int,就是8位、16位和32位的整形,主要是标示的范围不同,使用更小的单位可以更节省内存开销,对于系统来说这是十分重要的,对于Vector和STL中的vector功能上是相同的,而KeyedVector我们当做stl中的map去对待即可,本身就是一个哈希映射类型,下面Android123要强调的就是TypeHelpers这个文件,里面封装的sp模板和wp模板,很多源码中会有类似  static  sp<Camera> 这样的定义,就需要深入的了解下Android的SP了,如果你真的会C++这些都是小儿科了,比如   template <typename T> class sp;template <typename T> struct trait_trivial_move< sp<T> >{    enum { value = true }; }; // wp<> can be trivially movedtemplate <typename T> class wp;template <typename T> struct trait_trivial_move< wp<T> >{     enum […]

Android Framework学习指导(二) Android开发技术

  对于Android Framework层的学习,在上一次的 Android框架层学习指导 中我们已经讲到了基础的结构和定义,但是对于Framework层的核心还有哪些呢?   1.  在Android源码的base中,我们可以看到每个目录进去,都会有java和jni两个文件夹,后者对于初入android框架的学习十分有帮助,如果你刚开始了解NDK和JNI相关的不妨读读Google的代码,这对于代码风格和质量的提高都很有帮助。  2.  对于NDK和JNI来说,编译我们需要一个好的环境,这里还是推荐基于Unix架构的Linux或Mac OS编译,Android123推荐放弃Windows下的Cygwin和MingWin可以节省不少的时间,对于编译来说先掌握mk文件的结构比较重要,这里可以直接查看base目录中每个jni子目录的android.mk文件即可,在Linux下mk文件这种脚本方式对于过去一些Visual Studio用惯的可能感觉有些原始。  3.  当然学习Android Framework可以帮助改进系统,定制自己的固件,部分核心的库是独立的external包,比如说 SQLite、Webkit、zlib、libpng这些Android使用第三方开源的库都是在platform/external/xxx.git中。xxx代表最终的库名。  4. 对于部分的核心库,上次我们在Android框架层学习指导一文中由于篇幅并没有提到,其实在base目录下面的native中可以看到很多系统结构的定义和实现。Android开发网推荐深入掌握Android这个namespace中的所有结构,这样的基础是十分必要的。  5. 最后我们附上Base目录的结构图,希望对大家有用:   ├─api├─build├─cmds│  ├─am│  │  └─src│  │      └─com│  │          └─android│  │              └─commands│  │                  └─am│  ├─app_process│  ├─backup│  ├─bmgr│  │  └─src│  │      └─com│  │          └─android│  │              └─commands│  │                  └─bmgr│  ├─bootanimation│  ├─bugreport│  ├─dumpstate│  ├─dumpsys│  ├─ime│  │  └─src│  │      └─com│  │          […]

Android开发用的平板电脑推荐 Android开发技术

  随着Android honeycomb的普及,对于Android开发用的平板电脑购买也是十分必要的,到底哪款平板适合开发使用呢?  一、硬件方面   CPU最好是主流的NVIDIA Tegra2 A9双核1GHz,RAM为1GB,分辨率为WXGA即1280×800,运行的系统至少为Android 3.0。对于非谷歌官方的Android 2.x系统可以忽略,毕竟很多API是3.0才开始有的。  二、选购品牌   品牌过硬,最好是一线的大厂,由于和Google合作紧密,得到Android最新版代码和研发效率等因素要好很多,知名品牌的固件升级有保障。 目前摩托罗拉的Xoom已经有Android 3.1固件了,三星Galaxy Tab 10.1也将会在近期上市,而Acer A500和ASUS TF101由于存在国行升级固件相对较慢,建议购买台版、港行或欧美的这两个厂商表示本月推出Android 3.1固件。  三、经济问题  目前Android 3.0平板价格分为两个档次,比较有意思的是这两个档次是不同领域的制造商  1. 5000元左右的  手机制造商: 摩托罗拉Xoom、三星Galaxy Tab 10.1和LG Optimus Pad  2. 3500元左右的 笔记本制造商 华硕Eee Pad Transformer、宏碁Iconia Tab A500   从上面来看台湾的厂商价格比较亲民,由于华硕和宏碁拥有多年的笔记本电脑和PC制造工艺,设计平板走线拥有丰富的经验,同时硬件配置上丝毫不逊色于欧美厂商。

Android JNI学习指导 Android开发技术

  很多网友对Android JNI和C++开发相关的技术很感兴趣,由于JNI大部分技术都是针对Windows PC的,对于Android的JNI学习除了SDK中的一些例子外,其实大家完全可以通过Android源码中的base.git中根目录下的/core/jni文件夹下的cpp和h文件进行学习,这里是Google Android开发团队进行编码,在代码质量和稳定性方面都有保障,这里Android123推荐大家通过这些代码了解底层相关实现细节,虽然是C++的代码不过编码风格还是C的实现,对于基础学习,Android开发来说,开源方面的优势大幅超越封闭的iPhone和Windows Phone,同时对于间接使用Android Dalvik的Ophone OS 3、WebOS来说还是相当好的,当然有兴趣的网友可以移植Dalvik到Meego。

Nokia确认放弃Meego,可能考虑Android Android开发技术

  诺基亚确认将会放弃Meego,虽然N9和N950的发布可能让我们看到Nokia的Linux战略,但是近期诺基亚CEO埃洛普确认将放弃MeeGo系统,这无疑让我们想到N9或N950将成为N900,目前来看市场上似乎单独的手机厂商推出操作系统竞争力不是很大,比如三星Bada,早期时间摩托罗拉推出过Linux内核的智能机但最终还是失败了,不过让我们意外的是有一个未确认真实性的是Nokia正在测试一款代号为 NB72 的Android手机,使用了Android 2.2内核,虽然外观有些像N9但是摄像头的位置并不是在右下方,从运行界面来看可能是 运行下Android的恶作剧,当然也不排除Nokia不考虑Android,毕竟作为硬件厂商跑更多的操作系统,对于各个系统的发展有相关的制衡作用,目前Nokia维护着Symbian、Meego以及Windows Phone 7,最终加入Android的设计,看来Nokia的产品线还是不少的。    目前Nokia对Meego的态度是这样的,虽然N9运行的是Meego,但是应用使用了Qt去编写,除了Windows Phone 7无法支持Qt运行库外,Symbian和Meego还是能够跑Qt的,至于Meego上加个Android的Dalvik,目前来看由于Google的对于底层框架的在Android版本上 越来越紧密,即使Meego跑了Dalvik虚拟机,兼容性将会打打折扣,所以不要对Meego抱有太大的期望。

Android隐私问题可通过Hook技术解决 Android开发技术

  越来越多的Android隐私问题,使得我们考虑如何保护系统安全,对于Android平台的防火墙,可以考虑Rootkit惯用的Hook技术来实现一个简单的防火墙,这样我们可以对敏感的服务,比如说LocationManager、TelephonyManager和SmsManager以及CameraManager等可能产生隐私泄露的行为进行拦截,目前来看在Android上实现这些技术已经不是问题,但Root权限的请求是必须的。由于Android的API相对于其他平台更开放,如果Google推出一套权限的反病毒框架,安全和功能开放上可以做的更有竞争力。

URL编码问题 Android开发技术

  在Android平台上做Web上传等操可以考虑对于URL编码尽量做UTF-8的处理,这样空格和中文字符将会被转换,比如空格处理为20%,Android应用可以直接使用Java的URLEncoder.encode(strUrl , "utf-8"); 来处理,比如说 String sUrl="http://www.android123.com.cn/中文/";String sDest=URLEncoder.encode(sUrl , "utf-8");  执行完后sDest将会返回编码好的URL,同时上传图片可以考虑先处理为Base64编码。

Android文件下载方式选择 Android开发技术

  对于Android应用中涉及到文件下载来说,我们可以使用Java运行库的URL库或Apache的HttpXXX的处理。经过长期的测试JRE中的 URLConnection 的稳定性不是很好,这主要是封装问题底层仍然使用的是Apache的库,而从Android 2.2开始引入的AndroidHttpClient使用的是Apache库的方式下载,在整体稳定性和可靠性方面有了很大的提升,这里Android123推荐大家使用Apache。    一个完善的文件下载类需要更多的HTTP协议通讯,Apache库对于Web提交(上传)或Web下载有着强大的功能,比如说断点需要主要是获取Server上文件的大小,通过Http的Header查找Content-Length即可设置需要获取的文件块。同时Android对于InputStream流有个小bug在慢速网络的情况下可能产生中断,可以考虑重写FilterInputStream处理skip方法来解决这个bug。

山寨平板的480×800远比手机的480×800大 Android开发技术

   很多网友不明白很多Android山寨平板均使用了480×800的分辨率,但是相对于手机来说明显比手机的480×800的WVGA显示的内容要多和大,这点Android123提示大家还是要从DPI这样的问题入手了,在系统中存在DPI这个概念是依赖于设备的,同时显示系统的density也决定了分辨率,所以一般的7英寸平板电脑显示的480×800分辨率,完全可以放心,远大于你的手机。最简单的方法可以观察山寨平板的桌面图标显示数量或开个浏览器便可知晓。

Android Dock底座应用开发 Android开发技术

  很多网友可能发现部分Android手机或平板支持底座,目前比较主流的有摩托罗拉系列,中低端的Milestone和Milestone 2代均可以使用充电底座或多媒体底座,网购大概50元左右。而中高端的Atrix 4G则支持HD或物理键盘底座,在我们连接底座后,一般使用官方固件的Android手机会自动切换到底座的桌钟模式,会显示提前、时间或闹铃等信息,如果通过代码获取底座插拔状态呢? 下面Android123给大家一个简单的思路。    在Androidmanifest.xml文件中,我们在自己应用的主activity中,加入下面的代码              <meta-data android:name="android.dock_home" android:value="true" />               <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.DEFAULT" />                <category android:name="android.intent.category.LAUNCHER" />                <category android:name="android.intent.category.DESK_DOCK" />            </intent-filter>   大家可以看到,上面的     <action android:name="android.intent.action.MAIN" /> 和  <category android:name="android.intent.category.DEFAULT" /> 以及  <category android:name="android.intent.category.LAUNCHER" /> 均已经有了在默认创建的工程中。    不过对于底座应用的支持还有几个action,这些是从API Level 8开始支持的,对应Android 2.2的SDK,大家可以在android.app.UiModeManager类中找到比较重要的4个广播事件,ACTION_ENTER_CAR_MODE 进入行车模式,ACTION_EXIT_CAR_MODE  退出行车模式,其中 ACTION_ENTER_DESK_MODE  就是连接底座的广播,ACTION_EXIT_DESK_MODE 则是断开底座。

Android多线程断点续传下载文件类设计 Android开发技术

   对于Android平台,很多网友可能考虑开发一个软件商店,对于Android平台上如何实现断点续传操作呢? 这里Android123给大家一些思路和原理的介绍,同时在Android手机上要考虑的一些事情。   1. 流量控制,获取运营商的接入方式,比如说使用移动网络接入,尽可能的提示用户切换WiFi或提示,限制下载的流量以节省话费。   2. 屏幕锁控制,屏幕锁屏后导致应用会被挂起,当然Android提供了PowerManager.WakeLock来控制。   3. 对于断点续传,这要追溯到Http 1.1的特性了,主要是获取文件大小,如果这个无法读取的话,那么就无法断点续传了只能使用chunked模式了,当然获取远程服务器上文件的大小可以通过Http的响应头查找Content-Length。   4. 获取上次文件的更改时间,对于断点续传来说比较有风险的就是 继续下载的文件和早期下载的在server上有变动,这将会导致续传时下载的文件版本和原始的不同,一般有两种解决方法,早期我们配置服务器时通过Last-Modified这个http header获取文件上次修改时间,不过本次Android开发网推荐使用更为强大的ETag,ETag一般用于解决同一个URL处理不同返回相应,比如Session认证,多国语言,以及部分黑帽的SEO中。具体的实现大家可以参考RFC文档。   5. 考虑服务器的3xx的返回,对于专业的下载文件服务器会考虑到负载平衡问题,这就涉及到重定向问题,处理重定向使用Android的Apache库处理比较好。   6. 至于多线程,这里CWJ提示大家可能存在独立的线程下载一个文件,和多个线程分块下载单个文件之分,其中后者需要考虑上次下载数据是否存在问题,同时如果服务器不支持文件大小获取,则无法通过分段下载数据,因为不知道如何分段,所以在chunked模式中,只能使用一个线程下载一个文件,而不是多个线程下载一个文件。   7. 下载后的数据效验,可以考虑CRC等方式,当然对于一般的传输只要逻辑不出现问题,基本上不会有偏差。   8. 考虑DRM问题,这个问题在国内用的比较少,而国外的受数字保护的音乐和视频,需要额外的获取证书等。   9. 重试次数,对于一个文件可能在本次网络传输中受到问题,尤其是移动网络,所以可以设置一定的重试次数,让任务单独的走下去。   10. 线程开发方式,这里如果你的Java基础比较好,推荐直接使用Java并发库API比较好,如果过去只做过Java开发使用Thread即可,如果Java技术不过关可以Android封装的AsyncTask。   有关完善的多点续传的示例,Android123将在近期提供源码。

Android AIDL远程服务使用示例 Android开发技术

  很多网友来函表示对Android AIDL不是很理解,这里Android123准备了一个简单的例子,帮助大家了解Android上比较强大的远程服务设计吧。   一、为什么要使用AIDL,他的优势有哪些呢?   AIDL服务更像是 一个Server,可以为多个应用提供服务。由于使用了IDL这样类似COM组件或者说中间语言的设计,可以让后续的开发者无需了解内部,根据暴漏的接口实现相关的操作,AIDL可以工作在独立的进程中。  二、学习AIDL服务需要有哪些前置知识?   作为Android上服务的扩展,首先你要了解Android Service模型,Android Serivice我们可以分为两种模式,三个类型,1.最简单的Service就是无需处理onBind方法,一般使用广播通讯,效率比较低。2. 使用Binder模式处理Service和其他组件比如Activity通讯,Android开发网提示对于了解了Binder模式的服务后,开发AIDL远程服务就轻松容易的多。  三、具体实例,我们以com.android123.cwj.demo为工程名,首先在工程目录的com.android123.cwj目录下创建一个ICWJ.aidl文件,内容为   package com.android123.cwj;   interface ICWJ {   String getName();  }    如果格式AIDL格式没有问题,在Eclipse中ADT插件会在工程的gen目录下会自动生成一个Java实现文件。  在Service中代码如下:  public class CWJService extends Service {  public static final String BIND = "com.android123.cwj.CWJService.BIND";   public String mName="android123";  private final ICWJ.Stub mBinder = new ICWJ.Stub()  {      @Override      […]

Android ADK开发包示例开源代码 Android开发技术

   对于Android来说除了SDK和NDK外,ADK被称为第三大革命型,Android ADK通过USB为传输方式可以和外设进行通讯,基于Google的Open Accessory Protocol(开放式附件协议) 可以让你的Android设备和车载系统、家电进行通讯,当然ADK还可以让Android设备支持各种常用USB设备,比如扫描仪、打印机、键盘、鼠标等。在Android开源项目GIT官网上已经开设了 device/google/accessory/arduino.gitdevice/google/accessory/demokit.git  这两个分支,其中demokit为演示包,可以让你轻松的掌握Android外设的开发技术,Android123提示整体的开发十分方便,Google已经封装的十分到位,整个操作类似串口通讯,还是基于字节数组的协议传输,如果你找到相关的硬件协议,USB无线网卡等设备都可以很好的和Android设备进行通讯。这里要提示的是目前仅在Android 2.3.4和Android 3.1或更高的系统支持。

Android NDK C++开发注意事项总结 Android开发技术

   相信Android开发者都喜欢用C++编写一些高效的应用,有关Android NDK的C++开发相关知识Android123总结如下:   1. 从Android NDK r5开始支持了STL Port,在这个版本开始就可以使用部分STL库的功能了,比如说vector、string摆脱c下面容易出现的数组未初始化、越界,增强应用的健壮性。   2. 很多网友包含了include <vector> 这样头,但仍然无法编译,这里你首先要检查当前文件是否为.cpp后缀,同时为了使用标准库必须加入 APP_STL := stlport_static 在Application.mk文件中。相关对应还有  system              使用默认最小的C++运行库,这样生成的应用体积小,内存占用小,但部分功能将无法支持 stlport_static      使用STLport作为静态库,这项是Android开发网极力推荐的 stlport_shared     STLport 作为动态库,这个可能产生兼容性和部分低版本的Android固件,目前不推荐使用。 gnustl_static      使用 GNU libstdc++ 作为静态库   默认情况下STLPORT是不支持C++异常处理和RTTI,所以不要出现 -fexceptions 或 -frtti ,如果真的需要可以使用gnustl_static来支持标准C++的特性,但生成的文件体积会偏大,运行效率会低一些。   3. 支持C++异常处理,在Application.mk中加入 LOCAL_CPPFLAGS += -fexceptions这句,同理支持RTTI,则加入LOCAL_CPPFLAGS += -frtti,这里Android123再次提醒大家,第二条说的使用gnustl静态库,而不是stlport   4. 强制重新编译 STLPort ,在Application.mk中加入 STLPORT_FORCE_REBUILD := true 可以强制重新编译STLPort源码,由于一些原因可能自己需要修改下STLPort库,一般普通的开发者无需使用此项。   5 Android目前最新的NDK版本为r6,相关的学习可以查看NDK中的Samples整体和在PC上开发没有太大的不同。

Android开始开放C/C++编写的应用 Android开发技术

   对于Android平台来说已经有迹象表明开放纯C/C++编写的应用,过去我们也介绍过今天就说下具体的吧,在NDK的Samples中名为native-activity的例子已经证实了这点,不过目前Android123提示大家,显示系统Android上提供的C++接口只有OpenGL了,一起来看看AndroidManifest.xml中的定义吧。不过必须在Android 2.2或更高的固件上才能运行。注意下面的minSDK设置的为8,同时application的android:hasCode=false表示了这个应用将没有Java代码。    <?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"        package="com.example.native_activity"        android:versionCode="1"        android:versionName="1.0">     <uses-sdk android:minSdkVersion="8" />        <application android:label="@string/app_name" android:hasCode="false">             <activity android:name="android.app.NativeActivity"                android:label="@string/app_name" android:configChanges="orientation|keyboardHidden">                <meta-data android:name="android.app.lib_name" android:value="native-activity" />            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application> </manifest>  从上面来看activity对应的name必须是android.app.NativeActivity,这点和AIDL中Service的name也写全package name是一个道理,否则无法找到。下面是纯C++的JNI代码了 #include <jni.h>#include <errno.h> #include <EGL/egl.h>   //这里JNI目前提供的支持,不是很多,只有GL家族作为显示系统了#include <GLES/gl.h> #include <android/sensor.h> //感应器的支持#include <android/log.h> #include <android_native_app_glue.h>  //这里Android123提示大家,c程序必须从main开始,这里必须包含这个,经过改进的伪入口点了。 #define […]

Android JNI开发疑点总结 Android开发技术

   很多Android新手对于JNI开发过程中的疑问不是很清楚,根据android123@163.com邮箱中反馈的内容我们整理如下:   1. JNI中,什么情况才处理jstring、jint、jobject这样的类型,其实通过NDK开发Android C++应用,大部分仍然是常规的cpp和h的标准写法,只有需要和Java层通讯的方法才包含了类似JNIEXPORT void JNICALL XXX这样的函数,大多数的逻辑和标准C/C++没有什么区别。  2. 我有一个在Windows上开发好的dll能否在Android上使用呢? 这里Android开发网提醒大家,对于dll这样的PE文件只能在Windows平台下使用,而Linux上的动态库so文件如果是PC上的也无法通过JNI在Android上调用,由于CPU的指令不同,手机上必须使用ARM交叉编译器生成才可以使用,而PC上的为x86或64位,即使是Hello World这样代码兼容性很强,也必须在NDK中重新编译才能在Android上使用。  3. 学习JNI的基础是什么,或者说什么顺序学习? 这点Android123推荐大家先了解Java的类型,和内部编码,然后学习C/C++语言,对于NDK r5开始支持的C++语言,这里Android开发网要和大家说下了,如果需要在JNI中调用Java的类,你可以学习下反射机制,同时C++ STL在NDK r5开始支持,这样开发应用维护起来更方便些。最后看下NDK的Samples下载Android源码Framework层基本上就没有什么大问题了。  4. 学习NDK最大的困难是什么? 这里Android123认为,国内网友大多数都在Windows下做开发工作,整个NDK环境需要Cygwin,同时mk这样的makefile编译脚本的手动编写可能不是很友好,这点Android开发网已经准备了一整套的Android开发工具,将在近期公开,帮助大家在PC辅助开发Android应用,同时常见问题提供了相应的链接。   5. 在Android JNI用处大吗? 对于大多数开发者来说可能主要用于OpenGL游戏设计上,不过对于纯运算,算法上C语言比Java有着很多天生的优势,这点不容置疑,多一门技术多一个出路嘛,整个Android源代码十分庞大,开源的力量最终还是能打败更封闭的Windows Phone和iOS的。

Android NDK开发相关问题汇总 Android开发技术

  有关Android NDK开发的相关问题,仍然有不少网友存在问题,下面就常见的问题Android123总结如下:   1. Android 1.5如果调用C++库,都支持哪些方法?   由于Android 1.5 API Level为3,当初提供的类和函数可以在NDK下查看include目录中找到<cstddef>、   <new>、  <utility> 和   <stl_pair.h> 可以看到都是语言运行库和基本的数据类型。   2. NDK下的log支持,这里大家可以包含<android/log.h>这个头文件,同时在mk文件中加入LOCAL_LDLIBS := -llog 这个库文件即可。   3. NDK下处理Zip文件的压缩、解压处理通过zlib库来解决,Android内置了zlib库可以通过包含<zlib.h> 和 <zconf.h>两个头文件解决,LOCAL_LDLIBS := -lz。   以上的都可以在Android 1.5或更高的固件上运行,而对于Android 2.0到2.1之间的三个版本主要是OpenGL ES的支持。

Android应用开发趋势之HTML篇 Android开发技术

  对于很多新手Android应用程序开发出一些不错的UI可能有些难度,这里Android123推荐大家不妨试试更灵活的HTML作为UI,通过html+css+javascript方式,可以灵活开发出各种吸引人的UI,你甚至可以考虑JQuery这样的组件,老外已经写了本名为 《Building Android Apps with HTML, CSS, and JavaScript 》的图书,目前简体中文版仅售28元,可以通过搜索 《使用HTML、CSS和JavaScript开发Android程序》购买到。   如果你是刚入门Android开发,做一些简单有趣的应用,可以尝试下html方式,最大的特点就是高效快捷。网上有很多实用的Javascript代码段,直接引用就可以做出不少应用来。

Android开发知识点总结 Android开发技术

  1. 如何让你的应用优先安装到SD卡上?    从Android 2.2 SDK开始多出了一个属性在AndroidManifest.xml中,在manifest节点加入android:installLocation="preferExternal"即可,当然要想让你的应用真正的安装到SD卡上,用户最终的固件为2.2,同时用户选择安装时在SD卡上。一般只有大型游戏或非重要的系统级应用选择安装在SD卡上,SD卡的读写要慢于ROM且更费电,所以重要的应用,比如闹铃提醒是不能设置安装到SD卡的。   2. 如何防止Service被系统回收?   对于Service被系统回收,一般做法是通过提高优先级可以解决,在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时实用于广播,而Android123推荐大家如果你的应用很重要,可以考虑通过系统常用intent action来触发。   3.  Android NDK本地应用效率提升方法   对于C/C++的应用,这里Android开发网提示按照C++的习惯,简单反复调用的函数可以声明为inline,尽量少用虚函数,C++ STL的Stream效率不是很高,vector的内存管理要考虑仅分配不释放问题,如果需要涉及和Java通讯,则JNI的执行开销比较大,同时IPC通讯方法在本地端使用IBinder比较高效,当然如果你的技术不是很过关,Socket也是可以的,也更规范些吧。

开发者眼中的Windows Phone和Android Android开发技术

   对于开发者选择Windows Phone和Android呢? 下面就Android123的对实战开发不同做简单对比:   一、用户界面   Windows Phone的用户界面Metro UI我们算作色块好了,桌面主题无法定制,即使是每个厂商的主题,必须单独运行一个程序,比如HTC Hub。相对于Android来说桌面整个就可以被替换掉,这里分为三部分吧:1. 整个桌面主题 2.顶部滑动的状态栏 3. 桌面appWidget小插件。 Android用户可以放置天气预报、微博、开关WiFi小插件到桌面上,而WP7每次都要进入相应的程序,或进入到系统设置中才能开关WiFi十分繁琐。整体流畅性,Android设备硬件配置达到了512MB RAM和或者说同等级的WP7来说,体验上没有任何问题。市面上很多低端山寨Android设备严重影响了体验度,尤其是小RAM和ARM11的这种廉价硬件,要知道WP7最低配置就是1GHz的A8处理器。   二、电话短信    电话短信在界面上 Android和Windows Phone 7使用了会话方式,当然这些从iOS时代就开始了,要说模仿可能是抄袭Apple的,对于开发者角度来说,你可以在Android平台做出 归属地显示、来电防火墙,短信防火墙,而WP7那SDK发短信都要调用系统界面,所以这方面WP7上目前无法开发出相应的通话管理软件,如果你是商务人士可能会比较郁闷吧。   三、文件管理   WP7和iPhone一样,文件传输都需要借助PC上的专用软件,WP7需要Zune的支持,而iPhone则需要iTunes,它们能传输的只有 照片、音乐、应用、视频和电子书,安装软件除了手机内置的应用商店外,只有PC上的官方工具如Zune,否则还要考虑破解越狱。WP7越狱后能做的也只有安装软件了,并不开放API,这点和Android有本质的区别,在Android上你可以使用APK安装器装软件,无论是PC还是手机上。任何一部Android手机都支持U盘模式,可以方便的当做U盘来说用,而WP7默认插入电脑是没有反应的,还需要自己去DIY。   四、开发支持   WP7的开发工具为VS2010+Dot Net Framework 4.0,但是比较限制的是必须Vista或Win7才能开发,虽然XP下能破解安装SDK,但那只能是帮助手机越狱,而开发上还是需要回到Vista或Win7,这点Android上支持Windows、Mac OS和Linux,更可笑的是,微软没有开发注册账户,真机还无法部署软件,同时无法对真机截图,不知道微软怎么想的,还必须要上模拟器吗? 虽然Android的Eclipse开发环境安装麻烦些,但是没有这些可笑的限制,至少给了我们希望,而微软一竿子打死。

Android SDK目录结构和工具介绍 Android开发技术

   Android SDK目录下有很多文件夹,主要都是干什么的呢?    1. add-ons 这里面保存着附加库,比如Google Maps,当然你如果安装了Ophone SDK,这里也会有一些类库在里面。    2. docs 这里面是Android SDK API参考文档,所有的API都可以在这里查到。    3. market_licensing 作为Android Market版权保护组件,一般发布付费应用到电子市场可以用它来反盗版。    4. platforms 是每个平台的SDK真正的文件,里面会根据API Level划分的SDK版本,  这里就以Android 2.2来说,进入后有一个android-8的文件夹,android-8进入后是Android 2.2 SDK的主要文件,其中ant为ant编译脚本,data保存着一些系统资源,images是模拟器映像文件,skins则是Android模拟器的皮肤,templates是工程创建的默认模板,android.jar则是该版本的主要framework文件,tools目录里面包含了重要的编译工具,比如aapt、aidl、逆向调试工具dexdump和编译脚本dx。   5. platform-tools 保存着一些通用工具,比如adb、和aapt、aidl、dx等文件,Android123提示,这里和platforms目录中tools文件夹有些重复,主要是从android 2.3开始这些工具被划分为通用了。   6. samples 是Android SDK自带的默认示例工程,里面的apidemos强烈推荐初学者运行学习,对于SQLite数据库操作可以查看NotePad这个例子,对于游戏开发Snake、LunarLander都是不错的例子,对于Android主题开发Home则是android m5时代的主题设计原理。   7. tools 作为SDK根目录下的tools文件夹,这里包含了重要的工具,比如ddms用于启动Android调试工具,比如logcat、屏幕截图和文件管理器,而draw9patch则是绘制android平台的可缩放png图片的工具,sqlite3可以在PC上操作SQLite数据库,而monkeyrunner则是一个不错的压力测试应用,模拟用户随机按键,mksdcard则是模拟器SD映像的创建工具,emulator是android模拟器主程序,不过从android 1.5开始,需要输入合适的参数才能启动模拟器,traceview作为android平台上重要的调试工具。   8. usb_driver 顾名思义,保存着android平台google官方机型的驱动如nexus one、nexus s,同时也有一些老机型驱动的支持,比如说htc dream、htc magic和motorola的droid。

强制保持Android Activity状态 Android开发技术

  有的时候我们的Android在应用运行时,可能需要临时退出,比如突然接到来电,但是切换回来界面时,可能Activity又重新从第一个界面开始显示,并不是刚才用户操作的界面,这里可以通过在androidmanifest.xml中在需要保留的activity中添加android:alwaysRetainTaskStat="true" 这句即可,这里Android123还要提醒大家的是有时候你的应用可能会产生多个实例,你还可以在主Activity中加入android:launchMode="singleInstance" 来强制让系统仅运行一个实例。

Activity状态保存增强版 Android开发技术

  对于Activity状态保存上一次在 强制保持Android Activity状态 一文中我们做了讲解,但是还有一种更坏的情况,比如你接的来电时间比较长,由于用户的Android设备RAM较少,你的应用被Java VM的GC给回收了,下次用户再切换回,由于你的应用已经被系统结束了任务,对于游戏来说这可能是致命的。   所以通过重写Activity的onSaveInstanceState(Bundle outState) 方法可以在Android系统触发结束任务时,保存当前Activity的值,而下次进入该Activity时,可以通过重写 onRestoreInstanceState(Bundle savedInstanceState) 来恢复数据,参数Bundle支持常见的String、Integer、Double、以及字节数组,具体的使用实例可以参考 Android开发网早期文章 onSaveInstanceState和onRestoreInstanceState的用处

在Activity之间传递复杂类型 Android开发技术

  很多Android开发者对于Activity中如何传递复杂的类型不是很清楚,这里Android123再帮刚入门的开发者整理下。对于传递   一、实现Parcelable接口    对于Android来说传递复杂类型,主要是将自己的类转换为基础的字节数组,Activity之间传递数据是通过Intent实现的,对于二进制数据,传递的参数为putExtra(String name, Parcelable value) ,比如Bitmap类就实现了Parcelable接口,如果需要在Activity中传递图片,可以直接用Bitmap类型,当然如果本身是Drawable你可以先转化为Bitmap,可以参考 Bitmap和Drawable相互转换方法 一文。   相关的Intent方法还有 putExtra(String name, Parcelable[] value)  // 传递一个Parcelable数组putExtra(String name, Bundle value)  //传递一个Bundle对象 putParcelableArrayListExtra(String name, ArrayList<? extends Parcelable> value)  //传递一个实现Parcelable接口的对象数组putStringArrayListExtra(String name, ArrayList<String> value)  //传递一个字符串数组putIntegerArrayListExtra(String name, ArrayList<Integer> value)  //传递一个整形数组。   这里Android开发网提示大家,Integer这些装箱类型,Intent还实现了 putExtra(String name, int[] value)  这样的基础类型数组,同时Parcelable效率比标准的Java序列化更高,同时还被用作在AIDL中交换数据,所以掌握Parcelable这样的显示序列化技术,可以大幅提高数据交换性能。   二、使用全局单例模式   由于Android中Activity传递主要靠Intent这个类,Intent类内部传递数据的效率仍然需要拷贝,如果数据量很大,还可以考虑使用Singleton Pattern单例模式定义一个全局的静态类,这样传递的效率最高,大家可以看下Java设计模式,了解其中的妙用。   三、实现Serializable接口    如果你学习过传统的Java,则可以通过串行化技术,实现Serializable接口,其实这个原理和Parcelable差不多,均将自己的类转换为基本的类型比如说字节数组。在Android中不是很实用,这里不再赘述,在Intent中使用Intent  putExtra(String name, […]

预防Android内存泄露 Android开发技术

  对于很多处理图形相关的Android开发者来说,大的Bitmap对象可能直接导致软件崩溃,Android平台如何防止内存泄露呢? 目前来说Android设备的RAM可能差距比较大,很多低端配置的256MB RAM或512MB RAM由于运行了太多的后台任务或HTC Sense这样的主题导致了处理一些高像素的图片,比如500w或800w像素的照片很容易崩溃。   1. 判断目标设备Dalvik VM内存情况   通过 java.lang.Runtime类的 long  freeMemory() 方法可以获取当前进程的RAM可用情况,Runtime类需要  getRuntime() 方法来实例化。  比如获取最大可用RAM 为 Runtime.getRuntime().maxMemory();   2. Bitmap对象在打开时可以考虑先缩小图片   通过减少工作区域可以有效的降低RAM使用,由于在内存中是DIB方式,可以想象ARGB的图像占用内存为 4*height*width,比如500万像素的图片,占用内存就是500×4=2000万字节就是19MB左右。同时Java VM的异常处理机制和绘图方法可能在内部产生副本,最终消耗的运行内存是十分庞大的,对于图片打开时就进行缩小可以使用 android.graphics.BitmapFactory的相关方法来处理,这里参考Android123早期文章,Android缩略图类源代码 即可  3. 及时的显示执行Bitmap的recycle方法,以及是当时可以调用Runtime的gc方法,提示虚拟机尽快释放掉内存

setpref轻松修改preferences文件 Android开发技术

  有时候我们使用adb shell想更改一些应用的配置信息,Android上每个应用android.content.SharedPreferences类保存的位置对应apk安装后的/data/data/<package name>/shared_prefs 目录中,由于使用了key-value的pair方式存储,这里android使用的是xml文件,在linux shell下编辑不是很方便,不过通过 setpref 命令可以很轻松的修改。   1. 首先chmod 777 设置文件有写权限。   2. 为了防止共享违例,可以先killall <package name> 来结束掉任务。   3. 比如说设置 paid为true,则在/data/data/com.android123.test/shared_prefs目录中执行"setpref cwj boolean paid true  这句的意思是,设置cwj这个xml文件的paid属性值为true。   当然以上所有步骤额执行都需要root权限,一堆对于开发调试帮助比较大。

Android语音便签快速调用-内置录音程序 Android开发技术

  对于Android来说,官方提供了一个简单的录音程序,可以很方便的实现一个语音便签功能,大约95%的Android设备均自带了官方的这个录音应用,调用方法为   1. 首先在Activity中定义一个Activity返回结果句柄   private static final int CWJ_RECORD = 1987;   2. 接下来只需要执行Media.RECORD_SOUND_ACTION这个Action即可启动Android内置的录音程序。   Intent intent = new Intent(Media.RECORD_SOUND_ACTION);  startActivityForResult(intent, CWJ_RECORD); // Android123提示大家,这里使用startActivityForResult获取结果,不能简单的startActivity,否则无法获取保存录音文件的位置。   3. 最后处理 Activity的 onActivityResult 方法,代码为   @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {   if (resultCode == RESULT_OK) {   switch (requestCode) {   case CWJ_RECORD:              String dataUri=getIntent().getDataString();          String dataFile=data.getDataString() ; […]

100% Secure Checkout

PayPal / MasterCard / Visa