Adding android progress dialog inside Background service with AsyncTask,Getting FATAL Exception

一个人想着一个人 提交于 2019-12-10 03:47:00

问题


  1. Iam calling a Asynctask from Scheduled Service Every 10 mins it will Run.

  2. while running the Service, Progress dialog getting Exception from OnpreExecute.

ERROR :

FATAL EXCEPTION: main                                                                                    
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:594)

at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:259)

at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)

at android.app.Dialog.show(Dialog.java:286)

EDIT 1: Alarm Manager for calling the service for every 5 mins

/*Alarm manager Service for From Server*/
private void setServerFetch() {
    // for  to Server to GPS PING
    Intent myIntent1 = new Intent(LoginPage.this, AlarmService.class);
    pendingintent1 = PendingIntent.getService(LoginPage.this, 1111, myIntent1, 0);
    AlarmManager alarmManager5 = (AlarmManager) getSystemService(ALARM_SERVICE);
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTimeInMillis(System.currentTimeMillis());
    calendar1.add(Calendar.SECOND, 1);
    alarmManager5.set(AlarmManager.RTC_WAKEUP, calendar1.getTimeInMillis(), pendingintent1);
    alarmManager5.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar1.getTimeInMillis(), 300 * 1000, pendingintent1);

}

Calling the AsyncTask from Service Onstart

 @Override
    public void onStart(Intent intent, int startId)
    {
        super.onStart(intent, startId);


        try
        {

                Asynctask_Incident task=new Asynctask_Incident();
                task=new();

        }
        catch (Exception e)
        {
            e.printStackTrace();
            Log.i("PING", "EXCEPTION in reading Data from Web Async task ONstart.!");

        }

    }

Asynctask Class onStart Method

public class Asynctask_Incident extends AsyncTask<String, Void, Void>
    {


        @Override
        protected void onPreExecute()
        {
            super.onPreExecute();

            runOnUiThread(new Runnable() {

                @Override
                public void run() {

                    if (!pDialog.isShowing())
                    {
                        pDialog = new ProgressDialog(appContext);
                        pDialog.setCanceledOnTouchOutside(false);
                        pDialog.setCancelable(false);
                        pDialog.setMessage("Please Wait Updating Data From...");
                        pDialog.show();
                    }
                }
            });


        }

        @Override
        protected Void doInBackground(String... params)
        {
            try {
                getAPICall();

            } catch (Exception e) {
                e.printStackTrace();

                if (pDialog.isShowing()) {
                    pDialog.dismiss();
                }

            }

            return null;
        }
        @Override
        protected void onPostExecute(Void aVoid)
        {

            super.onPostExecute(aVoid);

            if (pDialog.isShowing()) {
                pDialog.dismiss();
            }


        }


    }

Help me to Solve this Issue.


回答1:


Actually you can't start a progress dialog from a service, because it needs the activity context not application context which come to be null in your case.

More info here: link1 , link2 and link3

If you want to trigger progress dialog based on service action, you may use Observer design patter, look here.

Update: If your app is running, you can use Handler and run it each 5 minutes.

Here is a complete example:

public class TestActivity extends AppCompatActivity {

private Handler handler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);

    handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            //
            new Asynctask_Incident(TestActivity.this).execute("url");
            handler.postDelayed(this, 5 * DateUtils.MINUTE_IN_MILLIS);
        }
    }, 0);
}

public class Asynctask_Incident extends AsyncTask<String, Void, Void> {


    ProgressDialog pDialog;
    Context appContext;

    public Asynctask_Incident(Context ctx) {
        appContext = ctx;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

            pDialog = new ProgressDialog(appContext);
            pDialog.setCanceledOnTouchOutside(false);
            pDialog.setCancelable(false);
            pDialog.setMessage("Please Wait Updating Data From...");
            pDialog.show();


    }

    @Override
    protected Void doInBackground(String... params) {
        try {
            getAPICall();

        } catch (Exception e) {
            e.printStackTrace();

            if (pDialog.isShowing()) {
                pDialog.dismiss();
            }

        }

        return null;
    }

    private void getAPICall() {

        //5 seconds delay for test, you can put your code here
        try {
            Thread.sleep(5 * DateUtils.SECOND_IN_MILLIS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onPostExecute(Void aVoid) {

        super.onPostExecute(aVoid);

        if (pDialog.isShowing()) {
            pDialog.dismiss();
        }


    }


}

}



回答2:


Intialize your ProgressDialog.

OnPreExecute();

runOnUiThread(new Runnable() {

                @Override
                public void run() {

                    if (pDialog == null)
                    {
                       pDialog = new ProgressDialog(appContext);
                        pDialog.setCanceledOnTouchOutside(false);
                        pDialog.setCancelable(false);
                        pDialog.setMessage("Please Wait Updating Data From...");

                    }

                   pDialog.show();
                }
            });

OnPostExecute();

 pDialog.dismiss();



回答3:


The exception Exception:android.vi‌​ew.WindowManager$BadT‌​okenException: Unable to add window -- token null is not for an application comes when the context is not alive. There may be other reason for this exception but context is major reason. Moreover, if previously shown Dialog is not dismissed, exception may occur.

Please try this code :

runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if(appContext != null) {

                    // if dialog is already showing, hide it
                    if(pDialog != null && pDialog.isShowing()) {
                        pDialog.dismiss();
                    }

                    if (pDialog == null) {
                        pDialog = new ProgressDialog(appContext);
                        pDialog.setCanceledOnTouchOutside(false);
                        pDialog.setCancelable(false);
                        pDialog.setMessage("Please Wait Updating Data From...");
                    }
                    pDialog.show();

                } else {
                    Log.e("Error","Context is Null");
               }
            }
        });

An additional check can be added : http://dimitar.me/android-displaying-dialogs-from-background-threads/




回答4:


You do not need to initialize the dialog in a thread in the onPreExecute. Because this method is always called in the UI thread. By calling a thread you are delaying it. So the doInbackground perhaps happened before the dialog was created.

Also you should not call anything that modifies the UI in the doItBackground method. Because this method runs in a worker thread. Any UI call must be in the main thread. The onPostExecute is called by the main thread. So put your dialog related calls there, but not in the doInBackground.

These lines in the doInbackground need to be removed.

if (pDialog.isShowing()) {
                        pDialog.dismiss();
                    }



回答5:


1) You don't need your ProgressDialog setup inside a Runnable, anything in onPreExecute() and onPostExecute() already runs on the UI thread. Only doInBackground() runs off the UI thread.

2) Put AsyncTask class in MainActivity, call it from MainActivity, not from your Service. Call your AsyncTask from the MainActivity like this:

new MyAsyncTask(MainActivity.this).execute("");

3) Finally, put this constructor in your AsyncTask class:

public MyAsyncTask(Context context) {
        appContext = context;
    }



回答6:


It seems like your context does not have the right set of resources. Make sure that your are using the right context.

Context context = this;
ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.show();

where "this" - AppCompatActivity or Activity context



来源:https://stackoverflow.com/questions/38974627/adding-android-progress-dialog-inside-background-service-with-asynctask-getting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!