0

AIM I have an activity with a list view and a few buttons and a few extra stuff. What I want is to populate this list view with custom adapter when the activity starts. As it takes time to generate this custom adapter I wanted to add a progress bar, so that user is not forced to stare at the unresponsive-screen. When done, dismiss this progress bar and show the activity as it is supposed to be.

WHAT I DID - "CODE"

public void onCreate(Bundle savedInstanceState) {
...
// all initialization done here properly
new ProgressTask(this).execute("");
}

public class ProgressTask extends AsyncTask<String, Void, Boolean> {

    public ProgressTask(ScanInboxActivity activity) {
        dialog = new ProgressDialog(activity.getApplicationContext());
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
    }

        /** progress dialog to show user that the backup is processing. */
    private ProgressDialog dialog;

    protected void onPreExecute() {
        this.dialog.setMessage("Scan start");
        this.dialog.show();
    }

    @Override
    protected void onPostExecute(final Boolean success) {
        if (dialog.isShowing()) {
            dialog.dismiss();               
        }
        populateList();
    }

    protected Boolean doInBackground(final String... args) {
        init(); // tasks to be performed- no error here
        scanSms(); // tasks to be performed- no error here
        return true;
    }
}

I get following Exception:

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.ScanInboxActivity}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
at android.app.ActivityThread.access$2300(ActivityThread.java:125)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRoot.setView(ViewRoot.java:509)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.app.Dialog.show(Dialog.java:241)
at com.example.ScanInboxActivity$ProgressTask.<init>(ScanInboxActivity.java:212)
at com.example.ScanInboxActivity.onCreate(ScanInboxActivity.java:59)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
... 11 more

Please note that when I write this

public void onCreate(Bundle savedInstanceState) {
// all initialization done here properly
init();
scanSms();
populateList();
}

Things work fine, though the activity which starts this activity hangs for a moment. I don't want this to happen.

Please suggest what to do. Thanks in advance.

EDIT scanSms() uses context. I can not eliminate use of context because it is used in a function (in a different class) called in scanSms(), which is also called from other activities around the application

harshit
  • 3,788
  • 3
  • 31
  • 54

3 Answers3

0

Try this:

public ProgressTask(ScanInboxActivity activity) {
        dialog = new ProgressDialog(activity);
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
    }

    protected void onPreExecute() {
        this.dialog.setMessage("Scan start");
        this.dialog.show();
    }

EDITED:

public class ProgressTask extends AsyncTask<String, Void, Boolean> {

        /** progress dialog to show user that the backup is processing. */
        private ProgressDialog dialog;

        public ProgressTask(MainMenuActivity activity) {
            dialog = new ProgressDialog(activity);
            dialog.setIndeterminate(true);
            dialog.setCancelable(false);
        }

        protected void onPreExecute() {
            this.dialog.setMessage("Scan start");
            this.dialog.show();
        }

        @Override
        protected void onPostExecute(final Boolean success) {
            if (dialog.isShowing()) {
                dialog.dismiss();               
            }
            //populateList();
        }

        protected Boolean doInBackground(final String... args) {
            //init(); // tasks to be performed- no error here
            //scanSms(); // tasks to be performed- no error here
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return true;
        }
    }
Dimmerg
  • 2,113
  • 1
  • 13
  • 14
  • Yes, pretty much the same. Difference is `at com.example.ScanInboxActivity$ProgressTask.(ScanInboxActivity.java:219)` now. i.e. changes the line number where I am calling this.dialog.show() – harshit Jun 18 '13 at 08:01
  • I've updated my post by adding full code. I tried this code in activity in my project and it worked. May be you make little typo or mistake? Compare again, please – Dimmerg Jun 18 '13 at 08:03
  • It worked. Thankyou. I don't know where the problem was with my code. I will be checking it out. I may have made a typo somewhere. – harshit Jun 18 '13 at 08:07
0

My assumption is that the methods init() and scanSms() which you put in doInBackground(), makes use of Context. If this is so then this might be the cause, as the doInBackground() should not use the context.

Try to do the initialization in onPreExecute() which is invoked on UI thread, and only the heavy stuff in doInBackground().

Andy Res
  • 15,963
  • 5
  • 60
  • 96
  • only scanSms() uses context. I tried putting init in onPreExecute(). It does not work that way. – harshit Jun 18 '13 at 07:53
-2
  class asytask extends AsyncTask<String, Integer, String>
        {
            ProgressDialog dialog ;
            @Override
            protected void onPreExecute() {
                // TODO Auto-generated method stub
                super.onPreExecute();
                dialog  = new ProgressDialog(getApplicationContext());
                dialog.show();
            }
            @Override
            protected String doInBackground(String... params) {
                // TODO Auto-generated method stub

//use your backgournd process
                return null;
            }
            @Override
            protected void onPostExecute(String result) {
                // TODO Auto-generated method stub
                super.onPostExecute(result);
                dialog.dismiss();

 //  visible process
            }
        }
abhi
  • 759
  • 6
  • 15