`

android源码解析--Message

阅读更多

看下类定义:

 

[java] view plaincopy
  1. Defines a message containing a description and arbitrary data object that can be sent to a Handler. This object contains two extra int fields and an extra object field that allow you to not do allocations in many cases.  
  2.   
  3. While the constructor of Message is public, the best way to get one of these is to call Message.obtain() or one of the Handler.obtainMessage() methods, which will pull them from a pool of recycled objects.  

 

 

定义一个包含任意类型的描述数据对象,此对象可以发送给Handler。对象包含两个额外的int字段和一个额外的对象字段,这样可以使得在很多情况下不用做分配工作。尽管Message的构造器是公开的,但是获取Message对象的最好方法是调用Message.obtain()或者Handler.obtainMessage(), 这样是从一个可回收对象池中获取Message对象。

 

[java] view plaincopy
  1. public final class Message implements Parcelable   


Message类是个final类,就是说不能被继承,同时Message类实现了Parcelable接口,我们知道android提供了一种新的类型:Parcel。本类被用作封装数据的容器,封装后的数据可以通过Intent或IPC传递。 除了基本类型以外,只有实现了Parcelable接口的类才能被放入Parcel中。

 

看一下全局变量:

 

[java] view plaincopy
  1. /** 
  2.      * User-defined message code so that the recipient can identify  
  3.      * what this message is about. Each {@link Handler} has its own name-space 
  4.      * for message codes, so you do not need to worry about yours conflicting 
  5.      * with other handlers. 
  6.      */  
  7.     public int what;  
  8.   
  9.     /** 
  10.      * arg1 and arg2 are lower-cost alternatives to using 
  11.      * {@link #setData(Bundle) setData()} if you only need to store a 
  12.      * few integer values. 
  13.      */  
  14.     public int arg1;   
  15.   
  16.     /** 
  17.      * arg1 and arg2 are lower-cost alternatives to using 
  18.      * {@link #setData(Bundle) setData()} if you only need to store a 
  19.      * few integer values. 
  20.      */  
  21.     public int arg2;  
  22.   
  23.     /** 
  24.      * An arbitrary object to send to the recipient.  When using 
  25.      * {@link Messenger} to send the message across processes this can only 
  26.      * be non-null if it contains a Parcelable of a framework class (not one 
  27.      * implemented by the application).   For other data transfer use 
  28.      * {@link #setData}. 
  29.      *  
  30.      * <p>Note that Parcelable objects here are not supported prior to 
  31.      * the {@link android.os.Build.VERSION_CODES#FROYO} release. 
  32.      */  
  33.     public Object obj;  
  34.   
  35.     /** 
  36.      * Optional Messenger where replies to this message can be sent.  The 
  37.      * semantics of exactly how this is used are up to the sender and 
  38.      * receiver. 
  39.      */  
  40.     public Messenger replyTo;  
  41.   
  42.     /** If set message is in use */  
  43.     /*package*/ static final int FLAG_IN_USE = 1;  
  44.   
  45.     /** Flags reserved for future use (All are reserved for now) */  
  46.     /*package*/ static final int FLAGS_RESERVED = ~FLAG_IN_USE;  
  47.   
  48.     /** Flags to clear in the copyFrom method */  
  49.     /*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAGS_RESERVED | FLAG_IN_USE;  
  50.   
  51.     /*package*/ int flags;  
  52.   
  53.     /*package*/ long when;  
  54.       
  55.     /*package*/ Bundle data;  
  56.       
  57.     /*package*/ Handler target;       
  58.       
  59.     /*package*/ Runnable callback;     
  60.       
  61.     // sometimes we store linked lists of these things  
  62.     /*package*/ Message next;  
  63.   
  64.     private static final Object sPoolSync = new Object();  
  65.     private static Message sPool;  
  66.     private static int sPoolSize = 0;  
  67.   
  68.     private static final int MAX_POOL_SIZE = 10;  

 

  1. what:用户定义消息代码以便收件人可以识别这是哪一个Message。每个Handler用它自己的名称空间为消息代码,所以您不需要担心你的Handler与其他handler冲突。
  2. arg1、arg2:如果只是想向message内放一些整数值,可以使用arg1和arg2来代替setData方法。
  3. obj:发送给接收器的任意对象。当使用Message对象在线程间传递消息时,如果它包含一个Parcelable的结构类(不是由应用程序实现的类),此字段必须为非空(non-null)。其他的数据传输则使用setData(Bundle)方法。注意Parcelable对象是从FROYO版本以后才开始支持的。
  4. replyTo:指明此message发送到何处的可选Messenger对象。具体的使用方法由发送者和接受者决定。
  5. FLAG_IN_USE:判断Message是否在使用( default 包内可见
  6. FLAGS_RESERVED:留个将来使用??
  7. FLAGS_TO_CLEAR_ON_COPY_FROM:明确在copyFrom方法
  8. 其他参数都比较简单,不详述

 

下面看obtain方法:

 

[java] view plaincopy
  1. /** 
  2.      * Return a new Message instance from the global pool. Allows us to 
  3.      * avoid allocating new objects in many cases. 
  4.      */  
  5.     public static Message obtain() {  
  6.         synchronized (sPoolSync) {  
  7.             if (sPool != null) {  
  8.                 Message m = sPool;  
  9.                 sPool = m.next;  
  10.                 m.next = null;  
  11.                 sPoolSize--;  
  12.                 return m;  
  13.             }  
  14.         }  
  15.         return new Message();  
  16.     }  


从全局池中返回一个新的Message实例。在大多数情况下这样可以避免分配新的对象。

 

在看它一系列的重载方法:

 

[java] view plaincopy
  1. /** 
  2.  * Same as {@link #obtain(Handler)}, but assigns a callback Runnable on 
  3.  * the Message that is returned. 
  4.  * @param h  Handler to assign to the returned Message object's <em>target</em> member. 
  5.  * @param callback Runnable that will execute when the message is handled. 
  6.  * @return A Message object from the global pool. 
  7.  */  
  8. public static Message obtain(Handler h, Runnable callback) {  
  9.     Message m = obtain();  
  10.     m.target = h;  
  11.     m.callback = callback;  
  12.   
  13.     return m;  
  14. }  
  15.   
  16. /** 
  17.  * Same as {@link #obtain()}, but sets the values for both <em>target</em> and 
  18.  * <em>what</em> members on the Message. 
  19.  * @param h  Value to assign to the <em>target</em> member. 
  20.  * @param what  Value to assign to the <em>what</em> member. 
  21.  * @return A Message object from the global pool. 
  22.  */  
  23. public static Message obtain(Handler h, int what) {  
  24.     Message m = obtain();  
  25.     m.target = h;  
  26.     m.what = what;  
  27.   
  28.     return m;  
  29. }  
  30.   
  31. /** 
  32.  * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, and <em>obj</em> 
  33.  * members. 
  34.  * @param h  The <em>target</em> value to set. 
  35.  * @param what  The <em>what</em> value to set. 
  36.  * @param obj  The <em>object</em> method to set. 
  37.  * @return  A Message object from the global pool. 
  38.  */  
  39. public static Message obtain(Handler h, int what, Object obj) {  
  40.     Message m = obtain();  
  41.     m.target = h;  
  42.     m.what = what;  
  43.     m.obj = obj;  
  44.   
  45.     return m;  
  46. }  
  47.   
  48. /** 
  49.  * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,  
  50.  * <em>arg1</em>, and <em>arg2</em> members. 
  51.  *  
  52.  * @param h  The <em>target</em> value to set. 
  53.  * @param what  The <em>what</em> value to set. 
  54.  * @param arg1  The <em>arg1</em> value to set. 
  55.  * @param arg2  The <em>arg2</em> value to set. 
  56.  * @return  A Message object from the global pool. 
  57.  */  
  58. public static Message obtain(Handler h, int what, int arg1, int arg2) {  
  59.     Message m = obtain();  
  60.     m.target = h;  
  61.     m.what = what;  
  62.     m.arg1 = arg1;  
  63.     m.arg2 = arg2;  
  64.   
  65.     return m;  
  66. }  
  67.   
  68. /** 
  69.  * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,  
  70.  * <em>arg1</em>, <em>arg2</em>, and <em>obj</em> members. 
  71.  *  
  72.  * @param h  The <em>target</em> value to set. 
  73.  * @param what  The <em>what</em> value to set. 
  74.  * @param arg1  The <em>arg1</em> value to set. 
  75.  * @param arg2  The <em>arg2</em> value to set. 
  76.  * @param obj  The <em>obj</em> value to set. 
  77.  * @return  A Message object from the global pool. 
  78.  */  
  79. public static Message obtain(Handler h, int what,   
  80.         int arg1, int arg2, Object obj) {  
  81.     Message m = obtain();  
  82.     m.target = h;  
  83.     m.what = what;  
  84.     m.arg1 = arg1;  
  85.     m.arg2 = arg2;  
  86.     m.obj = obj;  
  87.   
  88.     return m;  
  89. }  


都是先调用obtain()方法,然后把获取的Message实例加上各种参数。

 

 

[java] view plaincopy
  1. /** 
  2.  * Return a Message instance to the global pool.  You MUST NOT touch 
  3.  * the Message after calling this function -- it has effectively been 
  4.  * freed. 
  5.  */  
  6. public void recycle() {  
  7.     clearForRecycle();  
  8.   
  9.     synchronized (sPoolSync) {  
  10.         if (sPoolSize < MAX_POOL_SIZE) {  
  11.             next = sPool;  
  12.             sPool = this;  
  13.             sPoolSize++;  
  14.         }  
  15.     }  
  16. }  


向全局池中返回一个Message实例。一定不能在调用此函数后再使用Message——它会立即被释放。

 

 

[java] view plaincopy
  1. /** 
  2.  * Make this message like o.  Performs a shallow copy of the data field. 
  3.  * Does not copy the linked list fields, nor the timestamp or 
  4.  * target/callback of the original message. 
  5.  */  
  6. public void copyFrom(Message o) {  
  7.     this.flags = o.flags & ~FLAGS_TO_CLEAR_ON_COPY_FROM;  
  8.     this.what = o.what;  
  9.     this.arg1 = o.arg1;  
  10.     this.arg2 = o.arg2;  
  11.     this.obj = o.obj;  
  12.     this.replyTo = o.replyTo;  
  13.   
  14.     if (o.data != null) {  
  15.         this.data = (Bundle) o.data.clone();  
  16.     } else {  
  17.         this.data = null;  
  18.     }  
  19. }  


使此message跟参数o相似。浅拷贝数据域。不拷贝源message的链表字段,时间戳和目标/回调。

 

 

[java] view plaincopy
  1. /** 
  2.      * Return the targeted delivery time of this message, in milliseconds. 
  3.      */  
  4.     public long getWhen() {  
  5.         return when;  
  6.     }  

 

设置一个任意数据值的Bundle对象。如果可以,使用arg1arg2域发送一些整型值以减少消耗。

参考

         getData()

         peekData()


返回此消息的传输时间,以毫秒为单位。

 

[java] view plaincopy
  1. public void setTarget(Handler target) {  
  2.         this.target = target;  
  3.     }  


设置目标handler(接收其消息的Handler)。

 

 

[java] view plaincopy
  1. /** 
  2.   * Retrieve the a {@link android.os.Handler Handler} implementation that 
  3.   * will receive this message. The object must implement 
  4.   * {@link android.os.Handler#handleMessage(android.os.Message) 
  5.   * Handler.handleMessage()}. Each Handler has its own name-space for 
  6.   * message codes, so you do not need to 
  7.   * worry about yours conflicting with other handlers. 
  8.   */  
  9.  public Handler getTarget() {  
  10.      return target;  
  11.  }  


获取将接收此消息的Handler对象。此对象必须要实现Handler.handleMessage()方法。每个handler各自包含自己的消息代码,所以不用担心自定义的消息跟其他handlers有冲突。

 

 

[java] view plaincopy
  1. /** 
  2.     * Retrieve callback object that will execute when this message is handled. 
  3.     * This object must implement Runnable. This is called by 
  4.     * the <em>target</em> {@link Handler} that is receiving this Message to 
  5.     * dispatch it.  If 
  6.     * not set, the message will be dispatched to the receiving Handler's 
  7.     * {@link Handler#handleMessage(Message Handler.handleMessage())}. 
  8.     */  
  9.    public Runnable getCallback() {  
  10.        return callback;  
  11.    }  


获取回调对象,此对象会在message处理时执行。此对象必须实现Runnable接口。回调由接收此消息并分发的目标handler调用。如果没有设置回调,此消息会分发到接收handlerhandleMessage(Message)

 

 

[java] view plaincopy
  1. /**  
  2.      * Obtains a Bundle of arbitrary data associated with this 
  3.      * event, lazily creating it if necessary. Set this value by calling 
  4.      * {@link #setData(Bundle)}.  Note that when transferring data across 
  5.      * processes via {@link Messenger}, you will need to set your ClassLoader 
  6.      * on the Bundle via {@link Bundle#setClassLoader(ClassLoader) 
  7.      * Bundle.setClassLoader()} so that it can instantiate your objects when 
  8.      * you retrieve them. 
  9.      * @see #peekData() 
  10.      * @see #setData(Bundle) 
  11.      */  
  12.     public Bundle getData() {  
  13.         if (data == null) {  
  14.             data = new Bundle();  
  15.         }  
  16.           
  17.         return data;  
  18.     }  

 

 

获取附加在此事件上的任意数据的Bundle对象,需要时延迟创建。通过调用setData(Bundle)来设置Bundle的值。需要注意的是,如果通过Messenger对象在进程间传递数据时,需要调用Bundle类的Bundle.setClassLoader()方法来设置ClassLoader,这样当接收到消息时可以实例化Bundle里的对象。

         参考

                  peekData()

                  setData(Bundle)

[java] view plaincopy
  1. /**  
  2.  * Like getData(), but does not lazily create the Bundle.  A null 
  3.  * is returned if the Bundle does not already exist.  See 
  4.  * {@link #getData} for further information on this. 
  5.  * @see #getData() 
  6.  * @see #setData(Bundle) 
  7.  */  
  8. public Bundle peekData() {  
  9.     return data;  
  10. }  

 

getData()相似,但是并不延迟创建Bundle。如果Bundle对象不存在返回null。更多信息见getData()

         参考

                   getData()

                   setData(Bundle)

[java] view plaincopy
  1. /** 
  2.  * Sets a Bundle of arbitrary data values. Use arg1 and arg1 members  
  3.  * as a lower cost way to send a few simple integer values, if you can. 
  4.  * @see #getData()  
  5.  * @see #peekData() 
  6.  */  
  7. public void setData(Bundle data) {  
  8.     this.data = data;  
  9. }  

 

设置一个任意数据值的Bundle对象。如果可以,使用arg1arg2域发送一些整型值以减少消耗。

参考

         getData()

         peekData()

[java] view plaincopy
  1. /** 
  2.  * Sends this Message to the Handler specified by {@link #getTarget}. 
  3.  * Throws a null pointer exception if this field has not been set. 
  4.  */  
  5. public void sendToTarget() {  
  6.     target.sendMessage(this);  
  7. }  


Handler发送此消息,getTarget()方法可以获取此Handler。如果这个字段没有设置会抛出个空指针异常。

 

[java] view plaincopy
  1. void clearForRecycle() {  
  2.         flags = 0;  
  3.         what = 0;  
  4.         arg1 = 0;  
  5.         arg2 = 0;  
  6.         obj = null;  
  7.         replyTo = null;  
  8.         when = 0;  
  9.         target = null;  
  10.         callback = null;  
  11.         data = null;  
  12.     }  


default方法,包内可见,清空所有数据。

 

 

[java] view plaincopy
  1. /*package*/ boolean isInUse() {  
  2.      return ((flags & FLAG_IN_USE) == FLAG_IN_USE);  
  3.  }  
  4.   
  5.  /*package*/ void markInUse() {  
  6.      flags |= FLAG_IN_USE;  
  7.  }  


获取Message是否在使用和标记为使用。

 

构造方法:

 

[java] view plaincopy
  1. /** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}). 
  2.     */  
  3.     public Message() {  
  4.     }  


跟推荐使用Message.obtain()方法。

 

toString方法:

 

[java] view plaincopy
  1. public String toString() {  
  2.         return toString(SystemClock.uptimeMillis());  
  3.     }  
  4.   
  5.     String toString(long now) {  
  6.         StringBuilder   b = new StringBuilder();  
  7.           
  8.         b.append("{ what=");  
  9.         b.append(what);  
  10.   
  11.         b.append(" when=");  
  12.         TimeUtils.formatDuration(when-now, b);  
  13.   
  14.         if (arg1 != 0) {  
  15.             b.append(" arg1=");  
  16.             b.append(arg1);  
  17.         }  
  18.   
  19.         if (arg2 != 0) {  
  20.             b.append(" arg2=");  
  21.             b.append(arg2);  
  22.         }  
  23.   
  24.         if (obj != null) {  
  25.             b.append(" obj=");  
  26.             b.append(obj);  
  27.         }  
  28.   
  29.         b.append(" }");  
  30.           
  31.         return b.toString();  
  32.     }  

 

[java] view plaincopy
  1. public static final Parcelable.Creator<Message> CREATOR  
  2.             = new Parcelable.Creator<Message>() {  
  3.         public Message createFromParcel(Parcel source) {  
  4.             Message msg = Message.obtain();  
  5.             msg.readFromParcel(source);  
  6.             return msg;  
  7.         }  
  8.           
  9.         public Message[] newArray(int size) {  
  10.             return new Message[size];  
  11.         }  
  12.     };  


什么作用?

 

 

[java] view plaincopy
  1. public int describeContents() {  
  2.         return 0;  
  3.     }  

 

 

描述了包含在Parcelable对象排列信息中的特殊对象的类型。

返回值

         一个标志位,表明Parcelable对象特殊对象类型集合的排列。

[java] view plaincopy
  1. public void writeToParcel(Parcel dest, int flags) {  
  2.         if (callback != null) {  
  3.             throw new RuntimeException(  
  4.                 "Can't marshal callbacks across processes.");  
  5.         }  
  6.         dest.writeInt(what);  
  7.         dest.writeInt(arg1);  
  8.         dest.writeInt(arg2);  
  9.         if (obj != null) {  
  10.             try {  
  11.                 Parcelable p = (Parcelable)obj;  
  12.                 dest.writeInt(1);  
  13.                 dest.writeParcelable(p, flags);  
  14.             } catch (ClassCastException e) {  
  15.                 throw new RuntimeException(  
  16.                     "Can't marshal non-Parcelable objects across processes.");  
  17.             }  
  18.         } else {  
  19.             dest.writeInt(0);  
  20.         }  
  21.         dest.writeLong(when);  
  22.         dest.writeBundle(data);  
  23.         Messenger.writeMessengerOrNullToParcel(replyTo, dest);  
  24.     }  
  25.   
  26.     private final void readFromParcel(Parcel source) {  
  27.         what = source.readInt();  
  28.         arg1 = source.readInt();  
  29.         arg2 = source.readInt();  
  30.         if (source.readInt() != 0) {  
  31.             obj = source.readParcelable(getClass().getClassLoader());  
  32.         }  
  33.         when = source.readLong();  
  34.         data = source.readBundle();  
  35.         replyTo = Messenger.readMessengerOrNullFromParcel(source);  
  36.     }  


将类的数据写入外部提供的Parcel中和从Parcel中读取数据。

分享到:
评论

相关推荐

    sinch-android-rtc-3.12.3源码

    《Sinch Android RTC 3.12.3 源码深度解析》 Sinch Android RTC 3.12.3 是一个强大的实时通信库,专为Android平台设计,提供了丰富的功能,包括语音通话、视频通话以及即时消息传递。这款开源源码对于Android开发者...

    asmack-android-19-source-0.8.10

    《ASMACK源码解析——基于Android 19的0.8.10版本》 ASMACK,全称为Asynchronous Smack,是Smack库的扩展,专为Android平台设计,用于处理XMPP(Extensible Messaging and Presence Protocol)协议。XMPP是一种基于...

    Android源码解析

    ### Android源码解析知识点概述 #### 公共技术点概览 - **Java反射** - Java反射机制允许运行时检查类、接口、字段和方法的信息,并能够动态地调用方法和修改字段值。 - **应用场景**:动态加载类、实现插件化...

    Android应用源码LumaQQ- qq 代码.zip

    《深入剖析Android应用源码LumaQQ:QQ代码解析》 在移动开发领域,Android以其开源性和灵活性成为了开发者们的首选平台。本篇文章将对“LumaQQ-qq代码.zip”这个压缩包中的Android应用源码进行深度分析,帮助读者...

    Android代码-Android 一些重要知识点解析整理

    Android AsyncTask 完全解析,带你从源码的角度彻底理解 Android 异步消息处理机制完全解析,带你从源码角度彻底理解 Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系 Android消息...

    Android源码设计模式解析与实战 pdf高清版

    《Android源码设计模式解析与实战》是一本深入探讨Android系统源码中设计模式应用的专业书籍,适合希望提升技术能力、研究源码或学习设计模式的开发者。这本书以清晰的结构和实例,揭示了Android系统背后的软件工程...

    进阶android源码demo

    3. **UI绘制与布局优化**:Android视图系统(View和ViewGroup)的源码解析能帮助我们理解UI渲染过程,从而进行性能优化。例如,如何自定义View,减少无效的测量和绘制,以及如何利用硬件加速来提升性能。 4. **线程...

    Handler Looper MessageQueue 源码解析

    本文将深入解析这三者的源码,帮助你理解它们的工作原理,并教你如何手写一套自己的Handler系统。 首先,我们来了解Handler。Handler是Android中的一个关键类,用于发送和处理消息。在主线程中,一个Handler对象...

    安卓Android源码——面试题-.zip

    在安卓开发领域,掌握Android源码对于提升技能和理解系统底层运作至关重要,特别是在面试环节,对源码的理解往往能体现一个开发者的深度。本资料"安卓Android源码——面试题-"将聚焦于Android源码相关的面试问题,...

    Android即时通讯--仿QQ即时聊天源码(含服务器).zip

    在本项目中,我们主要探讨的是如何在Android平台上...以上就是"Android即时通讯--仿QQ即时聊天源码(含服务器)"项目所涵盖的主要技术点,通过这个项目,开发者可以全面了解即时通讯应用的开发流程,并提升相关技能。

    AndroidMqtt源码

    **Android MQTT 源码解析** 在移动应用开发中,实时通信是不可或缺的一部分,而 MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅消息协议,广泛用于物联网(IoT)设备和应用程序之间的低带宽、...

    安卓Android源码——pushMessage.zip

    "安卓Android源码——pushMessage.zip" 提供的源码可能是一个简单的推送消息实现,或者是一个完整的推送服务框架。这里我们将围绕Android推送消息的实现、工作原理以及相关技术进行详细讲解。 1. **Android推送消息...

    Android ApiDemos示例解析(26):App->Notification->IncomingMessage

    本文将深入解析`ApiDemos`中的一个特定示例——`App-&gt;Notification-&gt;IncomingMessage`,帮助开发者更好地理解和应用Android的通知功能。 通知(Notification)是Android系统中一种关键的用户界面元素,它在状态栏中...

    Android_API-jieshao.zip_android

    本文将深入解析Android API的基础内容,帮助新手快速理解并掌握API的使用。 一、Android API概述 Android API是由Java语言编写的,基于Linux内核的开放源码平台。它包含了众多库、服务和工具,为开发者提供了全面...

    安卓Android源码——PushMessage百度的.zip

    这个压缩包“安卓Android源码——PushMessage百度的.zip”很可能是包含了实现百度推送服务(Baidu Push)的源代码。在这里,我们将深入探讨如何理解和使用这样的源代码,以及相关的Android推送技术。 首先,我们...

    Android源码设计模式

    在Android系统中,设计模式是开发者理解和驾驭代码的关键。这些模式源自《设计模式:可复用面向对象软件的基础》一书,由...阅读《Android源码设计模式解析与实战.pdf》这样的资料,将有助于你深入学习和实践这些知识。

    安卓Android源码——android访问网络返回json解析和Hanlder的使用.zip

    本资源"安卓Android源码——android访问网络返回json解析和Hanlder的使用.zip"聚焦于两个核心概念:网络请求与数据解析,以及Handler的使用。我们将深入探讨这两个方面。 首先,Android中的网络访问是应用程序与...

    Android高级应用源码-仿微信聊天软件,Socket实现.rar

    该压缩包文件“Android高级应用源码-仿微信聊天软件,Socket实现.rar”提供了一个学习Android高级应用开发的实例,具体是仿照微信聊天软件的实现。通过使用Socket编程,这个项目展示了如何在Android平台上构建一个...

    消息循环 Looper 及其源码解析

    本文将深入探讨“消息循环”Looper及其源码解析,帮助开发者更好地理解和应用这一机制。 首先,理解Looper的概念。Looper是Android中的一个类,它的主要职责是管理消息队列(MessageQueue),并不断从队列中取出...

    Android高级应用源码-NetPayClinet2.5 for java.zip

    此外,理解Android的Looper和MessageQueue机制也是很重要的。 4. **Android权限管理**:由于涉及到敏感的财务信息,该应用可能需要获取如INTERNET、ACCESS_NETWORK_STATE等权限。开发者需要了解如何在...

Global site tag (gtag.js) - Google Analytics