2012-09-05 11 views
5

私は、Androidオープンソースサービスの例を使用してきました。私はちょうどユーザーに通知を送信するためにそれを使用する必要がありますが、奇妙な、それは多くのメモリを割り当てます。私はランニングサービスをチェックしました。それは約20MB(私がを設定した場合)または30MB(私はACTION_BACKGROUNDを設定しています)...サービスはたくさんのメモリを割り当てますか?

私はこのメモリ使用量を減らすために何をすべきですか?

私はすでに私は、ビットマップまたはWebViewのを持っていないthis discussionを読みました。ここで

は私のサービスです:

/** 
* This is an example of implementing an application service that can 
* run in the "foreground". It shows how to code this to work well by using 
* the improved Android 2.0 APIs when available and otherwise falling back 
* to the original APIs. Yes: you can take this exact code, compile it 
* against the Android 2.0 SDK, and it will against everything down to 
* Android 1.0. 
*/ 

public class NotificationService extends Service { 

static final String ACTION_FOREGROUND = "com.example.android.apis.FOREGROUND"; 
static final String ACTION_BACKGROUND = "com.example.android.apis.BACKGROUND"; 

private static final Class<?>[] mSetForegroundSignature = new Class[] { 
    boolean.class}; 
private static final Class<?>[] mStartForegroundSignature = new Class[] { 
    int.class, Notification.class}; 
private static final Class<?>[] mStopForegroundSignature = new Class[] { 
    boolean.class}; 

// protected NotificationManager mNM; 

private Method mSetForeground; 
private Method mStartForeground; 
private Method mStopForeground; 
private Object[] mSetForegroundArgs = new Object[1]; 
private Object[] mStartForegroundArgs = new Object[2]; 
private Object[] mStopForegroundArgs = new Object[1]; 

void invokeMethod(Method method, Object[] args) { 
    try { 
     method.invoke(this, args); 
    } catch (InvocationTargetException e) { 
     // Should not happen. 
     Log.w("ApiDemos", "Unable to invoke method", e); 
    } catch (IllegalAccessException e) { 
     // Should not happen. 
     Log.w("ApiDemos", "Unable to invoke method", e); 
    } 
} 

/** 
* This is a wrapper around the new startForeground method, using the older 
* APIs if it is not available. 
*/ 
void startForegroundCompat(int id, Notification notification) { 
    // If we have the new startForeground API, then use it. 
    if (mStartForeground != null) { 
     mStartForegroundArgs[0] = Integer.valueOf(id); 
     mStartForegroundArgs[1] = notification; 
     invokeMethod(mStartForeground, mStartForegroundArgs); 
     return; 
    } 

    // Fall back on the old API. 
    mSetForegroundArgs[0] = Boolean.TRUE; 
    invokeMethod(mSetForeground, mSetForegroundArgs); 
    // mNM.notify(id, notification); 
} 

/** 
* This is a wrapper around the new stopForeground method, using the older 
* APIs if it is not available. 
*/ 
void stopForegroundCompat(int id) { 
    // If we have the new stopForeground API, then use it. 
    if (mStopForeground != null) { 
     mStopForegroundArgs[0] = Boolean.TRUE; 
     invokeMethod(mStopForeground, mStopForegroundArgs); 
     return; 
    } 

    // Fall back on the old API. Note to cancel BEFORE changing the 
    // foreground state, since we could be killed at that point. 
    // mNM.cancel(id); 
    mSetForegroundArgs[0] = Boolean.FALSE; 
    invokeMethod(mSetForeground, mSetForegroundArgs); 
} 

@Override 
public void onCreate() { 
    // mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); 
    try { 
     mStartForeground = getClass().getMethod("startForeground", 
       mStartForegroundSignature); 
     mStopForeground = getClass().getMethod("stopForeground", 
       mStopForegroundSignature); 
     return; 
    } catch (NoSuchMethodException e) { 
     // Running on an older platform. 
     mStartForeground = mStopForeground = null; 
    } 
    try { 
     mSetForeground = getClass().getMethod("setForeground", 
       mSetForegroundSignature); 
    } catch (NoSuchMethodException e) { 
     throw new IllegalStateException(
       "OS doesn't have Service.startForeground OR Service.setForeground!"); 
    } 
} 

@Override 
public void onDestroy() { 
    // Make sure our notification is gone. 
    stopForegroundCompat(1); 
} 

// This is the old onStart method that will be called on the pre-2.0 
// platform. On 2.0 or later we override onStartCommand() so this 
// method will not be called. 
@Override 
public void onStart(Intent intent, int startId) { 
    handleCommand(intent); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    handleCommand(intent); 
    // We want this service to continue running until it is explicitly 
    // stopped, so return sticky. 
    return START_STICKY; 
} 

@Override 
public void onRebind(Intent intent) { 
    super.onRebind(intent); 
    handleCommand(intent); 
} 

void handleCommand(Intent intent) { 
    if (intent == null) 
     return; 

    if (ACTION_FOREGROUND.equals(intent.getAction())) { 

     DBHelper db = new DBHelper(this); 

     String lastTime = db.getLastVisitTime(); 
     if(!lastTime.equals("-1")) { 
      new Notifications(this).InviteUser(); 
     } 

     String target = db.getTargetValue(); 
     if(target.equals("")) { 
      new Notifications(this).TargetlessNotification(); 
     } 

     db.close(); 

     /* 
     // In this sample, we'll use the same text for the ticker and the expanded notification 
     CharSequence text = getString(R.string.app_name); 
     CharSequence description = getString(R.string.recall_user); 

     // Set the icon, scrolling text and timestamp 
     Notification notification = new Notification(R.drawable.icon, text, System.currentTimeMillis()); 

     // The PendingIntent to launch our activity if the user selects this notification PendingIntent 
     contentIntent = PendingIntent.getActivity(this, 1, new Intent(this, YKEYarinaSaklaActivity.class), 0); 

     // Set the info for the views that show in the notification panel. 
     notification.setLatestEventInfo(this, text, description, contentIntent); 

     // Set properties of notification 
     notification.flags = Notification.FLAG_INSISTENT | Notification.FLAG_AUTO_CANCEL; 
     notification.defaults |= Notification.DEFAULT_ALL; 

     startForegroundCompat(1, notification); 
     */ 


    } else if (ACTION_BACKGROUND.equals(intent.getAction())) { 
     stopForegroundCompat(1); 
    } 
} 

@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 
} 

