`
zhujianjia
  • 浏览: 478352 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

 
阅读更多

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

import android.app.Application;

public class MyApplication extends Application {
    private static MyApplication instance;

    public static MyApplication getInstance() {
        return instance;
    }

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

 然后在manifest中<application>中加入name="mypackage.MyApplication"就可以在任意类中使用MyApplication.getInstance()来获取应用程序Context了。

(二)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. 避免非静态的内部类,尽量使用静态类,避免生命周期问题,注意内部类对外部对象引用导致的生命周期变化

(三)获取别的包的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,代码如下:

package chroya.demo;  
  
import android.app.Activity;  
import android.os.Bundle;  
import android.util.Log;  
  
class Main extends Activity {  
      
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
    }  
      
    public void print(String msg) {  
        Log.d("Main", "msg:"+ msg);  
    }  
}  

  本包的调用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,还可以做很多事情,当然,题目所说的坏事,还是不要做为好

 

转自:http://www.cnblogs.com/Greenwood/archive/2011/04/02/2003803.html

分享到:
评论

相关推荐

    在C++程序中使用QML

    如果应用程序需求在QML组件实例间需求不同的设置只需要多个QDeclarativeEngine。 使用QDeclarativeComponent类载入QML Documents。每个QDeclarativeComponent实例呈现单一QML文档。QDeclarativeComponent可以传递一...

    Oracle9i的init.ora参数中文说明

    说明: 确定查询是否获取表级的读取锁, 以防止在包含该查询的事务处理被提交之前更新任何对象读取。这种操作模式提供可重复的读取, 并确保在同一事务处理种对相同数据的两次查询看到的是相同的值。 值范围: TRUE | ...

    Android插件框架Android-Plugin-Framework.zip

    1种是fragment运行在任意支持fragment的activity中,这种方式,在开发fragment的时候,fragmeng中凡是要使用context的地方,都需要使用通过PluginLoader.getPluginContext()获取的context,那么这种fragment对其运行...

    新版Android开发教程.rar

    Android 是一个专门针对移动设备的软件集,它包括一个操作系统,中间件和一些重要的应用程序。 Beta 版 的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 ...

    JAVA上百实例源码以及开源项目

     Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...

    JAVA上百实例源码以及开源项目源代码

     Java 3DMenu 界面源码,有人说用到游戏中不错,其实平时我信编写Java应用程序时候也能用到吧,不一定非要局限于游戏吧,RES、SRC资源都有,都在压缩包内。 Java zip压缩包查看程序源码 1个目标文件 摘要:Java源码...

    ASP.net技术内幕

    15.2 使用应用程序状态 15.2.1 理解应用程序状态和同步 15.2.2 使用Global.asax文件 15.2.3 理解Context和使用Global.asax文件 15.2.4 处理应用程序Start和Init事件 15.2.5 处理...

    asp.net技术内幕(1)

    15.2 使用应用程序状态 15.2.1 理解应用程序状态和同步 15.2.2 使用Global.asax文件 15.2.3 理解Context和使用Global.asax文件 15.2.4 处理应用程序Start和Init事件 15.2.5 处理Application...

    asp.net技术内幕(2)

    15.2 使用应用程序状态 15.2.1 理解应用程序状态和同步 15.2.2 使用Global.asax文件 15.2.3 理解Context和使用Global.asax文件 15.2.4 处理应用程序Start和Init事件 15.2.5 处理Application...

    asp.net技术内幕(5)

    15.2 使用应用程序状态 15.2.1 理解应用程序状态和同步 15.2.2 使用Global.asax文件 15.2.3 理解Context和使用Global.asax文件 15.2.4 处理应用程序Start和Init事件 15.2.5 处理Application...

    asp.net技术内幕(4)

    15.2 使用应用程序状态 15.2.1 理解应用程序状态和同步 15.2.2 使用Global.asax文件 15.2.3 理解Context和使用Global.asax文件 15.2.4 处理应用程序Start和Init事件 15.2.5 处理Application...

    asp.net技术内幕(3)

    15.2 使用应用程序状态 15.2.1 理解应用程序状态和同步 15.2.2 使用Global.asax文件 15.2.3 理解Context和使用Global.asax文件 15.2.4 处理应用程序Start和Init事件 15.2.5 处理Application...

    基于SIP开发软件电话的一些资源(转自YOUTOO)

    我们先进行一个简单的纯SIP信令(不带语音连接建立)的UAC的SIP终端的程序开发的试验(即一个只能作为主叫不能作为被叫的的SIP软电话模型),我们创建一个MFC应用程序,对话框模式,照上面的说明,...

    海康视频卡动态库

    /// 此DSP上第一个编码通道在所有编码通道中的索引 /// uint firstEncodeChannelIndex; /// /// 此DSP所包含的解码通道个数 /// uint decodeChannelCount; /// /// 此DSP上第一个解码通道在所有解码...

Global site tag (gtag.js) - Google Analytics