gpt4 book ai didi

android - 使用应用程序上下文而不是 Activity 上下文

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:05:04 25 4
gpt4 key购买 nike

这个问题是对 question 的扩展,我昨天发布的。我发现了可能的内存泄漏,并以正确的方式处理了这个问题。由非静态内部类引起的内存泄漏之一,更准确地说是非静态 Handler

但我今天面临一个新的内存泄漏问题。我读过这个 post ,本质是围绕着Context,Activity或者Application Context。 enter image description here

这是我从 Eclipse Memory Analyzer

得到的饼图

我看到此饼图的 Remainder 发生了变化,修复了 Handler 的问题后,Remainder 增加了 10.6 MB。

但是关于上下文问题,问题嫌疑人 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 类中,我还使用此上下文在 onPostExecute 方法中启动一个新的 Activity,这将使此上下文保持 Activity 状态。

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);
}
}

我需要上下文来启动这个新的 Activity,从资源中获取字符串等等。有什么可能的方法可以避免内存泄漏吗?感谢阅读这篇大文章,如果您需要更多代码或其他任何内容,请添加评论。

提前致谢。

最佳答案

您可能应该尽可能尝试使用 Application Context 而不是 Activity 上下文(并非总是可行)。

要从任何地方访问您的应用程序上下文,您可以定义自己的应用程序类

class MyApp extends Application
{
private static MyApp mInstance;

@Override
public void onCreate()
{
mInstance = this;
}

public static Context context()
{
return mInstance.getApplicationContext();
}

}

然后你在 list 中声明这个类

<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" android:name="com.myapp.MyAppClass">

并在适用的地方使用 MyApp.context()

关于android - 使用应用程序上下文而不是 Activity 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13509061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com