PS:それは、関連するだかどうかはわからないが、私は私のアプリのこのサービスonDestroyを始めているので、それは特定の上のユーザーへの通知をお送りしますAlarmManagerを使用して(だから、私の通知を削除AlarmManagerを避けるために殺されるべきではありません。)

+1

ダンプのhprofデータとこの素晴らしいチュートリアルの[分析](http://android-developers.blogspot.in/2011/03/memory-analysis-for-android.html) – nandeesh

+0

感謝。私はそれをチェックした、そして私が理解するように、何も間違っていない。しかし、まだそんなに割り当て:/ – yahya

+0

あなたはHPROFをダンプし、メモリを服用されているオブジェクトをチェックしてみたのですか? – nandeesh

答えて

2

使い方、そして、私は何とか実現...私は私ができるよう可能な限り自分のサービスをsimplfyしようとしましたが、状況はまだ同じですメモリがそれだけで減少する...だから、もし私にオプションがなければ、それ以外はできる。

public class NotificationService2 extends Service{ 

private String target, lastTime, notifCheck, notifCheck2; 

@Override 
public void onStart(Intent intent, int startId) { 

    Bundle extras = intent.getExtras(); 
    if(extras != null) { 
     this.lastTime = extras.getString("lastTime"); 
     this.target = extras.getString("target"); 
     this.notifCheck = extras.getString("notifCheck"); 
     this.notifCheck2 = extras.getString("notifCheck2"); 
    } 

    handleCommand(intent); 

    super.onStart(intent, startId); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    Bundle extras = intent.getExtras(); 
    if(extras != null) { 
     this.lastTime = extras.getString("lastTime"); 
     this.target = extras.getString("target"); 
     this.notifCheck = extras.getString("notifCheck"); 
     this.notifCheck2 = extras.getString("notifCheck2"); 
    } 

    handleCommand(intent); 

    // We want this service to continue running until it is explicitly 
    // stopped, so return sticky. 
    return START_STICKY; 
} 

@Override 
public IBinder onBind(Intent intent) { 
    handleCommand(intent); 
    return null; 
} 

@Override 
public void onRebind(Intent intent) { 
    super.onRebind(intent); 
    handleCommand(intent); 
} 

void handleCommand(Intent intent) { 
    if (intent == null) 
     return; 

    String lastTime = this.lastTime; 
    String notifCheck = this.notifCheck; 
    String target = this.target; 
    String notifCheck2 = this.notifCheck2; 

    if(lastTime != null && notifCheck != null) { 
     if(!lastTime.equals("-1") && !notifCheck.equals("1")) 
      new Notifications(this).InviteUser(); 
    } else this.stopSelf(); 

    if(target != null && notifCheck2 != null) { 
     if(target.equals("") && !notifCheck2.equals("1")) 
      new Notifications(this).TargetlessNotification(); 
    } else this.stopSelf(); 

} 

}