Service verbraucht viel Systemleistung

  • Antworten:6
Daniel online
  • Forum-Beiträge: 282

14.06.2011, 13:55:52 via Website

Hallo,

ich hab ein kleines Problem mit meinem Service. Er verbraucht mehr speicher als herkömmliche Apps wie Facebook oder so obwohl er eigentlich fast nichts macht.

In dem Service laufen CountdownTimer für meine App. Manchmal, selbst nachdem kein Timer mehr läuft, verbaucht er ca. 22mb. Es kommt mir so vor als würde deswegen mein Handy(HTC Wildfire) manchmal ruckeln.
Den Service kann man atm nur über einen Button in der App beenden, das er sich automatisch beendet wenn kein Timer mehr läuft mache ich jetzt gleich.
Trotzdem sollte er eigentlich nicht so viel Speicher benötigen, vielleicht könnt ihr mir ja ein paar Tipps geben.


1home;
2
3
4// Service laufen länger als die Anwendung und müssen daher explizit geschlossen werden
5import android.app.AlarmManager;
6import android.app.AlertDialog;
7import android.app.AlertDialog.Builder;
8import android.app.NotificationManager;
9import android.app.PendingIntent;
10import android.app.Service;
11import android.content.BroadcastReceiver;
12import android.content.ComponentName;
13import android.content.Context;
14import android.content.DialogInterface;
15import android.content.Intent;
16import android.content.IntentFilter;
17import android.content.ServiceConnection;
18import android.os.Binder;
19import android.os.Bundle;
20import android.os.CountDownTimer;
21import android.os.IBinder;
22import android.util.Log;
23import android.widget.TextView;
24
25public class miniService extends Service
26{
27
28
29
30 private miniServiceBinder mBinder = new miniServiceBinder();
31 private static String TAG = miniService.class.getSimpleName();
32 public static String ACTION_BROADCAST = "de.Daniel.home.intent.action.GIVETIME";
33 public static String WIDGET_BROADCAST = "com.android.myapp.widget.CLICK";
34
35 public int started;//Variable 1=ja, 0 nein
36 public int timer_finished = 0;
37 public String timer_finished_name;
38
39 public String sendTimer1;
40 public String sendTimer2;
41 public String sendTimer3;
42 public String sendTimer4;
43 public String sendTimer5;
44 public String sendTimer6;
45
46 public Intent giveTime1;
47 public Intent giveTime2;
48 public Intent giveTime3;
49 public Intent giveTime4;
50 public Intent giveTime5;
51 public Intent giveTime6;
52
53
54 public CountDownTimer count1;
55 public CountDownTimer count2;
56 public CountDownTimer count3;
57 public CountDownTimer count4;
58 public CountDownTimer count5;
59 public CountDownTimer count6;
60
61
62 public class miniServiceBinder extends Binder
63 {
64
65 }
66 @Override
67 public IBinder onBind(Intent intent)
68 {
69
70 return mBinder;
71 }
72
73
74 BroadcastReceiver serviceReceiver = new BroadcastReceiver() {
75
76 @Override
77 public void onReceive(Context context, Intent intent) {
78 sendTimer1 = "yes";
79 sendTimer2 = "yes";
80 sendTimer3 = "yes";
81 sendTimer4 = "yes";
82 sendTimer5 = "yes";
83 sendTimer6 = "yes";
84
85
86 }
87 };
88
89
90 public void onCreate()
91 {
92 Log.d(TAG, "onCreate");
93
94 getApplicationContext().registerReceiver(serviceReceiver, new IntentFilter(kitchen_main.ACTION_GETTIMER));
95 }
96
97 public int onStartCommand(Intent intent, int flag, int startId) // onStartCommand nur für Geräte mit Android 2.0 oder höher
98 {
99 Bundle extra = intent.getExtras();
100 if(extra!=null)
101 {
102 int id = extra.getInt("id"); // Id des Buttons
103 int hour = extra.getInt("hour");
104 int min = extra.getInt("min");
105 int seconds = extra.getInt("seconds");
106 String name = extra.getString("name");
107 if(extra.getInt("started")==1) started=1;
108 setCountDownTimer(id,name,started,hour,min,seconds); // hier wird der Coutdown gestartet
109 Log.d(TAG,"id:"+id+". Name "+ name);
110
111 //den Intent als Broadcast an das Widget weiterleiten
112 Intent widgetIntent = new Intent(getApplicationContext(), widget1.class);
113 widgetIntent.setAction("com.android.myapp.widget.CLICK");
114 int time_total = 1000*((hour*60*60)+(min*60)+seconds);
115 widgetIntent.putExtra("time",time_total);
116 widgetIntent.putExtra("name", name);
117 getApplicationContext().sendBroadcast(widgetIntent);
118
119
120
121 switch(id) // Sobald der Timer gestartet wird, wird ein Intent mit ihm verknüpft.
122 {
123 case R.id.main_llayout1:
124 giveTime1 = new Intent(ACTION_BROADCAST); // ACTION name ändern?
125 giveTime1.putExtra("name", name);
126 giveTime1.putExtra("id", id);
127 break;
128 case R.id.main_llayout2:
129 giveTime2 = new Intent(ACTION_BROADCAST);
130 giveTime2.putExtra("name", name);
131 giveTime2.putExtra("id", id);
132 break;
133 case R.id.main_llayout3:
134 giveTime3 = new Intent(ACTION_BROADCAST);
135 giveTime3.putExtra("name", name);
136 giveTime3.putExtra("id", id);
137 break;
138 case R.id.main_llayout4:
139 giveTime4 = new Intent(ACTION_BROADCAST);
140 giveTime4.putExtra("name", name);
141 giveTime4.putExtra("id", id);
142 break;
143 case R.id.main_llayout5:
144 giveTime5 = new Intent(ACTION_BROADCAST);
145 giveTime5.putExtra("name", name);
146 giveTime5.putExtra("id", id);
147 break;
148 case R.id.main_llayout6:
149 giveTime6 = new Intent(ACTION_BROADCAST);
150 giveTime6.putExtra("name", name);
151 giveTime6.putExtra("id", id);
152 break;
153
154 }
155
156 }
157
158 Log.d(TAG, "onStart");
159 return START_NOT_STICKY;//START_STICKY; // wird erst geschlossen wenn dazu aufgerufen.
160 }
161 @Override
162 public void onDestroy()
163 {
164 Log.d(TAG, "on Destroy");
165 if(count1 != null) count1.cancel();
166 if(count2 != null) count2.cancel();
167 if(count3 != null) count3.cancel();
168 if(count4 != null) count4.cancel();
169 if(count5 != null) count5.cancel();
170 if(count6 != null) count6.cancel();
171 getApplicationContext().unregisterReceiver(serviceReceiver);
172
173 }
174
175
176
177 public void setCountDownTimer(final int id, final String name,final int start, final int hour, final int min, final int seconds)
178 {
179 int time_total = 1000*((hour*60*60)+(min*60)+seconds);
180
181
182 switch(id)
183 {
184 case R.id.main_llayout1:
185 //Timer stoppen wenn er vorher schon lief
186 if(start==1){count1.cancel(); started=0;}
187 count1 = new CountDownTimer(time_total, 1000)
188 {
189
190 @Override
191 public void onTick(long millisUntilFinished) {
192 if(sendTimer1=="yes")
193 {
194 sendTimer1="no";
195 Log.d(TAG, "id1, intent gesendet");
196 giveTime1.putExtra("timeLeft",(int) millisUntilFinished);
197 getApplicationContext().sendBroadcast(giveTime1);
198
199 }
200
201
202 }
203
204 @Override
205 public void onFinish()
206 {
207 Log.d(TAG,"alert1");
208 Intent alert = new Intent(getApplicationContext(), showAlertDialog.class);
209 alert.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
210 alert.putExtra("name", giveTime1.getExtras().getString("name"));
211 getApplicationContext().startActivity(alert);
212
213
214
215 }
216
217
218 }.start();
219 break;
220 case R.id.main_llayout2:
221 if(start==1){count2.cancel();started=0;}
222 count2 = new CountDownTimer(time_total, 1000)
223 {
224
225 @Override
226 public void onTick(long millisUntilFinished) {
227 if(sendTimer2=="yes")
228 {
229 sendTimer2="no";
230 Log.d(TAG, "id2, intent gesendet");
231 giveTime2.putExtra("timeLeft",(int) millisUntilFinished);
232 getApplicationContext().sendBroadcast(giveTime2);
233
234 }
235
236 }
237
238 @Override
239 public void onFinish() {
240 Intent alert = new Intent(getApplicationContext(), showAlertDialog.class);
241 alert.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
242 alert.putExtra("name", giveTime2.getExtras().getString("name"));
243 getApplicationContext().startActivity(alert);
244
245 }
246
247 }.start();
248 break;
249 case R.id.main_llayout3:
250 if(start==1){count3.cancel();started=0;}
251 count3 = new CountDownTimer(time_total, 1000)
252 {
253
254 @Override
255 public void onTick(long millisUntilFinished) {
256 if(sendTimer3=="yes")
257 {
258 giveTime3.putExtra("timeLeft",(int) millisUntilFinished);
259 sendTimer3="no";
260 Log.d(TAG, "id3, intent gesendet");
261 getApplicationContext().sendBroadcast(giveTime3);
262 }
263
264
265 }
266
267 @Override
268 public void onFinish() {
269 Intent alert = new Intent(getApplicationContext(), showAlertDialog.class);
270 alert.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
271 alert.putExtra("name", giveTime3.getExtras().getString("name"));
272 getApplicationContext().startActivity(alert);
273
274 }
275
276 }.start();
277 break;
278 case R.id.main_llayout4:
279 if(start==1){count4.cancel();started=0;}
280 count4 = new CountDownTimer(time_total, 1000)
281 {
282
283 @Override
284 public void onTick(long millisUntilFinished) {
285 if(sendTimer4=="yes")
286 {
287 giveTime4.putExtra("timeLeft",(int) millisUntilFinished);
288 sendTimer4="no";
289 Log.d(TAG, "id4, intent gesendet");
290 getApplicationContext().sendBroadcast(giveTime4);
291 }
292
293 }
294
295 @Override
296 public void onFinish() {
297 Intent alert = new Intent(getApplicationContext(), showAlertDialog.class);
298 alert.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
299 alert.putExtra("name", giveTime4.getExtras().getString("name"));
300 getApplicationContext().startActivity(alert);
301
302 }
303
304 }.start();
305 break;
306 case R.id.main_llayout5:
307 if(start==1){count5.cancel();started=0;}
308 count5 = new CountDownTimer(time_total, 1000)
309 {
310
311 @Override
312 public void onTick(long millisUntilFinished)
313 {
314 if(sendTimer5=="yes")
315 {
316 giveTime5.putExtra("timeLeft",(int) millisUntilFinished);
317 sendTimer5="no";
318 Log.d(TAG, "id5, intent gesendet");
319 getApplicationContext().sendBroadcast(giveTime5);
320 }
321
322 }
323
324 @Override
325 public void onFinish() {
326 Intent alert = new Intent(getApplicationContext(), showAlertDialog.class);
327 alert.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
328 alert.putExtra("name", giveTime5.getExtras().getString("name"));
329 getApplicationContext().startActivity(alert);
330
331 }
332
333 }.start();
334 break;
335 case R.id.main_llayout6:
336 if(start==1){count6.cancel();started=0;}
337 count6 = new CountDownTimer(time_total, 1000)
338 {
339
340 @Override
341 public void onTick(long millisUntilFinished) {
342 if(sendTimer6=="yes")
343 {
344 giveTime6.putExtra("timeLeft",(int) millisUntilFinished);
345 sendTimer6="no";
346 Log.d(TAG, "id6, intent gesendet");
347 getApplicationContext().sendBroadcast(giveTime6);
348 }
349
350 }
351
352 @Override
353 public void onFinish() {
354 Intent alert = new Intent(getApplicationContext(), showAlertDialog.class);
355 alert.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
356 alert.putExtra("name", giveTime6.getExtras().getString("name"));
357 getApplicationContext().startActivity(alert);
358
359 }
360
361 }.start();
362 break;
363 }
364
365
366 }
367
368
369
370}

