ANR Problem

  • Antworten:2
Kullorki
  • Forum-Beiträge: 55

18.02.2013, 18:09:30 via Website

Hallo,
Also ich bastel in meiner freizeit gerne an einem Spiel herum, und habe eigentlich mehr oder weniger seit anfang an mit einem problem zu kämpfen.
Das Problem lässt sich wie folgt beschreiben :
Meistens wenn eine Activity startet kommt es manchmal (aber nicht immer!) vor dass Android ANR´s schmeißt.
Wenn diese geschmissen werden dann dauert es manchmal bis zu 5 minuten ehe es weiter geht.
Dabei ist zu bemerken das sobald die activity gestartet ist werden ANR´s nie geschmissen werden.

Edit:

Also das heißt z.b.:
app wird gestartet(intro)
durch touch wird das menü gestartet
durch spielstandauswahl wird das Spiel gestartet
im spiel wird durch die back taste und auswahl von Ja das menü gestartet
Das menü wird gezeichnet, reagiert aber auf keine Touch inputs -> ANR

Das Blöde daran ist es ist nie an der selben stelle auftritt.
Mein Spiel ist bisher so aufgebaut (Canvas): -> intro <-> Hauptmenü <-> Game
Man kann von der jeweiligen activity halt in die andere wechseln.

Hat da jemand gut erfahrungen mit wie man dem problem jetzt am besten auf die schliche kommt?
Ich hab jetzt method profiling schon ausprobiert, allerdings nicht wirklich nützliches da rauslesen können.
Gibt es eine bestimmte stelle in der traces.txt die einem Weiterhilft?

Ich kann dort aus der kilometer langen Datei zumindest nichts herrauslesen, da dort nur Android native Klassen aufgeführt sind :/

Alles was ich bisher rausfinden konnte ist, dass die Warscheinlichkeit das ein ANR aufkommt steigt, nachdem ich eine andere Activity starte, die schonmal gestartet worden ist.
Das Mache ich im Game z.b. so um ins Hauptmenü zu kommen:
1@Override
2 public boolean onKeyDown(int keyCode, KeyEvent event) {
3 if ((keyCode == KeyEvent.KEYCODE_BACK)) {
4 AlertDialog.Builder builder = new AlertDialog.Builder(Activity_Game.this);
5 builder.setTitle("Beenden");
6 builder.setMessage("Möchten Sie das Spiel wirklich beenden und zum Hauptmenü zurückkehren?\n Nicht gesicherter Fortschritt geht verloren!");
7
8 builder.setPositiveButton("Ja", new DialogInterface.OnClickListener() {
9 public void onClick(DialogInterface dialog, int id) {
10 Intent itemintent = new Intent(Activity_Game.this,Activity_menu.class);
11 itemintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
12 startActivity(itemintent);
13 Activity_Game.this.finish();
14 }
15 });
16 builder.setNegativeButton("Nein", new DialogInterface.OnClickListener() {
17 public void onClick(DialogInterface dialog, int id) {
18 }
19 });
20
21 AlertDialog alertDialog = builder.create();
22 alertDialog.show();
23 return true;
24
25 }else{
26...
27}
28}

Hat jemand Ideen oder Vorschläge?

