Question

In my Android application I am getting a very strange crash, when I press a button (Image) on my UI the entire application freezes and after a couple of seconds I getthe dreaded force close dialog appearing.

Here is what gets printed in the log:


WARN/WindowManager(88): Key dispatching timed out sending to package name/Activity
WARN/WindowManager(88): Dispatch state: {{KeyEvent{action=1 code=5 repeat=0 meta=0 scancode=231 mFlags=8} to Window{432bafa0 com.android.launcher/com.android.launcher.Launcher paused=false} @ 1281611789339 lw=Window{432bafa0 com.android.launcher/com.android.launcher.Launcher paused=false} lb=android.os.BinderProxy@431ee8e8 fin=false gfw=true ed=true tts=0 wf=false fp=false mcf=Window{4335fc58 package name/Activity paused=false}}}
WARN/WindowManager(88): Current state:  {{null to Window{4335fc58 package name/Activity paused=false} @ 1281611821193 lw=Window{4335fc58 package name/Activity paused=false} lb=android.os.BinderProxy@434c9bd0 fin=false gfw=true ed=true tts=0 wf=false fp=false mcf=Window{4335fc58 package name/Activity paused=false}}}
INFO/ActivityManager(88): ANR in process: package name (last in package name)
INFO/ActivityManager(88): Annotation: keyDispatchingTimedOut
INFO/ActivityManager(88): CPU usage:
INFO/ActivityManager(88): Load: 5.18 / 5.1 / 4.75
INFO/ActivityManager(88): CPU usage from 7373ms to 1195ms ago:
INFO/ActivityManager(88):   package name: 6% = 1% user + 5% kernel / faults: 7 minor
INFO/ActivityManager(88):   system_server: 5% = 4% user + 1% kernel / faults: 27 minor
INFO/ActivityManager(88):   tiwlan_wifi_wq: 3% = 0% user + 3% kernel
INFO/ActivityManager(88):   mediaserver: 0% = 0% user + 0% kernel
INFO/ActivityManager(88):   logcat: 0% = 0% user + 0% kernel
INFO/ActivityManager(88): TOTAL: 12% = 5% user + 6% kernel + 0% softirq
INFO/ActivityManager(88): Removing old ANR trace file from /data/anr/traces.txt
INFO/Process(88): Sending signal. PID: 1812 SIG: 3
INFO/dalvikvm(1812): threadid=7: reacting to signal 3
INFO/dalvikvm(1812): Wrote stack trace to '/data/anr/traces.txt'

This is the code for the Button (Image):


findViewById(R.id.endcallimage).setOnClickListener(new OnClickListener() {
                    public void onClick(View v) {
                        mNotificationManager.cancel(2);

                        Log.d("Handler", "Endcallimage pressed");

                        if(callConnected)
                        elapsedTimeBeforePause = SystemClock.elapsedRealtime() - stopWatch.getBase();

                        try {
                            serviceBinder.endCall(lineId);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        } 
                            dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD));
                            dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));
                    }
            });     

If I comment the following out the pressing of the button (image) doesn't cause the crash:


try {
      serviceBinder.endCall(lineId);
    } catch (RemoteException e) {
      e.printStackTrace();
    } 

The above code calls down through several levels of the app and into the native layer (NDK), could the call passing through several objects be leading to the force close? It seems unlikely as several other buttons do the same without issue.

How about the native layer? Could some code I've built with the NDK be causing the issue?

Any other ideas as to what the cause of the issue might be?

Was it helpful?

Solution

You must be as fast as possible in your onClick implementation. Expensive operations should be, in general, offloaded to a background thread.

In onClick, try:

Thread t = new Thread(){
    public void run(){
        your_stuff();
    }
};
t.start();

instead of just

your_stuff()

OTHER TIPS

You can encounter this error when you block the main thread (a.k.a. the UI thread) for a few seconds. Expensive operations should be, in general, offloaded to a background thread. AsyncTask is very helpful in these cases.

In your case you could do the following:

new AsyncTask<Void, Void, Void>() {
    @Override
    protected Void doInBackground(Void... params) {
        try {
            serviceBinder.endCall(lineId);
        } catch (RemoteException e) {
            e.printStackTrace();
        } 
    }
}.execute();

Do your long Operation in a seperate thread or use AsyncTask to get rid of ANR.

An ANR(Activity Not Responding) happens when some long operation takes place in the "main" thread. This is the event loop thread, and if it is busy, Android cannot process any further GUI events in the application, and thus throws up an ANR dialog.

Your activity took to long to say to the Android OS 'hey i'm still alive'! (This is what the UI thread does).

http://developer.android.com/guide/practices/design/responsiveness.html

Basically if you make the UI thread do some complex task it's too busy doing your task to tell the OS that it is still 'alive'.

http://android-developers.blogspot.co.uk/2009/05/painless-threading.html

You should move your XML Parsing code to another thread, then use a callback to tell the UI thread you have finished and to do something with the result.

http://developer.android.com/resources/articles/timed-ui-updates.html

Detecting where ANRs happen is easy if it is a permanent block (deadlock acquiring some locks for instance), but harder if it's just a temporary delay. First, go over your code and look for vunerable spots and long running operations. Examples may include using sockets, locks, thread sleeps, and other blocking operations from within the event thread. You should make sure these all happen in separate threads. If nothing seems the problem, use DDMS and enable the thread view. This shows all the threads in your application similar to the trace you have. Reproduce the ANR, and refresh the main thread at the same time. That should show you precisely whats going on at the time of the ANR

If Logcat doesn't output anything usefull, try to pull traces.txt from /data/anr/traces.txt

adb pull /data/anr/traces.txt .

as it may give more information on where the ANR Exception occurrred

And this link may also helpful for creating AsyncTask and Threads

If you are doing a resource intensive task then it might happen. While resuming the Activity. 1. Try stopping all your intensive work on onPause and then restarting it on onResume. 2. If you are showing map on Activity drawing overlay on it then stop refreshing the overlays while on sleep. And then restart it on onResume.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top