美文网首页
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