一些帮助发现内存泄漏

时间:2011-01-03 20:30:22

标签: android memory-management memory-leaks

我有几个人使用我的应用程序,听起来,几天之后,如果我的应用程序没有被杀死,手机响应速度会变慢,而且有点奇怪。

我想要一些内存管理方面的帮助。我有几个问题:

1)我在应用程序中很少引用静态类或变量。我有一个类(在它自己的文件中),它本质上是一个Singleton。这个类只有方法。没有变数等。我的应用程序大量使用Web服务调用,这个类是它的访问点。在此类中调用方法将引导IntentService,该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查询Cursor。当AsyncQueryHandler收到Cursor时,我在CursorAdapter上调用changeCursor,传入这个新的Cursor。在我的CursorAdapter的changeCursor处理程序中,我将Cursor传递给super,然后将我的Activity的私有Cursor成员变量设置为此Cursor并在其上调用startManagingCursor。

在此之后,我没有在onPause()或onStop()方法中做任何事情来停止管理Cursor或将其null或任何东西。这是错的吗?我想通过运行一点测试可能会有一些泄漏。如果我向下滚动ListView并旋转屏幕,则“销毁”活动,重新创建,查询新的Cursor,ListView自动滚动到旋转屏幕之前的位置。显然它仍然可以访问前面的Cursor,对吗?我不确定Android是如何做到的。

如果我打电话给mCursor.close();在onStop()处理程序中,这会产生问题。当屏幕旋转并填充时,用户会丢失其滚动位置。这显然是不可取的。那我该怎么办?我是否获得滚动位置,关闭光标,然后通过savedInstanceState传递滚动位置?

3)如何独立运行爆破的DDMS?如果我打开Eclipse打开它,它会对已经运行和关闭的DDMS实例抱怨。如果我关闭Eclipse,启动模拟器,然后启动独立的DDMS,它什么都看不到。

4)鉴于您对我的Android体验的了解(基于此帖或其他人),我还应该注意什么?我已经阅读了Romain Guy的一些文章,我已经摆脱了潜在的问题,但肯定还有更多我还没有意识到。

1 个答案:

答案 0 :(得分:0)

为什么要从callWebService方法启动服务?只需用该方法完成工作。如果你真的认为它应该是一个服务,只需抛弃单例并让你的活动绑定到服务并在那里调用它的方法。

是的,这是错的,你必须关闭光标。您应该在onStop中关闭它并在onStart或onResume上打开它(如果必须的话)。你真的应该尽快关闭它。