简体   繁体   中英

What to do incase of Application Not Responding" (ANR) dialog?

i am making a project in which wallpaper will be changed after every 5 seconds

I used this code and the wallpapers are changing after every 5 seconds but the problem is coming that is i mentioned in photos

DisplayMetrics displayMetrics = new DisplayMetrics();
        int height = displayMetrics.heightPixels;
        int width = displayMetrics.widthPixels << 1; // best wallpaper width is twice screen width

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        for(int i=0; i<=list.size();i++){
            if(i==list.size()){
                i=0;
            }


        BitmapFactory.decodeFile(list.get(i));


        options.inJustDecodeBounds = false;
        Bitmap decodedSampleBitmap = BitmapFactory.decodeFile(list.get(i));

        WallpaperManager wm = WallpaperManager.getInstance(this);
        try {
            Log.i("In Service", "before set wallpaper");
            wm.setBitmap(decodedSampleBitmap);
            Log.i("In Service", "after set wallpaper");
            Thread.sleep(5000);
            Log.i("In Service", "after thread");

        } catch (Exception e) {
            Log.e("Exception", "Cannot set image as wallpaper", e);
        }
        }

After sometime this dialog will appear as the images are getting change and as i click on the wait button it start working

and after sometime as i open the app again to select the other images i get the dialog

After that i read http://developer.android.com/training/articles/perf-anr.html and did work in different thread but than also nothing was useful. May i know what must i do so that this dialog must not appear


Update 1:

I used Async Task and its working fine and i am not getting the dialog ANR now but it is taking more than 5 secs in the case where the images are very heavy ie 1.5 to 2.5 mb case but its running good in case of images that are of size 300-400 mb

public class WallService extends Service {

    ArrayList<String> list;

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        Log.i("on create", "Service Created");

    }

    @Override
    @Deprecated
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub
        super.onStart(intent, startId);

        list = intent.getStringArrayListExtra("Imagess");
        new LongOperation().execute("");
    }

    private class LongOperation extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {

            DisplayMetrics displayMetrics = new DisplayMetrics();
            int height = displayMetrics.heightPixels;
            int width = displayMetrics.widthPixels << 1; // best wallpaper width
                                                            // is twice screen
                                                            // width

            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            for (int i = 0; i <= list.size(); i++) {
                if (i == list.size()) {
                    i = 0;
                }

                BitmapFactory.decodeFile(list.get(i));

                options.inJustDecodeBounds = false;
                Bitmap decodedSampleBitmap = BitmapFactory.decodeFile(list
                        .get(i));

                WallpaperManager wm = WallpaperManager
                        .getInstance(WallService.this);
                try {
                    Log.i("In Service", "before set wallpaper");
                    wm.setBitmap(decodedSampleBitmap);
                    Log.i("In Service", "after set wallpaper");
                    Thread.sleep(5000);
                    Log.i("In Service", "after thread");

                } catch (Exception e) {
                    Log.e("Exception", "Cannot set image as wallpaper", e);
                }
            }
            return "Executed";
        }

        @Override
        protected void onPostExecute(String result) {

        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(Void... values) {
        }
    }

}

But i didnot get solution for my second problem ie when i open the app again and i click on select photos button it give me this dialog box

SO may i know wht must i do for these two problems ie 1. it works good even if the image is heavier 2. i didnot get the dialog when i go back to app again

在此处输入图片说明

The logcat i got in this case is

05-07 19:03:34.414: E/dalvikvm(18247): can't open /data/misc/hprof_oom_dump.hprof: Permission denied
05-07 19:03:34.434: D/-heap(18247): Dump of hprof is not done
05-07 19:03:34.454: D/skia(18247): --- decoder->decode returned false
05-07 19:03:34.454: W/dalvikvm(18247): threadid=1: thread exiting with uncaught exception (group=0x418c5450)
05-07 19:03:34.454: E/AndroidRuntime(18247): FATAL EXCEPTION: main
05-07 19:03:34.454: E/AndroidRuntime(18247): java.lang.OutOfMemoryError
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:527)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:301)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:326)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at com.example.images.MainActivity.onActivityResult(MainActivity.java:110)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.app.Activity.dispatchActivityResult(Activity.java:5192)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3143)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3190)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.app.ActivityThread.access$1100(ActivityThread.java:133)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.os.Handler.dispatchMessage(Handler.java:99)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.os.Looper.loop(Looper.java:137)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at android.app.ActivityThread.main(ActivityThread.java:4803)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at java.lang.reflect.Method.invokeNative(Native Method)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at java.lang.reflect.Method.invoke(Method.java:511)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
05-07 19:03:34.454: E/AndroidRuntime(18247):    at dalvik.system.NativeStart.main(Native Method)
05-07 19:03:34.575: I/In Service(18247): before set wallpaper
05-07 19:03:53.525: I/In Service(18247): after set wallpaper
05-07 19:03:58.530: I/In Service(18247): after thread

you should relook at your design a bit. ANR dialogs are caused by 'doing heavy weight jobs on main UI thread'. Try to see if you can push you processing to an asynctask or a loader instead. That should solve your problem. The for loop you are using can be effectively pushed to an asynctask instead.

You get Application Not Responding because you're blocking the UI thread with your infinite for loop. You get the dialog for blocking the UI thread for more than 5 seconds.

Instead of a loop and Thread.sleep() for delays, consider using a Timer or Handler to fire up callbacks at specified times.

It's also a good idea to do bitmap loading and decoding on a background thread instead of UI thread but that's not the immediate reason for ANR here.

There is no ready made solution to avoid ANR. Generally, the system displays an ANR if an application cannot respond to user input. For example, if an application blocks on some I/O operation (frequently a network access) on the UI thread so the system can't process incoming user input events.

In any situation in which your app performs a potentially lengthy operation, you should not perform the work on the UI thread, but instead create a worker thread and do most of the work there. This keeps the UI thread (which drives the user interface event loop) running and prevents the system from concluding that your code has frozen.

So you can think of doing lengthy tasks in background (Using AsyncTask ) to avoid ANR message.

reference

http://developer.android.com/training/articles/perf-anr.html

https://stackoverflow.com/a/10515848/1665507

The problem you getting now is your app running out of memory ie, OOM..

To avoid ANR you can do long operations on no UI thread, (Thread and handler, Async task etc) To avoid OOM (Out of Memory exception) follow this to handle large bitmps http://developer.android.com/training/displaying-bitmaps/load-bitmap.html and also you can find some jni impementation to store and retrive large bitmaps efficiently..

Here is the one you may need JNI bitmap operations , for helping to avoid OOM when using large images

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM