この質問は、 昨日投稿したこの質問の拡張です。メモリリークの可能性があることを発見し、これを適切な方法で処理しました。非 static 内部クラス、より正確には非 static が原因のメモリ リークの 1 つHandler
。
しかし、今日、新しいメモリ リークの問題に直面しています。この投稿を読みました。エッセンスはContext
、Activity または Application Context に基づいています。
これは私が得た円グラフですEclipse Memory Analyzer
Remainder
この円グラフの問題を修正した後Handler
、残りが 10.6 MB 増加しました。
しかし、コンテキストの問題に移ると、Problem Suspect 2
どこを見るべきかのヒントが得られます
35 instances of "android.widget.FrameLayout", loaded by "<system class loader>" occupy 39 218 464 (39,94%) bytes.
Biggest instances:
•android.widget.FrameLayout @ 0x425aa258 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x425d9b20 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x42609258 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x4260a248 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x42925960 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x429808e0 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x429a4350 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x429d9b20 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x429e5710 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x42a28c98 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x42a51b80 - 3 266 728 (3,33%) bytes.
•android.widget.FrameLayout @ 0x46a8caf0 - 3 266 728 (3,33%) bytes.
を使用している場所でメモリリークが発生していることがわかりますFrameLayout
。FrameLayout を使用する唯一の場所は、Splash Screen
.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
utils = new AppUtils(getApplicationContext());
pd = (ProgressBar) findViewById(R.id.pd);
progress = (TextView) findViewById(R.id.progress);
version = (TextView)findViewById(R.id.version);
prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor prefEditor = prefs.edit();
prefEditor.putString("firstpw", "first");
prefEditor.commit();
folder = new CreateApplicationFolder(getApplicationContext(), true);
boolean isSDPresent = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
if (!isSDPresent) {
ErrorDialog dialog = new ErrorDialog(getApplicationContext(), getResources().getString(R.string.sdCardTitle),
getResources().getString(R.string.sdCardContent),
getResources().getString(R.string.ok), 2);
Log.i("SDCARD: ", "Is Not Present");
dialog.canCancelDialog(false);
} else {
Log.i("SDCARD: ", "Is Present");
version.setText("Version: " + utils.getAppVersion());
try {
new ReadConfig(Splash.this, pd, progress).execute("");
} catch (ParserConfigurationException e) {
Log.e("Parser: ", e.getMessage());
} catch (SAXException e) {
Log.e("Sax: ", e.getMessage());
} catch (IOException e) {
Log.e("IO: ", e.getMessage());
}
}
}
次のように、Activity コンテキストを AsyncTask に送信しているときに、メモリ リークが発生すると思われますReadConfig
。
try {
new ReadConfig(Splash.this, pd, progress).execute("");
} catch (ParserConfigurationException e) {
Log.e("Parser: ", e.getMessage());
} catch (SAXException e) {
Log.e("Sax: ", e.getMessage());
} catch (IOException e) {
Log.e("IO: ", e.getMessage());
}
また、ReadConfig クラスでは、このコンテキストを使用Activity
してonPostExecute
メソッドで新しいメソッドを開始しています。これにより、このコンテキストが維持されます。
protected void onPostExecute(String result) {
if (result.equals("noConfig")) {
Toast.makeText(context, context.getResources().getString(R.string.configNotFound),
Toast.LENGTH_LONG).show();
Intent mainIntent = new Intent(context, MainClass.class);
context.startActivity(mainIntent);
}
else if(result.equals("pathnotFound")) {
new ErrorDialog(context, context.getResources().getString(R.string.noBTFolderTitle), context.getResources().getString(R.string.noBtFolderContent), context.getResources().getString(R.string.exit), 2);
} else {
Intent mainIntent = new Intent(context, MainClass.class);
context.startActivity(mainIntent);
}
}
この新しいアクティビティを開始し、リソースから文字列を取得するなどのコンテキストが必要です。メモリリークを回避するためにこれを別の方法で行う方法はありますか? この大きな投稿を読んでくれてありがとう。さらにコードが必要な場合はコメントを追加してください。
前もって感謝します。