edit(Log ganz vergessen sorry ^^ ) :
102-18 18:54:34.327: I/InputDispatcher(1013): Application is not responding: Window{b59781a0 de.kullorki.projekt/de.kullorki.projekt.Activity_menu paused=false}. It has been 5006.3ms since event, 5006.1ms since wait started. Reason: Waiting because the touched window has not finished processing the input events that were previously delivered to it.
202-18 18:54:34.327: I/WindowManager(1013): Input event dispatching timed out sending to de.kullorki.projekt/de.kullorki.projekt.Activity_menu
302-18 18:54:34.327: I/Process(1013): Sending signal. PID: 1599 SIG: 3
402-18 18:54:34.327: I/dalvikvm(1599): threadid=3: reacting to signal 3
502-18 18:54:34.337: I/dalvikvm(1599): Wrote stack traces to '/data/anr/traces.txt'
602-18 18:54:34.337: I/Process(1013): Sending signal. PID: 1013 SIG: 3
702-18 18:54:34.337: I/dalvikvm(1013): threadid=3: reacting to signal 3
802-18 18:54:34.967: I/dalvikvm(1013): Wrote stack traces to '/data/anr/traces.txt'
902-18 18:54:34.967: I/Process(1013): Sending signal. PID: 1075 SIG: 3
1002-18 18:54:34.967: I/dalvikvm(1075): threadid=3: reacting to signal 3
1102-18 18:54:35.037: I/dalvikvm(1075): Wrote stack traces to '/data/anr/traces.txt'
1202-18 18:54:35.037: I/Process(1013): Sending signal. PID: 1139 SIG: 3
1302-18 18:54:35.037: I/dalvikvm(1139): threadid=3: reacting to signal 3
1402-18 18:54:35.197: I/dalvikvm(1139): Wrote stack traces to '/data/anr/traces.txt'
1502-18 18:54:35.227: D/dalvikvm(1013): GC_CONCURRENT freed 539K, 58% free 11365K/26503K, paused 14ms+1ms, total 19ms
1602-18 18:54:35.247: D/dalvikvm(1013): WAIT_FOR_CONCURRENT_GC blocked 0ms
1702-18 18:54:35.258: D/dalvikvm(1013): GC_EXPLICIT freed 230K, 57% free 11421K/26503K, paused 0ms+1ms, total 7ms
1802-18 18:54:35.767: E/ActivityManager(1013): ANR in de.kullorki.projekt (de.kullorki.projekt/.Activity_menu)
1902-18 18:54:35.767: E/ActivityManager(1013): Reason: keyDispatchingTimedOut
2002-18 18:54:35.767: E/ActivityManager(1013): Load: 0.4 / 0.13 / 0.04
2102-18 18:54:35.767: E/ActivityManager(1013): CPU usage from 9305ms to 0ms ago:
2202-18 18:54:35.767: E/ActivityManager(1013): 6.3% 800/surfaceflinger: 4.4% user + 1.9% kernel / faults: 564 minor
2302-18 18:54:35.767: E/ActivityManager(1013): 0% 811/adbd: 0% user + 0% kernel / faults: 78 minor
2402-18 18:54:35.767: E/ActivityManager(1013): 6.4% TOTAL: 4.4% user + 1.9% kernel + 0.1% softirq
2502-18 18:54:35.767: E/ActivityManager(1013): CPU usage from 927ms to 1435ms later:
2602-18 18:54:35.767: E/ActivityManager(1013): 3.5% 800/surfaceflinger: 3.5% user + 0% kernel
2702-18 18:54:35.767: E/ActivityManager(1013): 3.5% 878/SurfaceFlinger: 3.5% user + 0% kernel
2802-18 18:54:35.767: E/ActivityManager(1013): 3.9% TOTAL: 3.9% user + 0% kernel
2902-18 18:54:35.787: D/dalvikvm(1013): GC_CONCURRENT freed 152K, 55% free 12069K/26503K, paused 16ms+1ms, total 21ms
mfg

— geändert am 18.02.2013, 20:04:12

Antworten
Andreas Weichert
  • Forum-Beiträge: 287

19.02.2013, 10:04:17 via Website

Ich vermute stark, das dein Problem mit dem Activity-Livecycle zu tun hat.
Der Absturzt tritt wahrscheinlich genau dann auf, wenn eine Activity automatisch von Android zerstört wurde und Du die sie wieder öffnest.
Versuche doch mal deine App zu starten, zu einer Activity gehen, die oft abstrürzt.
Dann Hometaste und 2-3 andere Apps starten (Playstore ist gut für).
Dann über den Taskmanager (Home lang drücken) deine App wieder öffenen.
Sie sollte dann abstürzen.

Kullorki

Antworten
Kullorki
  • Forum-Beiträge: 55

19.02.2013, 11:40:33 via Website

Andreas Weichert

