轉載:Android獲取其餘包的Context和在任意位置獲取應用程序Context

1.在任意位置獲取應用程序Context
java

Android程序中訪問資源時須要提供Context,通常來講只有在各類component中(Activity, Provider等等)才能方便的使用api來獲取Context;喜歡編程的人都知道,編寫工具類能夠有效的實現代碼複用,而在Android下某些工具類的編寫很讓人困惑,例如:咱們要在工具類中獲取SharedPreferences,那就須要Context的支持。android

爲了解決這寫由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注意事項:api

在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.獲取別的包的Contextapp

Android中有Context的概念,想必你們都知道。Context能夠作不少事情,打開activity、發送廣播、打開本包下文件夾和數據庫、獲取classLoader、獲取資源等等。若是咱們獲得了一個包的Context對象,那咱們基本上能夠作這個包本身能作的大部分事情。ide

              Context有個createPackageContext方法,能夠建立另一個包的上下文,這個實例不一樣於它自己的Context實例,可是功能是同樣的。工具


      這個方法有兩個參數:
1。packageName  包名,要獲得Context的包名
2。flags  標誌位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY兩個選項。 CONTEXT_INCLUDE_CODE的意思是包括代碼,也就是說能夠執行這個包裏面的代碼。CONTEXT_IGNORE_SECURITY的意思是忽略安全警告,若是不加這個標誌的話,有些功能是用不了的,會出現安全警告。
this


      下面給個小例子,執行另一個包裏面的某個類的方法。
      另一個包的包名是chroya.demo,類名Main,方法名print,代碼以下:

Java代碼 

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方法的代碼塊以下:

Java代碼 

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。

相關文章
相關標籤/搜索