Androiod 开发精要 笔记

在Android中,所有的组件都是在主线程上构造的。因此,Service.onStartCommand函数的执行会阻塞主线程。如果涉及数据库读写、网络通信、复杂运算等耗时操作,那么就需要将相关操作放入独立的进程或线程中去执行。

将组件放入独立的进程中,可以通过配置文件的process参数来实现,代码如下:

 
 
  1. // 在service配置信息中,增加process  
  2. <service android:name="SimpleService" 
  3. android:process=":a_unique_process_name"/> 

但这样的方式会增加进程开销。因此,另一种可行的策略是在服务组件中另起一个独立的线程,将那些耗时又费力的操作交给它来打理。

最简单的实现策略是通过派生android.app.IntentService来执行服务组件中的处理逻辑。如图3-8所示,IntentService的实现原理非常简单。它本身是android.app.Service的子类,当启动时会在Service.onCreate函数中建立一个后台线程,该线程通过其独立的消息循环在后台等待事件。当Service.onStartCommand函数接到相关的Intent参数时,主线程会将其中的内容打包发送到后台线程中,在Service.onHandleIntent函数中进行处理。从实现来看,只需把本应放在Service.onStartCommand中执行的逻辑内容挪到Service.onHandleIntent中即可。

Parcel序列化后的数据是齐位的二进制流,如此设计是为了效率而不是为了灵活性。这就意味着,写入和读取数据的顺序与类型必须完全一致,稍有偏差,就会触发异常。如果需要传输的数据随着场景的不同有很大的变动,可以选择使用android.os.Bundle对象,它会按照键值对的模式将信息写入二进制数据流,以提高灵活性。

进程间通信机制是Android的重要基础,被广泛地应用在各类核心机制中,因此Parcel类型的实现主要通过C++来完成,上层Parcel对象通过JNI接口进行调用,从而提高了序列化相关操作的执行效率,确保Android系统可以高效运行。



在实际开发中,通常会在界面组件Activity.onResume函数中进行触发器组件的注册,而在Activity.onPause函数中注销对应的触发器组件。


数据源组件和其他组件一样,都构造于应用主线程中。直接对它进行数据的读写操作可能会阻塞主线程,从而影响应用与用户的交互。因此,当涉及大量的读写和查询时,调用者可以通过android.content.AsyncQueryHandler对象来实现对数据源组件的异步访问。

调用时,可以通过AsyncQueryHandler.startXXX系列方法将请求打包发送到后台线程,当相关处理完成后,会将结果异步回传给主线程并调用AsyncQueryHandler.onXXXComplete方法通知调用者。调用者在每次请求时,需要传入一个整型值token作为这次请求的标识,当该请求完成后进行回调时,会将token传回,帮助调用者确定这是哪一次请求。



ContentResolver相当于数据源组件的DNS和本地代理,它负责将各个URI定位到具体的数据源组件,并经由它对数据源进行增、删、改、查等操作。

当ContentResolver收到数据操作请求时,会先根据URI的信息去查找对应的数据源组件。ContentResovler对象中,有一个数据源组件的缓存对象ProviderMap,它是一个哈希表,存储各个URI对应到数据源组件对象。如果ContentResolver在缓存中未能查到对应的数据源组件,则会将查找请求发送给组件管理服务,该服务会负责查找到对应数据源组件的信息,并在ContentResolver中构造对象缓存。




Java虽有运行时二次编译的机制,但并非是解释型的语言,它的运行时加载单元是类。因此,在编写SDK版本相关代码时,要用类而不是函数为隔离单位。比如SDK版本的实现,可以按照如下格式进行划分:

 
 
  1. class MethodInLowSdk {  
  2.     public static void aMethod();  
  3. };  
  4.  
  5. class MethodInHighSdk {  
  6.     public static void aMethod();  
  7. }; 

在使用时通过android.os.Build.VERSION.SDK_INT判断SDK版本,从而决定使用哪个类中的方法,比如:
 
 
  1. void CallAMethodByVersion() {  
  2.     if (android.os.Build.VERSION.SDK_INT > low_sdk) {  
  3.         MethodInHighSdk.aMethod();  
  4.     } else {  
  5.         MethodInLowSdk.aMethod();  
  6.     }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值