美文网首页
Android知识点汇记录(精简版)

Android知识点汇记录(精简版)

作者: 浪里_个郎 | 来源:发表于2020-04-02 21:16 被阅读0次

    ANR

    根本原理,是系统把各种消息事件丢给应用的时候,会带一个延时消息,如果事件及时处理,则取消延时消息,否则在延时消息执行时,系统报应用ANR。

    Looper

    消息通知流程和原理

    根据消息处理时间(Message.when),将消息按照执行时间从先到后放到MessageQueue合适的位置(队列头是最早能被执行的消息)。
    先调nativePollOnce休眠,不过一开始传给epoll_wait的休眠时间是0,所以会立刻唤醒返回。然后取出查看Message.when,如果小于等于当前时间,直接返回。如果大于当前时间,则计算需等待时间,通过nativePollOnce传给epoll_wait休眠。到了时间epoll_wait就会被唤醒,从而返回该message。
    消息队列为空时,给nativePollOnce传入-1,epoll_wait无限期休眠(因为没有系统的延时消息,所以不会ANR)。有消息进来时,往epoll监听的fd写消息,从而唤醒epoll,java层解除阻塞从消息队列取消息。

    Looper中的fd

    Looper不仅可以监听用于系统消息通知的mWakeEventFd,还支持通过addFd函数增加监听的fd,epoll_wait监听到事件后,根据事件对应的fd,做不同的处理。每个添加的fd,都有自己对应的response回调处理。

        for (int i = 0; i < eventCount; i++) {
            //获取事件对应的fd
            int fd = eventItems[i].data.fd;
            uint32_t epollEvents = eventItems[i].events;
            //这是消息队列的fd
            if (fd == mWakeEventFd) {
                if (epollEvents & EPOLLIN) {
                    awoken();
                } else {
                    ALOGW("Ignoring unexpected epoll events 0x%x on wake event fd.", epollEvents);
                }
            } else {
                //这里是自定义的fd
                ssize_t requestIndex = mRequests.indexOfKey(fd);
                if (requestIndex >= 0) {
                    int events = 0;
                    if (epollEvents & EPOLLIN) events |= EVENT_INPUT;
                    if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT;
                    if (epollEvents & EPOLLERR) events |= EVENT_ERROR;
                    if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP;
                    pushResponse(events, mRequests.valueAt(requestIndex));
                } else {
                    ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
                            "no longer registered.", epollEvents, fd);
                }
            }
        }
    

    将代码放入UI线程执行

    非UI线程,我们可以通过Activity.runOnUiThread(Runnable runable)方法,把自定义Runnable放到UI主线程中执行。其原理就是通过UI线程中绑定了UI线程Looper的Handler,把Runnable封装成Message给post到UI线程消息队列:

        public final boolean post(Runnable r)
        {
           return  sendMessageDelayed(getPostMessage(r), 0);
        }
    

    Runnable被放进Message的callback中

        private static Message getPostMessage(Runnable r) {
            Message m = Message.obtain();
            m.callback = r;
            return m;
        }
    

    当Message被Looper从消息队列中取出并交给Handler处理,Handler会判断Message是否具有callback,如有,则处理:

        public void dispatchMessage(Message msg) {
            if (msg.callback != null) {
                handleCallback(msg);
            } else {
                if (mCallback != null) {
                    if (mCallback.handleMessage(msg)) {
                        return;
                    }
                }
                handleMessage(msg);
            }
        }
    
    线程间专递

    A activity -> B activity -> fragment再一路back键

    A: OnCreate -> onStart -> onResume -> onPause
    B:onCreate onStart onResume
    A:onStop
    B:onPause
    F:onAttach onCreate onCreateView onActivityCreated onStart onResume onPause onStop onDestroyView onDestroy onDetach
    B:onRestart onStart onResume onPause
    A:onRestart onStart onResume
    B:onStop onDestroy
    A:onStop onDestroy

    Activity常见标签

    theme / exported / launchMode / intent-fliter / process / noHistory

    launchMode四种模式使用场景

    standard:默认模式
    singleTop:例如通知栏多条消息都会跳转到同一个页面时
    singleTask:app主页,需要长时间存在且用户很有可能多次跳转过去的页面
    singleInstance:电话拨号盘页面,通过自己的应用或者其他应用打开拨打电话页面 ,只要系统的栈中存在该实例,那么就会直接调用。

    intent-fliter

    Action:代表一个Intent的标识
    Data:可以在Activity中通过getData获取
    category:标识这个activity能够handle的intent
    Extras: putExtra后Activity可以通过getExtra获取

    IntentService

    IntentService是后台服务类,我们在外部组件中通过Intent向IntentService发送请求命令,之后IntentService逐个执行命令队列里的命令,队列里的命令将会被顺序执行,最后执行完队列的所有命令后,服务也随即停止并被销毁。

    ContentProvider

    ContentProvider为其他应用程序提供了访问本应用程序的接口,其他应用程序可以通过ContentResolver来操作ContentProvider提供的数据,保证了被访数据的安全性。
    sql也有增删改查的方法,单sql只能操作本应用下的数据库。

    Service的两种启动方式区别

    startService:如果没有stopService,Service会一直在后台运行
    bindService:如果所有bind的进程都销毁了,就会自动调用onUnbind -> onDestroy。
    如果先bindService再调startService: onCreate -> onBind -> onStartCommand 这时stopService无效,必须先unBindService

    相关文章

      网友评论

          本文标题:Android知识点汇记录(精简版)

          本文链接:https://www.haomeiwen.com/subject/aopfphtx.html