(十七)Android获取其他包的Context和在任意位置获取应用程序Context(转载http://blog.sina.com.cn/s/blog_46726d240100usn9.html)

1.在任意位置获取应用程序Context

Android程序中访问资源时需要提供Context,一般来说只有在各种component中(Activity, Provider等等)才能方便的使用api来获取Context;喜欢编程的人都知道,编写工具类可以有效的实现代码复用,而在Android下某些工具类的编写很让人困惑,例如:我们要在工具类中获取SharedPreferences,那就需要Context的支持。

为了解决这写由Context带来的麻烦,我们可以自定义一个Application类来实现这种功能。

import android.app.Application;

public class ContextUtil extends Application {
    private static ContextUtil instance;

public static ContextUtil getInstance() {
        return instance;
    }

@Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        instance = this;
    }
}

然后在manifest中<application>中加入Android:name="mypackage.ContextUtil",这样我们就可以在任何一个类下面获取Context,例如:Context c=ContextUtil.getInstance();

2.context注意事项:

在android中context可以作很多操作,但是最主要的功能是加载和访问资源。在android中有两种context,一种是 application context,一种是activity context,通常我们在各种类和方法间传递的是activity context。
比如一个activity的onCreate:
protected void onCreate(Bundle state) {
        super.onCreate(state);

TextView label = new TextView(this); //传递context给view control
        label.setText("Leaks are bad");

setContentView(label);
}
把activity context传递给view,意味着view拥有一个指向activity的引用,进而引用activity占有的资源:view hierachy, resource等。
这样如果context发生内存泄露的话,就会泄露很多内存。
这里泄露的意思是gc没有办法回收activity的内存。

Leaking an entire activity是很容易的一件事。

当屏幕旋转的时候,系统会销毁当前的activity,保存状态信息,再创建一个新的。

比如我们写了一个应用程序,它需要加载一个很大的图片,我们不希望每次旋转屏 幕的时候都销毁这个图片,重新加载。实现这个要求的简单想法就是定义一个静态的Drawable,这样Activity 类创建销毁它始终保存在内存中。
实现类似:
public class myactivity extends Activity {
        private static Drawable sBackground;
        protected void onCreate(Bundle state) {
                super.onCreate(state);

TextView label = new TextView(this);
                label.setText("Leaks are bad");

if (sBackground == null) {
                        sBackground = getDrawable(R.drawable.large_bitmap);
                }
        label.setBackgroundDrawable(sBackground);//drawable attached to a view

setContentView(label);
        }
}
这段程序看起来很简单,但是却问题很大。当屏幕旋转的时候会有leak(即gc没法销毁activity)。
我们刚才说过,屏幕旋转的时候系统会销毁当前的activity。但是当drawable和view关联后,drawable保存了view的 reference,即sBackground保存了label的引用,而label保存了activity的引用。既然drawable不能销毁,它所 引用和间接引用的都不能销毁,这样系统就没有办法销毁当前的activity,于是造成了内存泄露。gc对这种类型的内存泄露是无能为力的。

避免这种内存泄露的方法是避免activity中的任何对象的生命周期长过activity,避免由于对象对 activity的引用导致activity不能正常被销毁。我们可以使用application context。application context伴随application的一生,与activity的生命周期无关。application context可以通过Context.getApplicationContext或者Activity.getApplication方法获取。

避免context相关的内存泄露,记住以下几点:
1. 不要让生命周期长的对象引用activity context,即保证引用activity的对象要与activity本身生命周期是一样的
2. 对于生命周期长的对象,可以使用application context
3. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化

3.获取别的包的Context

Android中有Context的概念,想必大家都知道。Context可以做很多事情,打开activity、发送广播、打开本包下文件夹和数据库、获取classLoader、获取资源等等。如果我们得到了一个包的Context对象,那我们基本上可以做这个包自己能做的大部分事情。

Context有个createPackageContext方法,可以创建另外一个包的上下文,这个实例不同于它本身的Context实例,但是功能是一样的。

这个方法有两个参数:
1。packageName  包名,要得到Context的包名
2。flags  标志位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY两个选项。 CONTEXT_INCLUDE_CODE的意思是包括代码,也就是说可以执行这个包里面的代码。CONTEXT_IGNORE_SECURITY的意思是忽略安全警告,如果不加这个标志的话,有些功能是用不了的,会出现安全警告。

下面给个小例子,执行另外一个包里面的某个类的方法。
      另外一个包的包名是chroya.demo,类名Main,方法名print,代码如下:

本包的调用Main的print方法的代码块如下:

Java代码

ok,这样,我们就调用了chroya.demo包的Main类的print方法,执行结果,打印出了Hello。

Android中有Context的概念,想必大家都知道。Context可以做很多事情,打开activity、发送广播、打开本包下文件夹和数据库、获取classLoader、获取资源等等。如果我们得到了一个包的Context对象,那我们基本上可以做这个包自己能做的大部分事情。

那我们能得到吗?很高兴的告诉你,能!
      Context有个createPackageContext方法,可以创建另外一个包的上下文,这个实例不同于它本身的Context实例,但是功能是一样的。

这个方法有两个参数:
1。packageName  包名,要得到Context的包名
2。flags  标志位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY两个选项。CONTEXT_INCLUDE_CODE的意思是包括代码,也就是说可以执行这个包里面的代码。CONTEXT_IGNORE_SECURITY的意思是忽略安全警告,如果不加这个标志的话,有些功能是用不了的,会出现安全警告。

下面给个小例子,执行另外一个包里面的某个类的方法。
      另外一个包的包名是chroya.demo,类名Main,方法名print,代码如下:

