在Android開發的過程當中,不免會使用單例模式或者靜態方法工具類.咱們會讓它們持有一些外部的Context或者View通常有如下幾種狀況:app
上面我已經說明了會內存泄露的狀況,咱們就來逐一詳細說明下如何操做,和證實他們是否會內存泄露ide
在講解關於靜態持有Context以前,咱們須要來認識一下Context本身的區別,原則上Context其實只有2種(儘管Activity/Fragment/Service/都有Context,可是實際上他們屬於一個類型的Context)工具
應用的Context,下面的2行代碼都是調用應用的Context,這個Context在一個app裏只會有一個.而且在App啓動時建立,App關閉時消亡,因此這個Context是貫徹App生命週期全程的.this
Context applicationContext = getApplicationContext();
Context baseContext = getBaseContext();
Activity 或者 Service 本身,Activity 或 Service本身自己就是Context,這種Context的生命週期只在Activity或Service的生命週期下,關閉了Activity後Context理所應當的也隨着消亡.有多少Activity和Service就會有多少個Context,而且重複屢次建立某個Activity的時候Context也是多個spa
首先說明,持有View和持有Context都是同樣的道理,因此我這裏就不在驗證持有View的狀況code
驗證順序是這樣的,我在MainActivity裏反覆啓動退出TestActivity,而後在TestActivity的onCreate方法裏調用單例類而且讓它持有Context,而後咱們在用Android studio自帶的內存泄露工具來分析.在這篇中,我將貼全代碼,後續只會將單例類或者工具類貼出.blog
首先咱們建立一個簡單的單例模式,而且讓它的全局變量持有Context生命週期
public class SingleMode { private static SingleMode mSingleMode; private Context mContext; private SingleMode(){ } public static synchronized SingleMode I(){ if (mSingleMode == null){ mSingleMode = new SingleMode(); } return mSingleMode; } public void setContext(Context context){ this.mContext = context; } }
而後讓TestActivity裏讓調用這個單例類內存
public class TestActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); SingleMode.I().setContext(this); } }
而後咱們在MainActivity裏啓動這個TestActivity開發
public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getName(); private Button btn1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn1 = findViewById(R.id.btn1); btn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this,TestActivity.class); startActivity(intent); } }); } }
手動反覆進出屢次,而後咱們在退出到MainActivity裏,抓取內存泄露信息
從內存泄露分析裏,能夠看到我已經返回到MainActivity有一段時間了,而且主動手動清理一次內存,可是在查找包下面咱們依然能夠看到TestActivity在存活,而且存活了多個,而SingleMode在存活是正常的由於靜態存活時間是最長的.換句話說就是由於SingleMode在存活而且持有Context才致使內存泄露了