00-面试查漏补缺

2024.3.13

Handler

  • sendMessage
  • post
    • 有callback的message
    • looper循环执行
  • sendMessage
    • 发送自定义的message
    • 可以没有callback
    • 可以有what、obj去和接收者传递消息

Message源码(仅public)

  • Message的获取
    • Handler包装的runnable
    • new Message()
    • obtain() 推荐,Message中的recycle方法会回收不用的Message,obtain的时候如果消息池不空,可以服用消息池
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      160
      161
      162
      163
      164
      165
      166
      167
      168
      169
      170
      171
      172
      173
      174
      175
      176
      177
      178
      179
      180
      181
      182
      183
      184
      185
      186
      187
      188
      189
      190
      191
      192
      193
      194
      195
      196
      197
      198
      199
      200
      201
      202
      203
      204
      205
      206
      207
      208
      209
      210
      211
      212
      213
      214
      215
      216
      217
      218
      219
      220
      221
      222
      223
      224
      225
      226
      227
      228
      229
      230
      231
      232
      233
      234
      235
      236
      237
      238
      239
      240
      241
      242
      243
      244
      245
      246
      247
      248
      249
      250
      251
      252
      253
      254
      255
      256
      257
      258
      259
      260
      261
      262
      263
      264
      265
      266
      267
      268
      269
      270
      271
      272
      273
      274
      275
      276
      277
      278
      279
      280
      281
      282
      283
      284
      285
      286
      287
      288
      289
      290
      291
      292
      293
      294
      295
      296
      297
      298
      299
      300
      301
      302
      303
      304
      305
      306
      307
      308
      309
      310
      311
      312
      313
      314
      315
      316
      317
      318
      319
      320
      321
      322
      323
      324
      325
      326
      327
      328
      329
      330
      331
      332
      333
      334
      335
      336
      337
      338
      339
      340
      341
      342
      343
      344
      345
      346
      347
      348
      349
      350
      351
      352
      353
      354
      355
      356
      357
      358
      359
      360
      361
      362
      363
      364
      365
      366
      367
      368
      369
      370
      public final class Message implements Parcelable {
      /**
      * User-defined message code so that the recipient can identify
      * what this message is about. Each {@link Handler} has its own name-space
      * for message codes, so you do not need to worry about yours conflicting
      * with other handlers.
      */
      public int what;

      /**
      * arg1 and arg2 are lower-cost alternatives to using
      * {@link #setData(Bundle) setData()} if you only need to store a
      * few integer values.
      */
      public int arg1;

      /**
      * arg1 and arg2 are lower-cost alternatives to using
      * {@link #setData(Bundle) setData()} if you only need to store a
      * few integer values.
      */
      public int arg2;

      /**
      * An arbitrary object to send to the recipient. When using
      * {@link Messenger} to send the message across processes this can only
      * be non-null if it contains a Parcelable of a framework class (not one
      * implemented by the application). For other data transfer use
      * {@link #setData}.
      *
      * <p>Note that Parcelable objects here are not supported prior to
      * the {@link android.os.Build.VERSION_CODES#FROYO} release.
      */
      public Object obj;
      @UnsupportedAppUsage
      /*package*/ int flags;

      /**
      * The targeted delivery time of this message. The time-base is
      * {@link SystemClock#uptimeMillis}.
      * @hide Only for use within the tests.
      */
      @UnsupportedAppUsage
      @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
      public long when;


      /** @hide */
      public static final Object sPoolSync = new Object();

      /**
      * Return a new Message instance from the global pool. Allows us to
      * avoid allocating new objects in many cases.
      */
      public static Message obtain() {
      synchronized (sPoolSync) {
      if (sPool != null) {
      Message m = sPool;
      sPool = m.next;
      m.next = null;
      m.flags = 0; // clear in-use flag
      sPoolSize--;
      return m;
      }
      }
      return new Message();
      }

      /**
      * Same as {@link #obtain()}, but copies the values of an existing
      * message (including its target) into the new one.
      * @param orig Original message to copy.
      * @return A Message object from the global pool.
      */
      public static Message obtain(Message orig) {
      Message m = obtain();
      m.what = orig.what;
      m.arg1 = orig.arg1;
      m.arg2 = orig.arg2;
      m.obj = orig.obj;
      m.replyTo = orig.replyTo;
      m.sendingUid = orig.sendingUid;
      m.workSourceUid = orig.workSourceUid;
      if (orig.data != null) {
      m.data = new Bundle(orig.data);
      }
      m.target = orig.target;
      m.callback = orig.callback;

      return m;
      }

      /**
      * Same as {@link #obtain()}, but sets the value for the <em>target</em> member on the Message returned.
      * @param h Handler to assign to the returned Message object's <em>target</em> member.
      * @return A Message object from the global pool.
      */
      public static Message obtain(Handler h) {
      Message m = obtain();
      m.target = h;

      return m;
      }

      /**
      * Same as {@link #obtain(Handler)}, but assigns a callback Runnable on
      * the Message that is returned.
      * @param h Handler to assign to the returned Message object's <em>target</em> member.
      * @param callback Runnable that will execute when the message is handled.
      * @return A Message object from the global pool.
      */
      public static Message obtain(Handler h, Runnable callback) {
      Message m = obtain();
      m.target = h;
      m.callback = callback;

      return m;
      }

      /**
      * Same as {@link #obtain()}, but sets the values for both <em>target</em> and
      * <em>what</em> members on the Message.
      * @param h Value to assign to the <em>target</em> member.
      * @param what Value to assign to the <em>what</em> member.
      * @return A Message object from the global pool.
      */
      public static Message obtain(Handler h, int what) {
      Message m = obtain();
      m.target = h;
      m.what = what;

      return m;
      }

      /**
      * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, and <em>obj</em>
      * members.
      * @param h The <em>target</em> value to set.
      * @param what The <em>what</em> value to set.
      * @param obj The <em>object</em> method to set.
      * @return A Message object from the global pool.
      */
      public static Message obtain(Handler h, int what, Object obj) {
      Message m = obtain();
      m.target = h;
      m.what = what;
      m.obj = obj;

      return m;
      }

      /**
      * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,
      * <em>arg1</em>, and <em>arg2</em> members.
      *
      * @param h The <em>target</em> value to set.
      * @param what The <em>what</em> value to set.
      * @param arg1 The <em>arg1</em> value to set.
      * @param arg2 The <em>arg2</em> value to set.
      * @return A Message object from the global pool.
      */
      public static Message obtain(Handler h, int what, int arg1, int arg2) {
      Message m = obtain();
      m.target = h;
      m.what = what;
      m.arg1 = arg1;
      m.arg2 = arg2;

      return m;
      }

      /**
      * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,
      * <em>arg1</em>, <em>arg2</em>, and <em>obj</em> members.
      *
      * @param h The <em>target</em> value to set.
      * @param what The <em>what</em> value to set.
      * @param arg1 The <em>arg1</em> value to set.
      * @param arg2 The <em>arg2</em> value to set.
      * @param obj The <em>obj</em> value to set.
      * @return A Message object from the global pool.
      */
      public static Message obtain(Handler h, int what,
      int arg1, int arg2, Object obj) {
      Message m = obtain();
      m.target = h;
      m.what = what;
      m.arg1 = arg1;
      m.arg2 = arg2;
      m.obj = obj;

      return m;
      }

      /** @hide */
      public static void updateCheckRecycle(int targetSdkVersion) {
      if (targetSdkVersion < Build.VERSION_CODES.LOLLIPOP) {
      gCheckRecycle = false;
      }
      }

      /**
      * Return a Message instance to the global pool.
      * <p>
      * You MUST NOT touch the Message after calling this function because it has
      * effectively been freed. It is an error to recycle a message that is currently
      * enqueued or that is in the process of being delivered to a Handler.
      * </p>
      */
      public void recycle() {
      if (isInUse()) {
      if (gCheckRecycle) {
      throw new IllegalStateException("This message cannot be recycled because it "
      + "is still in use.");
      }
      return;
      }
      recycleUnchecked();
      }
      /**
      * Return the targeted delivery time of this message, in milliseconds.
      */
      public long getWhen() {
      return when;
      }

      public void setTarget(Handler target) {
      this.target = target;
      }

      /**
      * Retrieve the {@link android.os.Handler Handler} implementation that
      * will receive this message. The object must implement
      * {@link android.os.Handler#handleMessage(android.os.Message)
      * Handler.handleMessage()}. Each Handler has its own name-space for
      * message codes, so you do not need to
      * worry about yours conflicting with other handlers.
      */
      public Handler getTarget() {
      return target;
      }

      /**
      * Retrieve callback object that will execute when this message is handled.
      * This object must implement Runnable. This is called by
      * the <em>target</em> {@link Handler} that is receiving this Message to
      * dispatch it. If
      * not set, the message will be dispatched to the receiving Handler's
      * {@link Handler#handleMessage(Message)}.
      */
      public Runnable getCallback() {
      return callback;
      }

      /** @hide */
      @UnsupportedAppUsage
      public Message setCallback(Runnable r) {
      callback = r;
      return this;
      }

      /**
      * Obtains a Bundle of arbitrary data associated with this
      * event, lazily creating it if necessary. Set this value by calling
      * {@link #setData(Bundle)}. Note that when transferring data across
      * processes via {@link Messenger}, you will need to set your ClassLoader
      * on the Bundle via {@link Bundle#setClassLoader(ClassLoader)
      * Bundle.setClassLoader()} so that it can instantiate your objects when
      * you retrieve them.
      * @see #peekData()
      * @see #setData(Bundle)
      */
      public Bundle getData() {
      if (data == null) {
      data = new Bundle();
      }

      return data;
      }

      /**
      * Like getData(), but does not lazily create the Bundle. A null
      * is returned if the Bundle does not already exist. See
      * {@link #getData} for further information on this.
      * @see #getData()
      * @see #setData(Bundle)
      */
      public Bundle peekData() {
      return data;
      }

      /**
      * Sets a Bundle of arbitrary data values. Use arg1 and arg2 members
      * as a lower cost way to send a few simple integer values, if you can.
      * @see #getData()
      * @see #peekData()
      */
      public void setData(Bundle data) {
      this.data = data;
      }

      /**
      * Chainable setter for {@link #what}
      *
      * @hide
      */
      public Message setWhat(int what) {
      this.what = what;
      return this;
      }

      /**
      * Sends this Message to the Handler specified by {@link #getTarget}.
      * Throws a null pointer exception if this field has not been set.
      */
      public void sendToTarget() {
      target.sendMessage(this);
      }

      /**
      * Returns true if the message is asynchronous, meaning that it is not
      * subject to {@link Looper} synchronization barriers.
      *
      * @return True if the message is asynchronous.
      *
      * @see #setAsynchronous(boolean)
      */
      public boolean isAsynchronous() {
      return (flags & FLAG_ASYNCHRONOUS) != 0;
      }

      /**
      * Sets whether the message is asynchronous, meaning that it is not
      * subject to {@link Looper} synchronization barriers.
      * <p>
      * Certain operations, such as view invalidation, may introduce synchronization
      * barriers into the {@link Looper}'s message queue to prevent subsequent messages
      * from being delivered until some condition is met. In the case of view invalidation,
      * messages which are posted after a call to {@link android.view.View#invalidate}
      * are suspended by means of a synchronization barrier until the next frame is
      * ready to be drawn. The synchronization barrier ensures that the invalidation
      * request is completely handled before resuming.
      * </p><p>
      * Asynchronous messages are exempt from synchronization barriers. They typically
      * represent interrupts, input events, and other signals that must be handled independently
      * even while other work has been suspended.
      * </p><p>
      * Note that asynchronous messages may be delivered out of order with respect to
      * synchronous messages although they are always delivered in order among themselves.
      * If the relative order of these messages matters then they probably should not be
      * asynchronous in the first place. Use with caution.
      * </p>
      *
      * @param async True if the message is asynchronous.
      *
      * @see #isAsynchronous()
      */
      public void setAsynchronous(boolean async) {
      if (async) {
      flags |= FLAG_ASYNCHRONOUS;
      } else {
      flags &= ~FLAG_ASYNCHRONOUS;
      }
      }

      /** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}).
      */
      public Message() {
      }
      }

