最近我一直在研究有關java/android中的內存泄漏,以及幾乎所有的地方都說它不是匿名類我應該使用帶有弱引用的靜態內部類。
所以,在我的Android應用程序我開始這樣做,但很快就厭倦了它,因爲它是很多樣板代碼...我認爲有一個替代解決方案,我寧願使用,但我不確定就防止內存泄漏而言,它是靜態內部類的有效替代方案。正如我之前所說,我沒有看到任何其他地方建議的解決方案(都說使用靜態內部類),所以這就是爲什麼我不知道我的替代方案會工作。可能的替代靜態內部類以防止android/java中的內存泄漏?
生病使用從我的應用程序一個簡單的例子:
我有一類稱爲Web客戶端負責處理異步Web請求,並接受名爲iCallback的接口返回從服務器到呼叫者的響應,並在我的活動,一旦我得到這個回調我需要關閉對話框,也許執行一些活動相關的事情(如觸發onBackPressed()和setResult())。
所以這裏是我的靜態內部類我創建:
private static class CallBack implements WebClient.ICallback
{
private WeakReference<ProgressDialog> mProgDiag;
private WeakReference<BaseActivity> mActivity;
public CallBack(BaseActivity activity, ProgressDialog progDiag)
{
this.mProgDiag = new WeakReference<>(progDiag);
this.mActivity = new WeakReference<>(activity);
}
@Override
public void onCallback(String data)
{
String responseAsString = Utils.extractStringFromResponse(...);
final BaseActivity parentActivity = mActivity.get();
ProgressDialog dialog = mProgDiag.get();
if(dialog != null)
{
dialog.dismiss();
}
if (responseAsString == null)
{
if(parentActivity != null)
{
Utils.makeServerErrorDialog(parentActivity,
new iDialogButtonClickedListener()
{
@Override
public void onDialogButtonClicked()
{
parentActivity.onBackPressed();
}
});
}
return;
}
//everything is ok
if (responseAsString.equals("1"))
{
if(parentActivity != null)
{
Intent result = new Intent();
result.putExtra(...);
parentActivity.setResult(Activity.RESULT_OK, result);
}
}
else
{
Utils.reportErrorToServer(...);
if(parentActivity != null)
{
parentActivity.setResult(Activity.RESULT_CANCELED);
}
}
if(parentActivity != null)
{
parentActivity.onBackPressed();
}
}
}
所以對於每一個變量,我需要在這個靜態內部類我要創建一個新的弱引用,然後檢索對象本身,然後每次我想訪問它,我需要檢查它是否爲空...這對我來說看起來像很多代碼。
這裏是我建議的替代方法:
public abstract class BaseActivity extends AppCompatActivity
implements WebClient.ICallback
{
private static final String TAG = "BaseActivity";
WebClient.ICallback mCallBack;
ProgressDialog mProgDiag;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(...);
mCallBack = this;
//some code to invoke a server request on button click
//and passing mCallBack to the request
}
@Override
public void onCallback(String data)
{
String responseAsString = Utils.extractStringFromResponse(...);
mProgDiag.dismiss();
if (responseAsString == null)
{
Utils.makeServerErrorDialog(this,
new iDialogButtonClickedListener()
{
@Override
public void onDialogButtonClicked()
{
onBackPressed();
}
});
return;
}
//everything is ok
if (responseAsString.equals("1"))
{
Intent result = new Intent();
result.putExtra(...);
setResult(Activity.RESULT_OK, result);
}
else
{
Utils.reportErrorToServer(...);
setResult(Activity.RESULT_CANCELED);
}
onBackPressed();
}
@Override
protected void onPause()
{
mCallBack = null;
super.onPause();
}
@Override
protected void onResume()
{
super.onResume();
mCallBack = this;
}
}
對我來說這似乎更清潔:沒有創造和每一個變量i需要訪問弱引用的檢索的情況下,我可以直接調用活動的方法(例如onBackPressed ()),並且不檢查無處不在。
我現在必須檢查null的唯一地方是在調用callBack方法之前在WebClient類中。
所以我的問題是,這種方法在防止內存泄漏方面取得了相同的結果嗎?這是靜態內部類的「值得」替代嗎?
好問題,一直想知道我是否真的需要每個變量的WeakReference並且每次檢查爲空 – Denny
好吧,在你的解決方案中仍然需要一些'null'檢查。但我認爲你的主要問題是你在需要時檢查這些價值。只需做一次檢查(對於你的例子中的'parentActivity')。 – AxelH
Java中沒有這樣的「靜態內部類」,因爲「內部類」的Java定義是非靜態的嵌套類。 –