2012-09-05 41 views
5

Tôi đã sử dụng ví dụ về dịch vụ nguồn mở Android. Tôi chỉ cần sử dụng nó để gửi thông báo cho người dùng, nhưng lạ, nó phân bổ rất nhiều bộ nhớ. Tôi đã kiểm tra Dịch vụ đang chạy và gần 20MB (nếu tôi đặt ACTION_BACKGROUND) hoặc 30MB (nếu tôi đặt ACTION_FOREGROUND) ...Dịch vụ phân bổ nhiều bộ nhớ?

Tôi nên làm gì để giảm mức sử dụng bộ nhớ này?

Tôi đã đọc this discussion Tôi không có bitmap hoặc webview.

Dưới đây là dịch vụ của tôi:

/** 
* 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: Tôi không biết nếu nó có liên quan hay không nhưng tôi đang bắt đầu này onDestroy dịch vụ của ứng dụng của tôi, vì vậy nó sẽ gửi thông báo cho người dùng trên một cụ thể thời gian với AlarmManager. (Vì vậy, nó không nên bị giết để tránh AlarmManager xóa thông báo của tôi.)

+1

bãi chứa dữ liệu hprof và [phân tích] (http://android-developers.blogspot.in/2011/03/memory-analysis-for-android.html) – nandeesh

+0

Cám ơn hướng dẫn tuyệt vời này. Tôi đã kiểm tra nó, và như tôi hiểu không có gì sai. Nhưng vẫn phân bổ rất nhiều:/ – yahya

+0

bạn đã cố gắng để đổ hprof và kiểm tra những đối tượng đang dùng bộ nhớ? – nandeesh

Trả lời

2

Tôi đã cố gắng đơn giản hóa dịch vụ của mình càng tốt, nhưng tình hình vẫn như cũ ... Sau đó tôi nhận ra rằng bằng cách nào đó, sử dụng của bộ nhớ giảm của chính nó ... Vì vậy, nếu tôi không có tùy chọn, tôi có thể ngoại trừ điều đó.

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

} 

} 
Các vấn đề liên quan