美文网首页android
Android Application的杂事

Android Application的杂事

作者: 黄海佳 | 来源:发表于2017-03-16 17:57 被阅读82次
    一、Application简单介绍

    每个Android App都在一个独立空间里, 意味着其运行在一个单独的进程中, 拥有自己的VM, 被系统分配一个唯一的user ID。Android App由很多不同组件组成,这些组件还可以启动其他App的组件。 因此, Android App并没有一个类似程序入口的main()方法。

    Android Application组件包括:
    • Activities: 前台界面, 直接面向User, 提供UI和操作。
    • Services: 后台任务。
    • Broadcast Receivers: 广播接收者。
    • Contexnt Providers: 数据提供者。
    一个进程里面只有一个线程---主线程。 这个主线程中有一个Looper实例,通过调用Looper.loop()从Message队列里面取出Message来做相应的处理。

    如果你的apk没有运行, 系统会为其创建一个新的进程并启动 。通常, 这个进程会持续运行直到被系统杀死. 关键是: 进程是在被需要的时候才创建的。

    二、Application启动流程

    用户点击app的时候发生了什么事情呢?

    1 会调用startActivity(Intent), 会通过Binder IPC机制, 最终调用到ActivityManagerService。 该Service会执行如下操作:
    • 第一步通过PackageManager的resolveIntent()收集这个intent对象的指向信息.
      指向信息被存储在一个intent对象中。
    • 接着通过grantUriPermissionLocked()方法来验证用户是否有足够的权限去调用该intent对象指向的Activity。
    • 如果有权限, ActivityManagerService会检查并在新的task中启动目标activity.
      现在, 是时候检查这个进程的ProcessRecord是否存在了。
    • 如果ProcessRecord是null, ActivityManagerService会创建新的进程来实例化目标activity。
    2 创建进程

    ActivityManagerService调用startProcessLocked()方法来创建新的进程, 该方法会通过前面讲到的socket通道传递参数给Zygote进程. Zygote孵化自身, 并调用ZygoteInit.main()方法来实例化ActivityThread对象并最终返回新进程的pid。

    ActivityThread随后依次调用Looper.prepareLoop()和Looper.loop()来开启消息循环。

    3 绑定Application

    接下来要做的就是将进程和指定的Application绑定起来. 这个是通过上节的ActivityThread对象中调用bindApplication()方法完成的. 该方法发送一个BIND_APPLICATION的消息到消息队列中, 最终通过handleBindApplication()方法处理该消息. 然后调用makeApplication()方法来加载App的classes到内存中。

    Paste_Image.png
    4 启动Activity

    经过前两个步骤之后, 系统已经拥有了该application的进程. 后面的调用顺序就是普通的从一个已经存在的进程中启动一个新进程的activity了.

    实际调用方法是realStartActivity(), 它会调用application线程对象中的sheduleLaunchActivity()发送一个LAUNCH_ACTIVITY消息到消息队列中, 通过 handleLaunchActivity()来处理该消息

    四、通过Application来监听App处于前台和后台?
    /**
     * @创建 HaiJia
     * @时间 2017/3/16 15:26
     * @描述 利用Application监听App处于前台和后台
     * @需求 App从前台切换到后台,不需要做什么操作;从后台切换到前台,需要先验证屏锁密码
     */
    
    public class ForegroundCallBacks implements Application.ActivityLifecycleCallbacks{
    
        public static final long CHECK_DELAY = 500;//Handler延迟执行时间
        public static final String TAG = ForegroundCallBacks.class.getName();
    
        public interface Listener {
            public void onBecameForeground();
            public void onBecameBackground();
        }
    
    
        private static ForegroundCallBacks instance;
        private boolean foreground = false, paused = true;
        private Handler handler = new Handler();
        private List<Listener> listeners = new CopyOnWriteArrayList<>();
        private Runnable check;
    
    
        /**
         *
         * @描述 初始化
         */
        public static ForegroundCallBacks init(Application application){
            if (instance == null) {
                instance = new ForegroundCallBacks();
                application.registerActivityLifecycleCallbacks(instance);
            }
            return instance;
        }
    
        /**
         *
         * @描述 get ForegroundCallBacks实例
         * @param Application
         */
        public static ForegroundCallBacks get(Application application){
            if (instance == null) {
                init(application);
            }
            return instance;
        }
    
        /**
         *
         * @描述 get ForegroundCallBacks实例
         * @param Context
         */
        public static ForegroundCallBacks get(Context ctx){
            if (instance == null) {
                Context appCtx = ctx.getApplicationContext();
                if (appCtx instanceof Application) {
                    init((Application)appCtx);
                }else {
                    throw new IllegalStateException(
                            "Foreground is not initialised and " +
                                    "cannot obtain the Application object");
                }
            }
            return instance;
        }
    
        /**
         * @描述 get ForegroundCallBacks实例
         */
        public static ForegroundCallBacks get(){
            if (instance == null) {
                throw new IllegalStateException(
                        "Foreground is not initialised - invoke " +
                                "at least once with parameterised init/get");
            }
            return instance;
        }
    
        /**
         *
         * @描述 App处于是否在前台
         */
        public boolean isForeground(){
            return foreground;
        }
    
        /**
         *
         * @描述 App处于是否在后台
         */
        public boolean isBackground(){
            return !foreground;
        }
    
        /**
         *
         * @描述 添加监听
         */
        public void addListener(Listener listener){
            listeners.add(listener);
        }
    
        /**
         *
         * @描述 移除监听
         */
        public void removeListener(Listener listener){
            listeners.remove(listener);
        }
    
    
    
        /**
         * @描述 onActivityResumed
         */
        @Override
        public void onActivityResumed(Activity activity) {
            paused = false;
            boolean wasBackground = !foreground;
            foreground = true;
            if (check != null)
                handler.removeCallbacks(check);
            if (wasBackground){
                LogUtils.log("went foreground");
                for (Listener l : listeners) {
                    try {
                        l.onBecameForeground();
                    } catch (Exception exc) {
                        LogUtils.log("Listener threw exception!", exc);
                    }
                }
            } else {
                LogUtils.log("still foreground");
            }
        }
    
        @Override
        public void onActivityPaused(Activity activity) {
            paused = true;
            if (check != null)
                handler.removeCallbacks(check);
            handler.postDelayed(check = new Runnable(){
                @Override
                public void run() {
                    if (foreground && paused) {
                        foreground = false;
                        LogUtils.log("went background");
                        for (Listener l : listeners) {
                            try {
                                l.onBecameBackground();
                            } catch (Exception exc) {
                                LogUtils.log("Listener threw exception!", exc);
                            }
                        }
                    } else {
                        LogUtils.log("still foreground");
                    }
                }
            }, CHECK_DELAY);
        }
    
        @Override
        public void onActivityCreated(Activity activity, Bundle bundle) {
    
        }
    
        @Override
        public void onActivityStarted(Activity activity) {
    
        }
    
        @Override
        public void onActivityStopped(Activity activity) {
    
        }
    
        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
    
        }
    
        @Override
        public void onActivityDestroyed(Activity activity) {
    
        }
    }
    

    相关文章

      网友评论

        本文标题:Android Application的杂事

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