Sie sollte dann abstürzen.
Ja, sie hängt dann (OnDraw wird aber anstandslos ausgeführt).
Ich habe das ganze jetzt auf dem Android Emulator probiert, und da hängt es anscheinend immer bei jeder Activity. (Die Intro activity funktioniert nur wenn ich die app gerade installiert habe. wenn Die App dann geschlossen wird wegen ANR, und ich sie dann wieder starte hängt Intro wie wenn ich sie vom Menu aus starten würde...)
Ich hab mir das mit dem Lifecycle nochmal angeguckt, aber
verstehe einfach nicht was ich falsch mache :(

Hier mal zum beispiel die intro activity (unwichtiger code weggelassen)
1public class Activity_intro extends Activity {
2
3/*variablen .... */
4 int Screenwidth, Screenheight
5boolean back= false;
6Panel zPanel;
7
8 public void onCreate(Bundle savedInstanceState) {
9 super.onCreate(savedInstanceState);
10 requestWindowFeature(Window.FEATURE_NO_TITLE);
11 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
12 Display display = getWindowManager().getDefaultDisplay();
13 Screenwidth = display.getWidth();
14 Screenheight = display.getHeight();
15 zPanel = new Panel(this);
16 setContentView( zPanel);
17 Log.d("Intro", "OnCreate");
18 }
19
20 @Override
21 protected void onResume() {
22 super.onResume();
23 Log.d("Intro", "OnResume");
24 }
25
26 @Override
27 protected void onPause() {
28 super.onPause();
29 Log.d("Intro", "OnPause");
30 }
31
32 protected void onDestroy(){
33 super.onDestroy();
34 Log.d("Intro", "OnDestroy");
35 }
36
37 protected void onStop(){
38 super.onDestroy();
39 Log.d("Intro", "OnStop");
40 }
41
42 @Override
43 public boolean onKeyDown(int keyCode, KeyEvent event) {
44 if ((keyCode == KeyEvent.KEYCODE_BACK)) {
45 AlertDialog.Builder builder = new AlertDialog.Builder(Activity_intro.this);
46 builder.setTitle("Beenden");
47 builder.setMessage("Möchten Sie das Spiel wirklich beenden ?\n");
48 builder.setPositiveButton("Ja", new DialogInterface.OnClickListener() {
49 public void onClick(DialogInterface dialog, int id) {
50 back = true;
51 Activity_intro.this.finish();
52 System.exit(0);
53 }
54 });
55 builder.setNegativeButton("Nein", new DialogInterface.OnClickListener() {
56 public void onClick(DialogInterface dialog, int id) {
57 }
58 });
59
60 AlertDialog alertDialog = builder.create();
61 alertDialog.show();
62 return true;
63 }
64 return false;
65 }
66
67class Panel extends SurfaceView implements SurfaceHolder.Callback {
68 private TutorialThread _thread;
69
70 .... variablen für onDraw und so weiter ausgelassen....
71
72 public Panel(Context context) {
73 super(context);
74 Log.d("Intro", "SurfaceView Konstruktor");
75 getHolder().addCallback(this);
76 setFocusable(true);
77 loadBitmaps();
78 }
79
80 @Override
81 public void onDraw(Canvas canvas) {
82 /* draw ...*/
83 }
84
85 public boolean onTouchEvent(MotionEvent event) {
86 if(event.getAction() == MotionEvent.ACTION_DOWN){
87 _thread.setRunning(false);
88 return true;
89 }
90 return false;
91 }
92
93 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
94 Log.d("Intro", "SurfaceView Changed");
95 }
96
97 public void surfaceCreated(SurfaceHolder holder) {
98 _thread = new TutorialThread(getHolder(), this);
99 _thread.setRunning(true);
100 _thread.start();
101 Log.d("Intro", "SurfaceView Created");
102 }
103
104 public void surfaceDestroyed(SurfaceHolder holder) {
105 boolean retry = true;
106 _thread.setRunning(false);
107 while (retry) {
108 try {
109 _thread.join();
110 retry = false;
111 } catch (InterruptedException e) {
112 }
113 }
114 Log.d("Intro", "SurfaceView Destroyed");
115 }
116
117
118class TutorialThread extends Thread {
119 private SurfaceHolder _surfaceHolder;
120 private Panel _panel;
121 private boolean _run = false;
122
123 public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
124 _surfaceHolder = surfaceHolder;
125 _panel = panel;
126 }
127
128 public void setRunning(boolean run) {
129 _run = run;
130 }
131
132 @Override
133 public void run() {
134 Canvas c;
135 while (_run) {
136 c = null;
137 try {
138 c = _surfaceHolder.lockCanvas(null);
139 synchronized (_surfaceHolder) {
140 _panel.onDraw(c);
141 }
142 } finally {
143 if (c != null) {
144 _surfaceHolder.unlockCanvasAndPost(c);
145 }
146 }
147 }
148 if(!back){
149 Intent itemintent = new Intent(Activity_intro.this,Activity_menu.class);
150 itemintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
151 startActivity(itemintent);
152 Activity_intro.this.finish();
153 }
154 }
155}
156}
157
158}

— geändert am 19.02.2013, 11:48:32

Antworten