精华内容
下载资源
问答
  • Android多module初始化application

    千次阅读 2019-09-11 08:49:32
    下面开始说明Android中,多个module是怎么初始化application,让module的application拥有实例的。 方法说起来很简单,就是使用反射。 因为软件打开的时候,只会初始化主工程的application(打开主工...

    开始之前,顺带提一下一个小知识,那就是:

    在Application里,attachBaseContext()方法的执行顺序是在onCreate()之前的

    下面开始说明Android中,多个module是怎么初始化application,让module的application拥有实例的。

    方法说起来很简单,就是使用反射。

    因为软件打开的时候,只会初始化主工程的application(打开主工程AndroidManifest,点击Merged Manifest,就可以看到,其他的application都被覆盖了,只剩下主工程application),所以在这里,我就想到在初始化主工程application的时候,对其他module的application进行初始化。

    最开始我是这样做的
    在主工程的application里的onCreate方法里
     

    //主工程Application
    public class MainApplication extends Application{
        public void onCreate(){
            super.onCreate();
    
            //.....中间执行主工程的一些初始化操作
            
            //初始化module的application
            try{
                Class<?> clazz = Class.forName(ModuleApplication.class.getName());
                ModuleApplication moduleApplication = (ModuleApplication)clazz.newInstance();
                moduleApplication.onCreate();
            }catch(Exception e){
                Log.e("ALeeObj", e.getMessage);
            }
        }
    }
    

    试了一下,发现完全没有用,该报null Object还是报了。

    我想知道,我们平时用到的getApplicationContext()和getBaseContext()到底怎么实现的?

    于是我去看看Application的源码,有点意外的发现,Application本身是没有getApplicationContext()和getBaseContext()这两个方法的。但同时我也看到Application还继承了一个叫ContextWrapper的类
     

    于是我跑去ContextWrapper的类看看,果然发现了这两个方法

    看来问题就在这个mBase里了,可以看到源码的注释,这个mBase是在构造方法里或者setBaseContext里设置的,然而,我找了整个类,也没找到setBaseContext这个方法,只能去构造方法看看。

    看上去是在构造方法里设置值了,直到我跑回我们的主角Application里看看

    坑啊,派生类Application里直接把null传进了ContextWrapper的构造方法。那ContextWrapper的mBase到底是在哪里赋值的呢?

    实际上,mBase的赋值还是在ContextWrapper里赋值的

    是不是感觉很熟悉,就是在这个我们常用的attachBaseContext里赋值的,所以我们重写attachBaseContext的时候,一定要记得调一遍super.attachBaseContext()啊。那attachBaseContext是在什么时候调用的呢?找了一下,发现原来还是在Application里调用的,这也解释了为什么我们使用主工程的application的时候不会报null Object的错误。

    而attach是在什么时候调用的,我暂时还没找到,希望哪位大佬可以分享一下。

    既然知道了application最需要初始化的mBase在哪里初始化,那我们初始化module的application就操作就变得很清晰了。下面直接上代码。

    public class MainApplication extends Application {
    
        private ModuleApplication moduleApplication;//module的Application映射
    
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            //....一些主工程的初始化操作
    
            //同步Module的Application的onCreate
            if (moduleApplication != null){
                moduleApplication.onCreate();//用于执行module的一些自定义初始化操作
            }
        }
    
        @Override
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
    
            moduleApplication = getModuleApplicationInstance(this);
            try {
                //通过反射调用moduleApplication的attach方法
                Method method = Application.class.getDeclaredMethod("attach", Context.class);
                if (method != null) {
                    method.setAccessible(true);
                    method.invoke(moduleApplication, getBaseContext());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //映射获取ModuleApplication
        private ModuleApplication getModuleApplicationInstance(Context paramContext) {
            try {
                if (moduleApplication == null) {
                    ClassLoader classLoader = paramContext.getClassLoader();
                    if (classLoader != null) {
                        Class<?> mClass = classLoader.loadClass(ModuleApplication.class.getName());
                        if (mClass != null)
                            moduleApplication = (ModuleApplication) mClass.newInstance();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return moduleApplication;
        }
    }

    可以看到,实际上就是主工程的Application和module的Application共用一个base,最后我们想要的结果也实现了。

    在这里额外说明一下,我们初始化了ModuleApplication肯定是想用的,但使用时要注意一下,如果直接在module里使用getApplication(),获取到的仍然是主工程的Application,因而,如果想使用ModuleApplication,一个比较好的方式是保存下来application对象。例如:

    public ModuleApplication extends Application{
        private static ModuleApplication instance;
        
        public void onCreate(){
            super.onCreate();
            //...一些自定义操作
            instance = this;
        }
    
        public static getInstance(){
            return instance;
        }
    }

    很简单,就是初始化后把对象保存下来,之后要用到Module Application时,就用ModuleApplication.getInstance()。

    展开全文
  • Android 集成第三方SDK Application多次初始化

    不知道大家有没有遇到过, 在集成多个第三方 SDK 时 ( 比如集成环信和百度地图就会 ), 有时候 Application 的 onCreate ( ) 方法会执行多次, 这样就回导致程序崩溃, 我是这么处理的:

    在 Application 的 onCreate ( ) 方法中调用 oneInit( ) 方法:

    //项目的包名
    public final static String PKG_NAME = "com.example.leon";
    
    /**
     * 单次初始化
     */
    public void oneInit() {
        int pid = android.os.Process.myPid();
        String processAppName = getAppName(pid);
        LogUtil.println("processAppName---" + processAppName);
        //默认的app会在以包名为默认的process name下运行,如果查到的process name不是APP的process name就return掉
        if (processAppName == null ||!processAppName.equalsIgnoreCase(PKG_NAME)) {
            LogUtil.println("enter the service process!");
            // 则此application::onCreate 是被service 调用的,直接返回
            return;
        }
    }
    
    private String getAppName(int pID) {
        String processName = null;
        ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
        List l = am.getRunningAppProcesses();
        Iterator i = l.iterator();
        while (i.hasNext()) {
            ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
            try {
                if (info.pid == pID) {
                    processName = info.processName;
                    return processName;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return processName;
    }
    展开全文
  • 最近项目中遇到一个问题:APP运行2个进程,然后发现APP的Application的onCreate被调用了两次,导致Application初始化了两次,造成app启动的时候非常缓慢而且已启动占用的内存很大,因为两个进程都初始化了相同的资源...

    最近项目中遇到一个问题:APP运行2个进程,然后发现APP的Application的onCreate被调用了两次,导致Application初始化了两次,造成app启动的时候非常缓慢而且已启动占用的内存很大,因为两个进程都初始化了相同的资源,而且两个进程是相互独立的,所以各自初始化的资源都是独立的,也就是初始化了两份一样的资源;
    原因:APP运行多进程导致Application被初始话多次
    解决方案:获取当前进程的名称,然后根据进程名称匹配你要初始化的进程,再初始化相关进程的Applicaition

    public static String getProcessName(Context cxt, int pid) {
            ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
            if (runningApps == null) {
                return null;
            }
            for (ActivityManager.RunningAppProcessInfo procInfo : runningApps) {
                if (procInfo.pid == pid) {
                    return procInfo.processName;
                }
            }
            return null;
        }

    然后在Application里面添加:

    // 多进程导致多次初始化Application,这里只初始化App主进程的Application
    String curProcessName = getCurProcessName(this);
            if (!curProcessName.equals(getPackageName())) {
                return;
            }
    展开全文
  • Android 多进程会多次初始化 Application

    千次阅读 2016-08-21 22:12:04
    集成某 SDK 后 APP 多了一个进程,打 log 的时候偶然发现Application 初始化了两次,虽然对 APP 本身没什么影响,但多初始化一次也没什么用 - - 解决方法就是判断当前进程是否是 APP 默认进程,是才进行初始化操作,...

    集成某 SDK 后 APP 多了一个进程,打 log 的时候偶然发现Application 初始化了两次,虽然对 APP 本身没什么影响,但多初始化一次也没什么用 - -

    解决方法就是判断当前进程是否是 APP 默认进程,是才进行初始化操作, APP 默认进程名就是包名。

    @Override
        public void onCreate() {
            super.onCreate();
            String curProcess = OsUtils.getProcessName(this, Process.myPid());
            if (!getPackageName().equals(curProcess)) {
                return;
            }
    
            ... // 初始化操作
        }
        ...
    }

    获取进程名的方法:

       public static String getProcessName(Context cxt, int pid) {
            ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
            if (runningApps != null && !runningApps.isEmpty()) {
                for (ActivityManager.RunningAppProcessInfo procInfo : runningApps) {
                    if (procInfo.pid == pid) {
                        return procInfo.processName;
                    }
                }
            }
    
            return null;
        }
    展开全文
  • 刚刚接触Felx,有点让人摸不着头脑,特别是在使用mxml文件时,尤为明显。因此,弄清楚Application的初始化非常...2. 初始化Application.systemManager 3. Application在初始化过程之前, 派发预初始化事件(preinitial
  • application初始化

    2018-09-16 19:24:35
    public class BaseApplication extends Application { private DiskCache diskCache; private File file; @Override public void onCreate() { super.onCreate(); if (Environm...
  • Spring初始化ApplicationRunner、InitializingBean、@PostConstruct执行顺序问题前言一、ApplicationRunner 接口的用法二、InitializingBean接口的用法三、@PostConstruct注解的用法三者在Spring项目启动的执行...
  • Spring初始化总结ApplicationListener

    千次阅读 2018-08-09 16:15:13
    我们在使用Spring开发的时候,很多的时候都需要在bean初始化之前,...但是这两种方法,我们很难控制执行的先后顺序,为了控制绝对的初始化顺序,所以我们需要使用ApplicationListener,这个类可以使用org.springfra...
  • 参考Android多module初始化application Android-组件化如何处理多个ModuleApplication共存问题? 一个重点: 在Application里,attachBaseContext()方法的执行顺序是在onCreate()之前的 组件化的目的是为了业务...
  • Application初始化

    千次阅读 2009-04-07 14:39:00
    FLEX生成的SWF运行的顺序是preloader->systemManager->FlexApplication started…然后才是preinitialize在所有的初始化之前触发,没有子组件的定义,但是可以引用组件的变量.、 initialize当所有子组件生成完成后触发...
  • 使用场景在一些业务场景中,当容器初始化完成之后,需要处理一些操作,比如一些数据的加载、初始化缓存、特定任务的注册等等。这个时候我们就可以使用Spring提供的ApplicationListener来进行操作。用法本文以在...
  • Replugin初始化流程
  • Application中的初始化

    千次阅读 2017-06-29 11:55:37
    每个进程开启走Application中的onCreate方法,保证一切进程在主线程中初始化,判断是否为主线程的方法如下:`public class HuaqianApplication extends Application {public static HuaqianApplication app;...
  • Android 的 Application 初始化

    千次阅读 2017-10-11 09:36:15
    在Android开发中如何使用Application类 自己独立开发项目之后,才发现对Application类并不十分了解,现在开始直接搭建一个新的项目,才踩过这个坑。 1.Context类 Android是用Java语言来编写和,然而Android却...
  • 之前在做项目时,遇到一个大坑,就是我的APP 的Application 的onCreate方法,竟然执行了好几次,这就导致我在onCreate里面做了一些初始化的操作被重复执行了,导致奇怪的bug产生。后来冷静下来分析一下,才发现有...
  • springboot的ApplicationRunner实现应用启动后初始化操作 在日常项目中可能会遇到一些需要在项目启动完成后进行的一些初始化操作。 实现: 定义一个类TestApplicationRunner实现ApplicationRunner接口,然后重写...
  • Flex Application 初始化事件的顺序

    千次阅读 2012-10-08 17:55:16
    Flex Application 初始化事件的顺序 (1)首先测试下单个Application初始化事件的顺序 顺序如下: preinitialize 在组件初始化序列开始时调度。在这个事件里面调用Application里的组件会出错。因为这个时候组件...
  • 一直没怎么搞清楚FLEX组件的初始化顺序。认真学习了一下! FLEX生成的SWF运行的顺序是preloader->systemManager->FlexApplication started...然后才是preinitialize 在所有的初始化之前触发,没有子组件的定义,但是...
  • 加载与初始化Flex Application

    千次阅读 2011-08-25 15:34:08
    10. 所有内容(运行时共享库和主swf)加载完毕后,Preloader派发initProgress事件,此事件告知SystemManager所有内容准备就绪,可以开始初始化Application对象了。 11. SystemManager接收initProgress事件,跳至...
  • JavaFx Application 给控件做初始化

    千次阅读 2020-06-07 17:30:41
    JavaFx Application给控件做初始化 javafx里面想要给控件做初始化我知道两种: 1. 在stage加载fxml布局文件的时候 search = FXMLLoader.load(Main.class.getResource("fxml/*.fxml")); search.lookup("#id");//这...
  • Flex Application 初始化顺序

    千次阅读 2008-09-25 20:07:00
    preloader->systemManager->FlexApplication started…然后才是preinitialize在所有的初始化之前触发,没有子组件的定义,但是可以引用组件的变量.initialize当所有子组件生成完成后触发,在这个时间点还没有组件被渲染...
  • App启动时Application初始化详解

    千次阅读 2016-12-01 11:27:32
    App的ActivityThread与Application详解一个App的程序入口到底是什么? 是ActivityThread.main(),每一个App应用都是由AMS通过Socket与Zygote进程进行通信,请求它fork一个子进程出来作为这个即将要启动的应用程序的...
  • 在实际开发工作中,有时需要在项目启动的时候初始化资源,例如:缓存、定时任务等等。 Spring Boot 提供了这样的方案,只要创建 Bean 实现CommandLineRunner或者ApplicationRunner即可。这两个的作用是相同的,只是...
  • 因项目需要预配置 文件加载路径,需要在项目启动完成后对配置文件所在的目录进行初始化。 下面简单说一说在SpringBoot中该如何去实现。 第一步 创建实现ApplicationListener接口的类 public class ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 442,035
精华内容 176,814
关键字:

初始化application