本包的调用Main的print方法的代码块如下:

Context c = createPackageContext("chroya.demo", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
//载入这个类
Class clazz = c.getClassLoader().loadClass("chroya.demo.Main");
//新建一个实例
Object owner = clazz.newInstance();
//获取print方法,传入参数并执行
Object obj = clazz.getMethod("print", String.class).invoke(owner, "Hello");

ok,这样,我们就调用了chroya.demo包的Main类的print方法,执行结果,打印出了Hello。

怎么样,这只是一个调用其他包的代码的例子,我们获取到Context,还可以做很多事情,当然,题目所说的坏事,还是不要做为好。

时间: 2024-10-14 07:59:30

(十七)Android获取其他包的Context和在任意位置获取应用程序Context(转载http://blog.sina.com.cn/s/blog_46726d240100usn9.html)的相关文章

在任意位置获取应用程序CONTEXT

Android程序中访问资源时需要提供Context,一般来说只有在各种component中(Activity, Provider等等)才能方便的使用api来获取Context, 而在某些工具类中要获取就很麻烦了.为此,我们可以自定义一个Application类来实现这种功能. import android.app.Application; public class MyApplication extends Application {    private static MyApplicati

Android x86模拟器Intel Atom x86 System Image配置与使用方法[转载:http://blog.sina.com.cn/s/blog_8669d5ab0101d3s9.html]

前言:大家现在开发使用的Android 模拟器模拟的是 ARM 的体系结构(arm-eabi),因此模拟器并不是运行在x86上而是模拟的ARM,所以我们调试程序的时候经常感觉到非常慢,大部分开发者应该都深有体会.针对这种情况,前段时间Intel推出了支持x86的Android模拟器,这将大大提高启动速度和程序的运行速度,这将允许Android模拟器能够以原始速度(真机运行速度)运行在使用Intel x86处理器的电脑中,各位开发者有福了,下面将为大家展示使用方法.一.首先下载intel提供的 

关于android中v7包(appcompat)的说明

关于android中v7包(appcompat)的说明,有需要的朋友可以参考下. 大家对于v4包都已经很熟悉了,现在在新建android项目时,v4包是默认导入的.v7包出来没多长时间,用的人也不多,主要对3.0以下版本提供ActionBar支持,以及SearchView,PopupMenu等控件的支持.因为一些开源框架已经实现对3.0以下版本ActionBar的支持,所以v7包的使用意义也不是很大.既然谷歌官方提供了这个功能,也很有必要学习一下.现在根据自己在官方文档上的学习和实践,现总结如下

Android sdk资源包res里面的drawable(ldpi、mdpi、hdpi、xhdpi、xxhdpi)

(1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854) (2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480) (3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320) ldpi:240x320 mdpi:320x480 hdpi:480x800.480x854 xhdpi:至少960*720 xxhdpi:1280×720 android 自适应 多屏幕支持 1.屏幕

Android获取APK包名的几种方法

Android获取APK包名的几种方法:1.adb shell pm list package -f | findstr 关键字 #只能获取到包名,主Activity名无法获取到 2.使用aapt--aapt是sdk自带的一个工具,在sdk\builds-tools\目录下 运行后的结果中以下两行分别是应用包名package和入口activity名称 package: name=’com.estrongs.android.pop’ launchable-activity: name=’com.e

Android学习笔记十七.Android数据存储与IO.File存储常用API

Android通过一套完整的I/O流体系,包括FileInputStream.FileOutputStream等,通过这些I/O流来访问手机存储上的文件. 一.API 1.File (1)功能:该类提供一些有限的功能-获取或设置文件的权限.文件类型.最后依次修改时间等,通常它所代表的文件名(包含路径)将被转换为UTF-8字节序列被使用. (2)继承关系 java.lang.Object ? java.io.File (3)构造方法  File(File dir, String name):构造一

android v7兼容包RecyclerView的使用(三)——布局管理器的使用

前两篇文章 android v7兼容包RecyclerView的使用(二) android v7兼容包RecyclerView的使用(一) 介绍了RecyclerView的基本用法以及与它相关的重要的几个类,本篇文章介绍布局管理器的具体用法. 为了演示布局管理器的使用,找了很多个例子,都没有找到感觉合适的例子,后来google了一把,发现了一个比较适合说明问题的例子.所以就拿该例子来解释吧. 在演示布局管理器前,我们先把UI部分搭建完成.由于使用到了V7兼容包的另一个包CardView,所以在这

Android应用开发-小巫CSDN博客client之获取评论列表

Android应用开发-小巫CSDN博客客户端之获取评论列表 上一篇博客介绍了博文具体内容的业务逻辑实现,本篇博客介绍小巫CSDN博客客户端的最后一项功能.获取评论列表,这个功能的实现跟前面获取文章列表和文章具体的内容不一样,CSDN博客获取评论是通过js来请求server载入评论列表的,返回数据为json数据.我们这里要做的事情就是找到这种一个js文件,再找到请求url的拼接字符串.然后依据我们的需求,请求文章的评论列表获取到当前文章的评论json数据,然后进行解析工作.最后展示到我们的界面其

android v7兼容包RecyclerView的使用(二)

上篇文章 android v7兼容包RecyclerView的使用(一)讲了RecyclerView的最基本用法,现在开始挖掘更详细的内容. 在RecyclerView的API中,有这样一句话 A flexible view for providing a limited window into a large data set. 大致意思就是:当有大量的数据显示在一个有限大小的窗口上时,RecyclerView就是解决这种情况的一个灵活的View. 从以上描述可以看出RecyclerView的