android 基础知识点

ContentProvider、ContentResolver、ContentObserver之间的关系

简单一句话来描述就是:使用ContentResolver来获取ContentProvider提供的数据,同时注册ContentObserver监听Uri数据的变化

描述一次网络请求过程(三次握手,四次挥手)

bitmap相关(Bitmap内存计算等)

Looper的架构

Handler里面有一个重要的成员变量Looper,Looper里面维护了一个MessageQueue(消息队列),当我们使用handler.post或者sendMessage相关的方法都是将消息Message放入到消息队列中。每一个线程都将拥有一个自己的Looper,顾名思义ThreadLocal是和线程绑定的。当我们有一个线程A使用sThreadLocal.set(Looper a),线程B使用sThreadLocal.set(Looper b)的方式存储,如果我们在线程B中使用sThreadLocal.get()将会得到Looper b的实例。所以我们每个线程可以拥有独立的Looper,Looper里面维护了一个消息队列,也就是每一个线程维护自己的消息队列。

当在主线程中时,在你的应用启动时系统便给我们创建了一个MainLooper存入了sThreadLocal中,所以平时我们使用Handler时,如果是在主线程中创建的,我们是不需再去创建一个Looper给Handler的,因为系统已经做了,所以当我们new Handler时,系统便将之前存入的Looper通过sThreadLoca中get出来,然后再去从对应的消息队列中读取执行。

而当我们在子线程中创建Handler时,如果直接new Handler运行时肯定会报错的,提示我们必须先调用Looper.prepare()方法,为什么呢?因为我们没有创建子线程对应的Looper放入sThreadLocal当中,而prepare方法就是new了一个Looper的实例通过
通过Handler有很多种发送消息的方式:

post(Runable run)
postDelayed
sendEmptyMessage()
…等等
其实无论是通过post的方式或者send的方式,最后都是通过

public final boolean sendMessageDelayed(Message msg, long delayMillis)

我们使用post传入的Runnable实例,也是通过:
private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
       m.callback = r;
       return m; 
 }
         
通过上面的方法,将Runnable的实例转换为Message的实例,然后调用通用的方法发送到消息队列中,最终会通过下面的方式放入队列:

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
       msg.target = this;
       if (mAsynchronous) {
           msg.setAsynchronous(true);
       }
    return queue.enqueueMessage(msg, uptimeMillis);
  }

在子线程中使用handler就意味着handler的实例是在子线程中去创建的。

Looper.prepare();
mHandler = new Handler(){
    @Override
  public void handleMessage(Message msg) {
            Log.d(TAG," mHandler is coming");
  handler_main.sendEmptyMessage(1);
  }
};
mHandler.sendEmptyMessage(1);
Looper.loop();

如果在调用之前必须调用Looper.prepare()方法,这个是在当前线程中创建一个looper出来,如果是普通的应用场景可以直接使用HandlerThread,其中是带有Looper的。
第二点值得注意的就是,Looper.loop()这个方法是无限循环的,所以在Looper.loop()后边的程序代码块是无法执行到的。loop()方法的主要作用是一直不断的通过queue.next()方法来读取来自messagequeue中的msg,这个方法是block的状态,如果queue中没有消息的话会一直阻塞在这里。
关于Looper还有一个方法,当我们需要获取Looper实例时,可以直接在对应线程调用Looper looper = Looper.myLooper();来获取,默认情况下,系统只会给MainT
hread分配一个looper。

Callable、Future和FutureTask

Android系统服务 —— WMS与AMS

Popupwindow与Dialog的区别

(1)PopupWindow在显示之前必须设置宽高,Dialog无此限制

(2)PopupWindow默认不会响应物理键盘的back,除非显示设置了popup.setFocusable(true);而在点击back的时候,Dialog会消失

(3)PopupWindow不会给页面其他部分添加蒙层,而Dialog会

(4)PopupWindow没有标题,Dialog默认有标题,可以通过dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);取消标题

(5)二者显示的时候都要设置Gravity。如果不设置,Dialog默认是Gravity.CENTER

(6)二者都有默认的背景,都可以通过setBackGroundDrawable(new ColorDrawable(android.R.color.transparent));去掉

本质差别:
AlterDialog是非阻塞式对话框:AlterDialog弹出时,后台还可以做事情
PopupWindow是阻塞式对话框:PopupWindow弹出时,程序会等待,在PopupWindow退出前,程序一直等待,只有在调用dismiss方法后,PopupWindow退出,程序才会向下执行。
差别表现:
AlterDialog弹出时,背景是黑色的,但是当我们点击背景,AlterDialog会消失,证明程序不仅响应AlterDialog的操作,还响应其他操作,其他程序没有被阻塞,说明AlterDialog是非阻塞式对话框,PopupWindow弹出时,背景没有变化,但是当我们点击背景的时候,程序没有响应,只允许我们操作PopupWindow,其他操作被阻塞。

java对象生命周期

  1.  创建阶段(Created)
    
  2.  应用阶段(In Use)
    
  3.  不可见阶段(Invisible)
    
  4.  不可达阶段(Unreachable)
    
  5.  收集阶段(Collected)
    
  6.  终结阶段(Finalized)
    
  7.  对象空间重分配阶段(De-allocated)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值