【发布时间】:2011-01-03 20:30:21
【问题描述】:
我有几个人在使用我的应用程序,听起来几天后,如果我的应用程序没有被杀死,手机的响应速度就会变慢并且有点奇怪。
我需要一些关于内存管理的帮助。我有几个问题:
1) 我在我的应用程序中很少引用静态类或变量。我有一个类(在它自己的文件中),它本质上是一个单例。这个类只有方法。没有变量之类的。我的应用程序大量使用了 Web 服务调用,而这个类就是它的访问点。调用此类中的方法将启动一个 IntentService,它会进行实际的 Web 服务调用。这是一个例子。请注意,callWebService 方法还引用了 MyIntentService.JOB_DELETE 和 MyIntentService.ITEM_ALL,它们是 MyIntentService 中的静态 int:
public class MySingleton {
private static MySingleton mInstance = null;
protected MySingleton() { }
public synchronized static MySingleton getInstance() {
if (mInstance == null) {
mInstance = new MySingleton();
}
return mInstance;
}
public void callWebService(Context appContext, int intUserId) {
Intent intent = new Intent();
intent.setClass(appContext, MyIntentService.class);
intent.putExtra("job", MyIntentService.JOB_DELETE);
intent.putExtra("data_type", MyIntentService.ITEM_ALL);
intent.putExtra("user_id", intUserId);
appContext.startService(intent);
}
}
在我的活动中,我调用:
MySingleton.getInstance().callWebService(getApplicationContext(), ((MyApplication)getApplicationContext()).getUserId());
我在这里做错了什么吗?由于这个 Singleton 只包含方法,所以最好不要让它成为 Singleton 并且所有方法都是静态的?
2) 光标。
我有几个使用 CursorAdapters 的 Activity。我将使用 AsyncQueryHandler 查询游标。当 AsyncQueryHandler 收到 Cursor 时,我在 CursorAdapter 上调用 changeCursor,传入这个新的 Cursor。在我的 CursorAdapter 的 changeCursor 处理程序中,我将 Cursor 传递给 super,然后将我的 Activity 的私有 Cursor 成员变量设置为此 Cursor 并在其上调用 startManagingCursor。
在此之后,我不会在 onPause() 或 onStop() 方法中执行任何操作来停止管理 Cursor 或将其清空或任何其他操作。这是错的吗?我想通过运行一个小测试可能会发生一些泄漏。如果我向下滚动 ListView 并旋转屏幕,Activity 被“销毁”,重新创建,查询一个新的 Cursor,ListView 自动滚动到屏幕旋转之前的位置。它显然仍然可以访问以前的光标,对吧?我不太确定 Android 是如何做到这一点的。
如果我调用 mCursor.close();在 onStop() 处理程序中,这会产生问题。当屏幕旋转并填充时,用户会失去滚动位置。这显然是不可取的。那我该怎么办?是否获取滚动位置,关闭Cursor,然后通过saveInstanceState 传递滚动位置?
3) 我如何单独运行该死的 DDMS?如果我在 Eclipse 打开的情况下打开它,它会抱怨 DDMS 实例已经在运行并关闭。如果我关闭 Eclipse,启动模拟器,然后启动独立的 DDMS,它什么也看不到。
4) 鉴于您对我的 Android 体验的了解(基于这篇文章或其他文章),我还应该注意什么?我已经阅读了 Romain Guy 的几篇文章,我已经摆脱了潜在的问题,但肯定还有更多我还没有意识到。
【问题讨论】:
-
不是答案,而是查找内存问题的有用工具,尤其是与对象保留有关的问题:我建议使用 Eclipse MAT 查看应用程序的 HPROF 转储(community.developer.motorola.com/t5/… 是一个很好的解释,使用Motodev 工作室;您可以在没有它的情况下执行此操作,只需将 HPROF 转储并自己加载到 MAT 中即可)。
标签: android memory-management memory-leaks