Sto usando un esempio di servizio open source Android. Ho solo bisogno di usarlo per inviare notifiche all'utente, ma strano, alloca molta memoria. Ho controllato in Running Services, ed è quasi 20MB (se ho impostato ACTION_BACKGROUND
) o 30MB (se ho impostato ACTION_FOREGROUND
) ...Il servizio alloca molta memoria?
Cosa devo fare per ridurre questo utilizzo della memoria?
Ho già letto this discussion Non ho bitmap o webview.
Ecco il mio servizio:
/**
* 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: Non so se è rilevante o no, ma sto iniziando questo servizio OnDestroy di mia app, in modo che lo trasmetteranno notifica utente su un determinato tempo con AlarmManager. (Quindi non dovrebbe essere ucciso per evitare AlarmManager cancellando la mia notifica.)
dati discarica hprof e [Analizza] (http://android-developers.blogspot.in/2011/03/memory-analysis-for-android.html) – nandeesh
Grazie per questo tutorial impressionante. L'ho controllato e, come ho capito, non c'è niente di sbagliato. Ma ancora assegna così tanto:/ – yahya
hai provato a scaricare hprof e verificare quali oggetti stanno prendendo memoria? – nandeesh