Danke jedem für die Mühe :)

Antworten
Daniel online
  • Forum-Beiträge: 282

14.06.2011, 14:11:57 via Website

Nachtrag:
Ich habe nun eine Funktion eingebaut wobei geschaut wird ob alle Timer abgelaufen sind und dann der Service beendet wird. onDestroy() wird aufgerufen(sehe ich im Log). Selbst wenn ich die Funktion dann per Exit verlasse bleibt sie nach wie vor "da" und belegt Speicher. Das sehe ich über eine andere App.
Ist das normal? Ich will ja keinen Energiefresser sondern nen Wecker programmieren ;)

Antworten
Ansgar M
  • Forum-Beiträge: 1.544

14.06.2011, 15:17:44 via App

Wieso einen Timer für einen Wecker?
Der AlarmManager ist dafür viel besser geeignet denke ich!
Lg Ansgar

Antworten
Daniel online
  • Forum-Beiträge: 282

14.06.2011, 15:41:27 via Website

Der Timer wird in der App dargestellt wie er runterzählt, das funktioniert soweit ich weiß am besten mit nem CountdownTimer.

Antworten
Ansgar M
  • Forum-Beiträge: 1.544

14.06.2011, 15:48:14 via App

Ja,
schon klar. Aber muss der dann auch im Service die ganze Zeit mitlaufen? Reicht es nicht, wenn man die Activity startet, das man dann die Restzeit berechnet und einen neuen Countdown startet?
Lg Ansgar

Luigi

Antworten
Johannes Borchardt
  • Forum-Beiträge: 114

16.06.2011, 11:05:03 via Website

Hi,

tut mir leid, ein kurzer Off-Topic Einwurf:
Objekte, also zum Beispiel Strings, sollten in Java immer mit equals() und nicht mit == verglichen werden. Mit == wird lediglich die Position im Speicher überprüft. Das heißt, wenn z.B. ein Stringobjekt A = "abc" gespeichert wurde und Stringobjekt B = "abc" ebenfalls existiert, kann es sein, dass die virtuelle Maschine aus Optimierungsgründen den String an der selben Stelle speichert. In diesem Fall ergibt == true. Tut sie dies aus irgendeinem Grund nicht, wird der Abgleich mit == false ergeben.
Darum: Bei Objekten immer equals verwenden (also z.B. A.equals(B)).
Nur so am Rande ;-)

VG
Johannes

Antworten
Daniel online
  • Forum-Beiträge: 282

17.06.2011, 15:01:06 via Website

Danke für den Hinweis ich habe versucht es auszubessern dort wo ich was gefunden habe.
Ich habe das Problem jetzt so gelöst das der Service sich selbst beendet sobald kein Timer mehr läuft.

Antworten