Looper每次循环在做什么

阅读更多

00-面试查漏补缺

View绘制流程图

起点:ViewRootImpl

ViewRootImpl中有一个巨长的方法performTraversals,其中会依次调用三个函数

  • performMeasure
  • performLayout
  • performDraw

通过ViewRootImplsetView方法,ViewRootImpl对象会拥有一个mView对象

阅读更多

19-RecyclerView

RecyclerView

  • flexible:
  • limited: 有限屏幕中显示
  • large: 大量内容

RecyclerView的优势

  • Linear, Grid, Staggered Grid三种布局
  • itemAnimator接口
  • 强制实现ViewHolder
  • 解耦设计
  • 性能更好

listView的局限

  • 只能纵向列表

  • 没有动画api

  • api设计太个性了,和其他view设计的重复

  • 性能不好

  • 三个帮手

    • LayoutManager: 负责布局Views
    • ItemAnimator: 负责给View加动画
    • Adaptor: 提供views
阅读更多

20-Android多线程

Thread.yield()

  • 暂时把时间片让出去,变成可运行状态(ready)

handler

Looper

  • ThreadLocal的
  • 相当于一个线程里的大循环
  • 在大循环里循环从messageQueue中拿消息
  • 拿到消息后执行消息

Handler

阅读更多

