美文网首页
源码面试题

源码面试题

作者: taijielan | 来源:发表于2019-02-22 14:22 被阅读0次
1. activity的启动流程?

lanuch ->actvitymange->activitymagerservice(ActivityManagerService(AMS)负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作) binder->
Lanuch:也是应用,也是一个acitivity
instrumentation:execStartActivity()
activitymanager:产生与IActivityManger, 这个是写在aidl文件中的类,
activitymangerservice(ams):ActivityManagerService(AMS)负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作,是服务端进程:中间通过binder机制,Aidl文件。进行显示还是隐式跳转的判断
ActivityStackSupervisor:中进行一列的处理,获取当前activity的启动模式,当前intent是隐式还是显示,暂停正在启动的页面,以及启动activity的进程,启动前判断当前应用的进程是否启动,如果没有启动通知ActivityMangerService
Process:打开用来与Zygote进程通信的Socket,
ActivityThread:穿件新进程的时候,执行activityThread的main方法,然后attach到AMS,并将新进程的ApplicationThread对象传给AMS.
ActivityManagerService:调用ActivityStackSuperVisor来在新的进程中启动Activity
ActivityStackSuperVisor:通过applicationThread 启动acitivity
ApplicationThread:发送message到ActivityThread中
ActivityThread:处理message,通过反射获取到需要启动的acivity和application


为什么Handler能够跨线程通信?

Handler的创建与Looper有关,我们可以在主线程中创建,也可以在子线程中创建,由于主线程中已经创建好了Looper,
首先主线程中会自动创建主线程的loopre对象在ActivityThread中

    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
        // It will be in the format "seq=114"
        long startSeq = 0;
        if (args != null) {
            for (int i = args.length - 1; i >= 0; --i) {
                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
                }
            }
        }
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

在子线程中创建首先调用 Looper.prepare(),再然后 Looper.loop();具体的

  new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
              Handler handler = new Handler(){
                  @Override
                  public void handleMessage(Message msg) {
                      super.handleMessage(msg);
                      Log.e("info","--->");
                      Toast.makeText(MainActivity.this,"da",Toast.LENGTH_LONG).show();
                  }
              };

                handler.sendEmptyMessage(1);
                Looper.loop();

            }
        }).start();

现在分析为什么主线程创建的Handler,而子线程利用Handler能够发送消息到主线程?
前面已经说过,主线程会默认创建一个主线程的Looper,当我们从子线程handler.sendEmptyMessage(1)消息的时候,知道这个过程是将msg压入到消息队列的过程。当msg进入到messagequeue中,压入到messagequeue中之前有个msg与handler的绑定关系“ msg.target = this”,其中这是就是发送当前msg的Handler,主线程中默认调用了由于调用了Looper.looper()方法。将不断轮询其中的msg,最终调用的处理的地点是msg.target.dispatchMessage(msg);
主要看msg.target这个对象,从上面可知这是发送当前msg的Handler对象。在源码中msg和Handler有个绑定的关系。谁发送的msg,该msg保存发送Handler的引用,最后交由这个Handler来处理msg。


Looper中有个无限轮询消息队列的操作,为什么没有导致App没有报ANR?

产生ANR的原因有2种:

  • 在指定时间内没有响应输入的事件.
  • 处理响应的事件超时。
    Android程序的入口就是ActivityThread 的main方法,如果main方法执行完了,那么应用也就执行完了,所以looper是无限循环是有必要的,不然程序会自动退出。所以在Android中其他的所有操作都是在这个无限循之内。looper.loop()理论上可能会造成堵塞,所说的堵塞是指处理事件不够快,就不会造成ANR,Looper.loop()本身是不会堵塞的。

相关文章

网友评论

      本文标题:源码面试题

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