服务分配大量内存?

时间:2012-09-05 06:47:05

标签: android memory memory-management service notifications

我一直在使用Android开源服务示例。我只需要使用它向用户发送通知,但很奇怪,它会分配大量内存。我检查了运行服务,它几乎是20MB(如果我设置ACTION_BACKGROUND)或30MB(如果我设置ACTION_FOREGROUND)...

我该怎么做才能减少内存使用量?

我已阅读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;
}
}

P.S。:我不知道它是否相关,但我正在启动我的应用程序的onDestroy服务,所以它会在特定时间用AlarmManager向用户发送通知。 (因此不应该杀死它以避免AlarmManager删除我的通知。)

1 个答案:

答案 0 :(得分:2)

我试图尽可能简化我的服务,但情况仍然相同......然后我意识到,某种程度上,内存的使用会自行减少......所以,如果我没有选择,我可以除外。

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

}

}