2011-01-03 10 views
2

私のアプリケーションを使用している人が少数で、数日後に電話が応答しなくなり、アプリが死んでいないとちょっと変わってしまいます。メモリリークを発見するのに役立つもの

私はメモリ管理について少し助けてください。私はいくつかの質問があります:

1)私はアプリケーション内で静的なクラスまたは変数への参照をほとんど作成しません。私は本質的にシングルトンである(独自のファイル内に)クラスを持っています。このクラスにはメソッドがあります。変数などはありません。私のアプリケーションはWebサービスコールを大量に使用し、このクラスはそのためのアクセスポイントです。このクラスのメソッドを呼び出すと、実際のWebサービス呼び出しを行うIntentServiceが起動します。ここに例があります。 callWebService方法もMyIntentServiceで静的int型ですMyIntentService.JOB_DELETEとMyIntentService.ITEM_ALLを、参照することに注意してください:私の活動の

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

私は何がありますここで間違っている?このシングルトンはメソッドのみで構成されているため、シングルトンではなく、すべてのメソッドを静的にする方が良いでしょうか?

2)カーソル。

私はCursorAdaptersを使用するいくつかのアクティビティを持っています。私は、AsyncQueryHandlerを使用してCursorをクエリします。 AsyncQueryHandlerがCursorを受け取ると、CursorAdapterでchangeCursorを呼び出し、この新しいCursorを渡します。私のCursorAdapterのchangeCursorハンドラでは、Cursorをsuperに渡してから、自分のActivityのprivate Cursorメンバー変数をこのCursorに設定し、startManagingCursorを呼び出します。

この後、私はonPause()またはonStop()メソッドで何もしないで、カーソルの管理を停止するか、またはそれを無効にします。これは間違っていますか?私は少しのテストを実行することによっていくらかの漏れがあるかもしれないと思っています。 ListViewをスクロールして画面を回転すると、アクティビティが「破棄」され、再作成され、新しいCursorが照会され、ListViewが自動的に画面が回転する前の位置にスクロールされます。それは明らかに前のCursorにアクセスできますか?私はAndroidがどうやってこれをやっているのか本当にわからない。

私がmCursor.close()を呼び出した場合、 onStop()ハンドラでは、問題が発生します。画面が回転して表示されると、ユーザーはスクロール位置を失います。これは明らかに望ましくない。では私は何をしますか?スクロール位置を取得し、カーソルを閉じてから、スクロール位置をsavedInstanceStateに渡しますか?

3)ブラストされたDDMSをスタンドアロンで実行するにはどうすればよいですか?私がEclipseを開いて開くと、すでに実行中のDDMSのインスタンスが呼び出され、閉じます。 Eclipseを閉じてエミュレータを起動し、スタンドアロンのDDMSを起動すると、何も表示されません。

4)私のAndroidの経験(この投稿や他のものに基づいて)について知っていることを考えれば、他に何を探しているべきですか?私はRomain Guyによっていくつかの記事を読みましたが、私は潜在的な問題を取り除きましたが、確かに私はまだ実現していません。

+0

メモリに関する問題、特にオブジェクトの保持に関するツールを見つけるための便利なツール:Eclipse MATでアプリケーションのHPROFダンプを確認することをおすすめします(http://community.developer.motorola.com/t5/MOTODEV-Studio-for-Android-Blog/MOTODEV-Studio/ba-p/9591は、Motodevスタジオを使用すると良い説明です。 HPROFダンプを取ってMATにロードするだけです)。 –

答えて

0

なぜcallWebServiceメソッドからサービスを開始していますか?その方法で作業をしてください。あなたが本当にそれがサービスであるべきだと思うのであれば、シングルトンを捨てて、サービスにバインドしてそこのメソッドと呼ぶようにしてください。

はい、間違っています。カーソルを閉じる必要があります。 onStopで閉じて、必要ならばonStartまたはonResumeで開く必要があります。あなたは本当にできるだけ早くそれを閉じるべきです。

+0

Google I/O 2010プレゼンテーションから、サービス(サービス内のスレッド、具体的にはIntentServiceがそれを処理する)でWebサービスコールを実行するように指示されています。そのcallWebServiceメソッドは、アプリの10の異なる場所から呼び出すことができます。そのため、10行の異なる場所に同じ6行のコードを置くのではなく、一度にモジュール化されています。 – Andrew

+0

ウェブコールにサービスを使用する固有の理由は、別のスレッドにある限りです。あなたのサービスからいくつかのコードを見せてください。しかし私の賭けはあなたがカーソルを漏らしているということです。あなたのアプリは何をしていますか?なぜそれはずっと記憶に残っているのですか?あなたは24時間365日稼働したままにしていますか?あなたはそうしてはいけません。 – Falmarri

+0

IntentServicesは、コードの実行が終了すると自動的に終了します。自分のIntentServiceがIntentを処理するとき、Intent(例:ユーザーID)で渡されたデータを受け取り、Webサービスを呼び出し、返されたJSONを解析し、そのデータをアプリケーションのデータベースに書き込みます。場合によっては、私はCursorを照会しますが、IntentServiceでは、Cursorを使用し終わった時点で、常にClose()およびnullを返します。 IntentServiceは、新しいデータがブロードキャストを介して利用可能であることを再クエリする必要のあるアクティビティを通知します。アクティビティはブロードキャストを聞き、新しいCursorを照会します。 – Andrew

関連する問題