精华内容
下载资源
问答
  • 初始化application
    千次阅读
    2016-03-24 16:33:03

    最近项目中遇到一个问题: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多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()。

    展开全文
  • Context的继承结构从图中可以看到,直系子类有两个,一个是ContextWrapper,一个是ContextImpl。...而ContextWrapper又有三个直接的子类,ContextThemeWrapper、Service和Application。其中,ContextThe...

    Context的继承结构从图中可以看到,直系子类有两个,一个是ContextWrapper,一个是ContextImpl。那么从名字上就可以看出,ContextWrapper是上下文功能的封装类,而ContextImpl则是上下文功能的实现类。而ContextWrapper又有三个直接的子类,ContextThemeWrapper、Service和Application。其中,ContextThemeWrapper是一个带主题的封装类,而它有一个直接子类就是Activity。

    在这里我们至少看到了几个所比较熟悉的面孔,Activity、Service、还有Application。由此,其实我们就已经可以得出结论了,Context一共有三种类型,分别是Application、Activity和Service。这三个类虽然分别各种承担着不同的作用,但它们都属于Context的一种,而它们具体Context的功能则是由ContextImpl类去实现的。

    一种比较特殊的情况是Dialog要求在Activity的Context中弹出,而一些全局的例如网络终端的Dialog需要什么特殊权限。

    2. Application类在项目开发中的使用

    首先在项目目录下一个Java类继承Application类,实现是onCreate()方法。这个类可以做APP的全局初始化工作,比如图片加载框架的全局配置信息设置。

    public class MyApplication extends Application {

    private static MyApplication myApplication;

    @Override

    public void onCreate() {

    super.onCreate();

    myApplication = this;

    }

    public static MyApplication getInstance(){

    return myApplication;

    }

    }

    然后千万不要忘了在Android项目的Manifest文件中指定Application的实现类,不然系统会创建一个默认的Application类。

    android:name=".MyApplication"

    android:allowBackup="true"

    android:icon="@mipmap/ic_launcher"

    android:label="@string/app_name"

    android:roundIcon="@mipmap/ic_launcher_round"

    android:supportsRtl="true"

    android:theme="@style/AppTheme">

    3. Application类或Context类的误用情况

    1. 不能用Application缓存数据!!!

    因为Application会因为进入background后内存不足被系统干掉,进入后系统会重现创建一个Application类,而导致缓存在Application类里的数据全部初始化而丢失。

    2. 错误的获取全局Context对象的方式

    public class AnddroidApplication extends Application {

    private static AnddroidApplication app;

    public static AnddroidApplication getInstance() {

    if (app == null) {

    app = new AnddroidApplication();

    }

    return app;

    }

    }

    上面这种方式如果是单纯的Java工程可能没有问题,但是在Android里这样说大错特错的。因为Application是系统组件,系统组件实例是要由系统去创建的,如果我们这里直接创建一个,不过是简单的Java对象而已,不具备任何Context能力,也无法进行任何Context操作。标准的写法就本文的第一段示意代码那样。

    3. 在控件的构造方法中获取Context或者做其他视图操作

    写过Android的同学应该知道自己或者看别人dome都很少或者基本看不到在控件构造函数内进行初始化,获取参数等这些操作吧!是的,这样做是很容易出难以发现的Bug的。具体原因是在ContextWrapper类的源码中,他有一个attachBaseContext()方法,这个方法会将传入的一个Context参数赋值给mBase对象,之后mBase对象就有值了。而我们又知道,所有Context的方法都是调用这个mBase对象的同名方法,那么也就是说如果在mBase对象还没赋值的情况下就去调用Context中的任何一个方法时,就会出现空指针异常,上面的代码就是这种情况。Application中方法的执行顺序如下图所示:

    0818b9ca8b590ca3270a3433284dd417.png

    展开全文
  • 源码分析之——Application初始化流程

    千次阅读 2022-01-25 14:39:45
    Android的小伙伴应该对Application都很熟悉了,也知道在自己的项目中如何使用Application,是不是如下所示? public class MainApplication extends BaseApplication { @Override protected void attachBaseContext...

    在这里插入图片描述

    前言

    做完年终总结,顿感时间飞逝,春去秋来,一转眼已是年底。回想过去的一年,未感技术有所精益,徒有年龄不断增长,内心惶恐万分,坐立不安,遂拾起键盘,写下这篇文章。盼望能和各位仁人志士不断交流学习,共同进步。
    在这里插入图片描述

    Android的小伙伴应该对Application都很熟悉了,也知道在自己的项目中如何使用Application,是不是如下所示?

    public class MainApplication extends BaseApplication {
        @Override
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
            MultiDex.install(base);
        }
    
            @Override
        public void onTerminate() {
            super.onTerminate();
        }
        
    }
    
    public abstract class BaseApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
            initSystem();
        }
    
        protected abstract void initSystem();
    
    }
    

    看了以上代码,有些同学就会问了,这个Application到底是干嘛的?在应用层我们也没调用呀,它到底是如何被启动的呢?
    抱着这个疑问,本文将站在AMS的角度来分析Application的启动流程,如有错误的地方还请不吝赐教。

    启动流程

    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • 无非就是异步初始化,延迟初始化,懒加载三种,我先对application中的初始化代码块做异步初始化 优化后加快了300ms,使用线程池,大概代码如下 ``` class Application{ onCreate(){ //do sth ...
  • Android 多进程会多次初始化 Application

    千次阅读 2016-08-21 22:12:04
    集成某 SDK 后 APP 多了一个进程,打 log 的时候偶然发现Application 初始化了两次,虽然对 APP 本身没什么影响,但多初始化一次也没什么用 - - 解决方法就是判断当前进程是否是 APP 默认进程,是才进行初始化操作,...
  • 1.问题:安卓在初始化Application时,数据被初始化了两遍,我在Application中初始化了本地的一些数据存到数据库中以供项目中使用,但是在初始化的时候发现数据存储了两遍,刚开始还以为是方法调用重复,后来检测了代码未...
  • Android组件Application

    千次阅读 2019-12-25 22:44:59
    上一篇文章笼统的总结了一下组件开发的一些基础性问题,本篇文章继续组件的学习,主要分如下三个方面介绍组件中的 Application 如下: Application的作用 合并Application 动态配置Application Application...
  • CommandLineRunner和ApplicationRunner在SpringApplication.run()之前,在所有的beans加载完成之后执行,用于执行一些初始化操作(如加载缓存、读取配置文件、创建线程池等) CommandLineRunner和ApplicationRunner的...
  • 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...
  • Android 集成第三方SDK Application多次初始化
  • 主要介绍了IOS初始化控制器的实现方法总结的相关资料,这里提供两种实现方法分别是ViewControllViewController方法和 ViewControllViewController 与 xib方法,需要的朋友可以参考下
  • springboot的ApplicationRunner实现应用启动后初始化操作 在日常项目中可能会遇到一些需要在项目启动完成后进行的一些初始化操作。 实现: 定义一个类TestApplicationRunner实现ApplicationRunner接口,然后重写...
  • 主要介绍了详解SpringBoot程序启动时执行初始化代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Spring初始化ApplicationRunner、InitializingBean、@PostConstruct执行顺序问题前言一、ApplicationRunner 接口的用法二、InitializingBean接口的用法三、@PostConstruct注解的用法三者在Spring项目启动的执行...
  • 在实际开发工作中,有时需要在项目启动的时候初始化资源,例如:缓存、定时任务等等。 Spring Boot 提供了这样的方案,只要创建 Bean 实现CommandLineRunner或者ApplicationRunner即可。这两个的作用是相同的,只是...
  • App启动时Application初始化详解

    万次阅读 2016-12-01 11:27:32
    App的ActivityThread与Application详解一个App的程序入口到底是什么? 是ActivityThread.main(),每一个App应用都是由AMS通过Socket与Zygote进程进行通信,请求它fork一个子进程出来作为这个即将要启动的应用程序的...
  • 原文: Your android libraries should not ask for an application context通常来说,当我们引入一个第三方库,...
  • 之前在做项目时,遇到一个大坑,就是我的APP 的Application 的onCreate方法,竟然执行了好几次,这就导致我在onCreate里面做了一些初始化的操作被重复执行了,导致奇怪的bug产生。后来冷静下来分析一下,才发现有...
  • 然后就会显示项目已卸载,重新加载也加载不进去,最后发现是我把操作系统自带的ISS Express一不小心卸载了,在官网重新下载一个ISS Express就能重新打开了
  • visual studio 2017 配置IIS Express 失败,初始化 applicationhost.config文件失败,找不到IIS Express。cocos2dx网页游戏网站形式打开错误 先检查一下IIS Express有没有下,我的vs以前也不知道怎么下的,IIS ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 517,525
精华内容 207,010
关键字:

初始化application