18-Java多线程

Thread, Runnable, callable

  • 基础

ThreadFactory

1
2
3
public interface ThreadFactory {
Thread newThread(Runnable r);
}
  • 实现一个工厂,生成thread,方便对同类thread进行统一的初始化操作

Executor

阅读更多

21-RxJava

Single

static <T> Single.just(T t)

  • 生成一个Singled对象
    • return onAssembly(new SingleJust(t))
    • onAssembly是一个钩子函数,一般情况下不做任何操作,就是调用一个Function<T, R>.apply()

Observer

  • 有后续的onNext
  • 有周期的Observer.interval()每隔一段时间onNext一次

Disposable

阅读更多

06-OKHTTP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
final Dispatcher dispatcher; // 线程控制
final @Nullable Proxy proxy; // 代理服务器,java.net
final List<Protocol> protocols;
final List<ConnectionSpec> connectionSpecs;
final List<Interceptor> interceptors;
final List<Interceptor> networkInterceptors;
final EventListener.Factory eventListenerFactory;
final ProxySelector proxySelector;
final CookieJar cookieJar;
final @Nullable Cache cache;
final @Nullable InternalCache internalCache;
final SocketFactory socketFactory;
final SSLSocketFactory sslSocketFactory;
final CertificateChainCleaner certificateChainCleaner;
final HostnameVerifier hostnameVerifier;
final CertificatePinner certificatePinner;
final Authenticator proxyAuthenticator;
final Authenticator authenticator;
final ConnectionPool connectionPool;
final Dns dns;
final boolean followSslRedirects;
final boolean followRedirects;
final boolean retryOnConnectionFailure;
final int callTimeout;
final int connectTimeout;
final int readTimeout;
final int writeTimeout;
final int pingInterval;

websocket

wikipedia:

  • 利用tcp提供全双工通信 WebSocket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection.
  • 运行在80/443端口上 WebSocket is designed to work over HTTP ports 443 and 80 as well as to support HTTP proxies and intermediaries

Dispatcher - 线程控制

使用Deque控制任务

阅读更多

05-Retrofit

HOST验证

在上节https的ca证书验证时,如果某个恶意网站直接获取整个ca证书,发给其他用户骗取信任怎么办。这个时候就需要host验证,即证书的host主机与发送证书的主机host是否是同一个域名。

fiddler如何抓包

fiddler是一个中间人,通过系统代理,浏览器/应用将请求发送至fiddler,fiddler自签一个证书与浏览器/应用使用,且需要用户向操作系统安装根证书。fiddler拿到数据包后再与服务器交互。

retrofit源码阅读

retrofit的使用

阅读更多

04-登录授权 Https TCP/IP

登录授权

Basic

在header中
Authorization: Basic username:password(Base64ed, encrypted)

Bearer

在header中
Authorization: Bearer bearer_token

这里的bearer_token就类似于github的Personal access tokens,在请求中持有token的请求,可以根据token的权限对第三方账号中的数据进行获取、修改

阅读更多