热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android开发分享在Android上获取“上下文”的静态方法?

有没有办法通过使用静态&#

有没有办法通过使用静态方法来获取当前的“上下文”实例?

我正在寻找这种方式,因为我讨厌每次更改时都保存“上下文”实例。

    做这个:

    在Android清单文件中,声明以下内容。

       

    然后写下这个class级:

     public class MyApplication extends Application { private static Context context; public void onCreate() { super.onCreate(); MyApplication.cOntext= getApplicationContext(); } public static Context getAppContext() { return MyApplication.context; } } 

    现在,无处不在调用MyApplication.getAppContext()静态获取您的应用程序上下文。

    不,我不这样认为。 不幸的是,你坚持从ActivityContext的其他子类之一调用getApplicationContext() 。 另外, 这个问题有些相关。

    大多数需要方便的方法来获取应用程序上下文的应用程序创build自己的扩展android.app.Application的类。

    指南

    您可以通过首先在您的项目中创build一个类来完成此任务,如下所示:

     import android.app.Application; import android.content.Context; public class App extends Application { private static Application sApplication; public static Application getApplication() { return sApplication; } public static Context getContext() { return getApplication().getApplicationContext(); } @Override public void onCreate() { super.onCreate(); sApplication = this; } } 

    然后,在您的AndroidManifest中,您应该在AndroidManifest.xml的标记中指定您的类的名称:

      ...  

    然后,您可以使用以下方法在任何静态方法中检索应用程序上下文:

     public static void someMethod() { Context cOntext= App.getContext(); } 

    警告

    在添加类似上面的东西到你的项目之前,你应该考虑文档说:

    通常不需要子类Application。 在大多数情况下,静态单例可以以更模块化的方式提供相同的function。 如果你的单例需要一个全局上下文(例如注册广播接收者),那么检索它的函数可以被赋予一个Context,它在第一次构造单例时在内部使用Context.getApplicationContext()。


    reflection

    还有另一种使用reflection来获取应用程序上下文的方法。 反思在Android中经常被看低,我个人认为这不应该用在生产中。

    为了检索应用程序上下文,我们必须调用一个隐藏类( ActivityThread )的方法,该方法从API 1开始已经可用:

     public static Application getApplicationUsingReflection() throws Exception { return (Application) Class.forName("android.app.ActivityThread") .getMethod("currentApplication").invoke(null, (Object[]) null); } 

    还有一个隐藏类( AppGlobals )提供了一种静态获取应用程序上下文的方法。 它使用ActivityThread获取上下文,所以下面的方法和上面发布的方法之间确实没有区别:

     public static Application getApplicationUsingReflection() throws Exception { return (Application) Class.forName("android.app.AppGlobals") .getMethod("getInitialApplication").invoke(null, (Object[]) null); } 

    快乐的编码!

    这是一个无证的方式从UI线程的任何地方获取应用程序 (这是一个上下文)。 它依赖隐藏的静态方法ActivityThread.currentApplication() 。 它应该至less在Android 4.x上工作。

     try { final Class activityThreadClass = Class.forName("android.app.ActivityThread"); final Method method = activityThreadClass.getMethod("currentApplication"); return (Application) method.invoke(null, (Object[]) null); } catch (final ClassNotFoundException e) { // handle exception } catch (final NoSuchMethodException e) { // handle exception } catch (final IllegalArgumentException e) { // handle exception } catch (final IllegalAccessException e) { // handle exception } catch (final InvocationTargetException e) { // handle exception } 

    请注意,此方法可能返回null,例如,当您在UI线程之外调用方法时,或者应用程序未绑定到线程时。

    如果您可以更改应用程序代码,则最好使用@RohitGhatol的解决scheme。

    这取决于你正在使用的上下文。 我可以想到这种方法至less有一个缺点:

    如果您尝试使用AlertDialog.Builder创buildAlertDialog.Builder ,则Application上下文将不起作用。 我相信你需要当前Activity的背景…

    假设我们正在讨论获取应用程序上下文,我按照@Rohit Ghatol扩展应用程序的build议来实现它。 那么发生了什么呢,就是不能保证以这种方式检索的上下文总是非空的。 在你需要的时候,通常是因为你想初始化一个帮手,或者得到一个资源,不能拖延时间; 处理空情况不会帮助你。 所以我明白,我基本上是在对付Android架构,正如文档中所述

    注意:通常不需要子类Application。 在大多数情况下,静态单例可以以更模块化的方式提供相同的function。 如果您的单例需要全局上下文(例如注册广播接收者),请在调用单例的getInstance()方法时将Context.getApplicationContext()作为Context参数包含在内。

    并由Dianne Hackborn解释

    应用程序存在的唯一原因是你可以从中得到,因为在1.0之前的开发过程中,我们的一个应用程序开发人员不停地窃听我需要有一个顶级的应用程序对象,他们可以从中得到更多的“正常“他们的应用模式,我最终放弃了,我会永远后悔让这个。 ?

    她也build议解决这个问题:

    如果你想要的是一些可以在应用程序的不同部分共享的全局状态,请使用单例。 […]这更自然地导致你应该如何pipe理这些东西 – 按需要初始化它们。

    所以我所做的是摆脱扩展应用程序,并直接将上下文传递给单例助手的getInstance(),同时在私有构造函数中保存对应用程序上下文的引用:

     private static MyHelper instance; private final Context mContext; private MyHelper(@NonNull Context context) { mCOntext= context.getApplicationContext(); } public static MyHelper getInstance(@NonNull Context context) { synchronized(MyHelper.class) { if (instance == null) { instance = new MyHelper(context); } return instance; } } 

    调用者然后将一个本地上下文传递给帮助者:

     Helper.getInstance(myCtx).doSomething(); 

    因此,要正确回答这个问题:有办法静态地访问应用程序上下文,但是他们都应该不鼓励,并且应该更喜欢将本地上下文传递给单例的getInstance()。


    对于任何感兴趣的人,您可以在fwd博客阅读更详细的版本

    如果你打算使用RoboGuice ,你可以把上下文注入到你想要的任何类中。 这里有一个小小的例子,介绍如何使用RoboGuice 2.0(本文写作时的beta 4)

     import android.content.Context; import android.os.Build; import roboguice.inject.ContextSingleton; import javax.inject.Inject; @ContextSingleton public class DataManager { @Inject public DataManager(Context context) { Properties properties = new Properties(); properties.load(context.getResources().getAssets().open("data.properties")); } catch (IOException e) { } } } 

    我在某个时候使用过这个:

     ActivityThread at = ActivityThread.systemMain(); Context cOntext= at.getSystemContext(); 

    这是我用于获取系统服务和工作的有效上下文。

    但是,我只在框架/基础修改中使用它,并没有在Android应用程序中尝试它。

    您必须知道的一个警告 :当使用这种上下文注册广播接收器时,它将不起作用,您将得到:

    java.lang.SecurityException:给定的调用者包android没有在ProcessRecord进程中运行

    我认为你需要一个getAppContext()方法的主体:

     public static Context getAppContext() return MyApplication.context; 

    您可以使用以下内容:

     MainActivity.this.getApplicationContext(); 

    MainActivity.java:

     ... public class MainActivity ... { static MainActivity ma; ... public void onCreate(Bundle b) { super... ma=this; ... 

    其他class级:

     public ... public ANY_METHOD... { Context c = MainActivity.ma.getApplicationContext(); 

    我使用Singletondevise模式的变体来帮助我。

     import android.app.Activity; import android.content.Context; public class ApplicationContextSingleton { private static Activity gContext; public static void setContext( Activity activity) { gCOntext= activity; } public static Activity getActivity() { return gContext; } public static Context getContext() { return gContext; } } 

    然后我调用ApplicationContextSingleton.setContext( this ); 在我的activity.onCreate()ApplicationContextSingleton.setContext( null );onDestroy() ;

    我刚刚发布了一个名为Vapor API的jQuery启发式Android框架,旨在简化应用程序开发。

    中心的$ facade类维护一个WeakReference (通过Ethan Nicholas链接到关于这个的很棒的Java博客文章)到当前的Activity上下文,你可以通过调用:

     $.act() 

    WeakReference维护一个引用,而不会阻止垃圾回收回收原始对象,所以你不应该有内存泄漏的问题。

    当然不利的$.act()是,你冒着$.act()可能返回null的风险。 我还没有遇到这种情况,所以这可能只是一个最小的风险,值得一提。

    如果您不使用VaporActivity作为Activity类,也可以手动设置上下文:

     $.act(Activity); 

    而且,大部分的VAPI API框架本身都使用这个存储的上下文,这可能意味着如果你决定使用这个框架,你就不需要自己存储它。 查看网站了解更多信息和样品。

    我希望帮助:)

    如果你出于某种原因需要任何类中的应用程序上下文,而不仅仅是那些扩展应用程序/活动的应用程序上下文,可能是一些工厂或辅助类。 您可以将以下单例添加到您的应用程序。

     public class GlobalAppContextSingleton { private static GlobalAppContextSingleton mInstance; private Context context; public static GlobalAppContextSingleton getInstance() { if (mInstance == null) mInstance = getSync(); return mInstance; } private static synchronized GlobalAppContextSingleton getSync() { if (mInstance == null) mInstance = new GlobalAppContextSingleton(); return mInstance; } public void initialize(Context context) { this.cOntext= context; } public Context getApplicationContext() { return context; } } 

    然后在你的应用程序类的onCreate中初始化它

     GlobalAppContextSingleton.getInstance().initialize(this); 

    通过电话随时随地使用

     GlobalAppContextSingleton.getInstance().getApplicationContext() 

    但是,我不build议这种方法,但除了应用程序上下文。 因为它可能导致内存泄漏。

    根据这个来源,你可以通过扩展ContextWrapper来获得你自己的Context

     public class SomeClass extends ContextWrapper { public SomeClass(Context base) { super(base); } public void someMethod() { // notice how I can use "this" for Context // this works because this class has it's own Context just like an Activity or Service startActivity(this, SomeRealActivity.class); //would require context too File cacheDir = getCacheDir(); } } 

    用于ContextWrapper的JavaDoc

    代理Context的实现,将其所有调用简单地委托给另一个Context。 可以被分类为修改行为而不更改原始上下文。

    所以我修改了接受的答案,因为它造成了内存泄漏,这就是我想出的…

       public class MyBakingAppContext extends Application { private static Object mContext; public void onCreate() { super.onCreate(); mCOntext= getApplicationContext(); } public static Context getAppContext() { return (Context)mContext; } } 

    我实际上做的是,分配上下文到一个对象,并返回对象作为上下文(将其转换为上下文)。 希望它有帮助。

    这将在AndroidManifest.xml文件中

       

    这是MyApplication.java文件

     public class MyApplication extends Application { private static MyApplication application; @Override public void onCreate() { super.onCreate(); application = this; } public static MyApplication getContext(){ return application; } } 

      以上就是android开发分享在Android上获取“上下文”的静态方法?相关内容,想了解更多android开发(异常处理)及android游戏开发关注(编程笔记)。


      推荐阅读
      • GetWindowLong函数
        今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
      • Java太阳系小游戏分析和源码详解
        本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
      • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
      • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
      • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
      • Java容器中的compareto方法排序原理解析
        本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
      • 如何用UE4制作2D游戏文档——计算篇
        篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
      • Spring特性实现接口多类的动态调用详解
        本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
      • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
      • Voicewo在线语音识别转换jQuery插件的特点和示例
        本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
      • PHP中的单例模式与静态变量的区别及使用方法
        本文介绍了PHP中的单例模式与静态变量的区别及使用方法。在PHP中,静态变量的存活周期仅仅是每次PHP的会话周期,与Java、C++不同。静态变量在PHP中的作用域仅限于当前文件内,在函数或类中可以传递变量。本文还通过示例代码解释了静态变量在函数和类中的使用方法,并说明了静态变量的生命周期与结构体的生命周期相关联。同时,本文还介绍了静态变量在类中的使用方法,并通过示例代码展示了如何在类中使用静态变量。 ... [详细]
      • XML介绍与使用的概述及标签规则
        本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
      • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
      • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
      • flowable工作流 流程变量_信也科技工作流平台的技术实践
        1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
      author-avatar
      僾媙
      这个家伙很懒,什么也没留下!
      PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
      Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有