Android 在IntentService中创建AlertDialog时无法添加窗口

Android 在IntentService中创建AlertDialog时无法添加窗口,android,android-alertdialog,intentservice,Android,Android Alertdialog,Intentservice,我想在IntentService内创建AlertDialog,但在AlertDialog.Builder构造函数内传递上下文时,会显示以下错误: 06-30 00:01:31.265 11994-11994/com.alwa7y W/System.err: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application 06-30 00:01:31

我想在IntentService内创建AlertDialog,但在AlertDialog.Builder构造函数内传递上下文时,会显示以下错误:

06-30 00:01:31.265 11994-11994/com.alwa7y W/System.err: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
06-30 00:01:31.267 11994-11994/com.alwa7y W/System.err:     at android.view.ViewRootImpl.setView(ViewRootImpl.java:572)
    at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:310)
    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:86)
    at android.app.Dialog.show(Dialog.java:319)
    at com.go.mushaf.mushafapplication.services.DownloadService$override.showAlert(DownloadService.java:176)
    at com.go.mushaf.mushafapplication.services.DownloadService$override.access$dispatch(DownloadService.java)
    at com.go.mushaf.mushafapplication.services.DownloadService.showAlert(DownloadService.java:0)
    at com.go.mushaf.mushafapplication.services.DownloadService$BackGroundTask.onPostExecute(DownloadService.java:88)
    at com.go.mushaf.mushafapplication.services.DownloadService$BackGroundTask.onPostExecute(DownloadService.java:61)
    at android.os.AsyncTask.finish(AsyncTask.java:651)
    at android.os.AsyncTask.access$500(AsyncTask.java:180)
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:148)
06-30 00:01:31.268 11994-11994/com.alwa7y W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5451)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
这是创建AlertDialog的方法:

    public void showAlert(String message, String header) {
        if (header.equals(""))
            header = "Alert!";
        try {
            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getApplicationContext());
//            Log.d(TAG, "show: " + alertDialog.getOwnerActivity());
            alertDialogBuilder.setTitle(header);
            alertDialogBuilder.setMessage(message);
            alertDialogBuilder.setPositiveButton("موافق",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            ((Activity) context).finish();
                            dialog.dismiss();

                            showEndLoadingNotification(context);
                        }
                    });
//            alertDialogBuilder.show();
            alertDialogBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    ((Activity) context).finish();
                }
            });
            AlertDialog alertDialog = alertDialogBuilder.create();
            alertDialog.show();
        } catch (Exception ignored) {
            ignored.printStackTrace();
        }//when app trying to display a dialog using a previously finished activity as a context
    }
这是IntentService类:

    package com.go.mushaf.mushafapplication.services;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.IntentService;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.go.mushaf.mushafapplication.DownloadActivity;
import com.go.mushaf.mushafapplication.MainActivity;

import java.util.ArrayList;

import static com.go.mushaf.mushafapplication.DownloadActivity.BUNDLE;
import static com.go.mushaf.mushafapplication.DownloadActivity.CONTEXT;
import static com.go.mushaf.mushafapplication.DownloadActivity.TEXT_ID;
import static com.go.mushaf.mushafapplication.DownloadActivity.getLoadingText;
import static com.go.mushaf.mushafapplication.DownloadActivity.mTxtProgress;
import static com.go.mushaf.mushafapplication.DownloadActivity.showEndLoadingNotification;
import static com.go.mushaf.mushafapplication.Utility.getPages;


public class DownloadService extends IntentService {

    public int viewId;
    Context context;
    public static final String TAG = "servicee";

    public DownloadService() {
        super("DownloadService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        if (intent.hasExtra(BUNDLE)) {
            viewId = intent.getBundleExtra(BUNDLE).getInt(TEXT_ID);
            Log.d(TAG, "onHandleIntent: ");
        }
        new BackGroundTask().execute();
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        context = getApplicationContext();
        return super.onStartCommand(intent, flags, startId);
    }

    public class BackGroundTask extends AsyncTask<Void, Integer, Void> {

        private final String ASYNC_ERROR = this.getClass().getName();
        private RequestBuilder<Drawable> x;
        private ArrayList<String> pagesList = getPages();

        @Override
        protected Void doInBackground(Void... arg0) {

            // FIXME: 6/27/2018
            doAllCache(mTxtProgress);
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
//            if(x!=null) {
//                x.preload();
////                if (!cancelFlag || count < MainActivity.mushafTotal)
////                    new BackGroundTask().execute(++count);
//            }
            showAlert("تم اكتمال التحميل بنجاح", "تم التحميل");
            // getApplicationContext(), unable to add window
            // DownladService.this, unable to add window
            // getBaseContext(), unable to add window
        }

        private void doAllCache(final TextView mTxtProgress) {
            Log.d(TAG, "doAllCache: " + mTxtProgress.getText().toString());
            Log.d(TAG, "doAllCache: " + pagesList.size());
            for (int i=0; i<pagesList.size(); i++) {
                String pageNumber = pagesList.get(i); //get string for page number
                Log.d(TAG, "doAllCache: " + pageNumber);
                String url = MainActivity.mainUril + pageNumber + ".gif"; // get page url
                final int finalI = i;
                x = Glide.with(DownloadService.this)
                        .load(url)
                        .listener(new RequestListener<Drawable>() {
                            @Override
                            public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
//                                Log.i("Image Loading End", String.valueOf(i));
                                mTxtProgress.setText(getLoadingText(getApplicationContext(), finalI));
                                Log.d(TAG, "onResourceReady: " + resource +"\n"+model.toString()+"\n"+target+"\n"+dataSource);
////                                //check cancel
////                                if (cancelFlag) {
////                                    finish();
////                                } else {
//
//                                    if (finalI < MainActivity.mushafTotal) {
//                                        final int ii = finalI + 1;
//                                        new BackGroundTask().execute();
//
////                                    new Handler().postDelayed(new Runnable() {
////                                        @Override
////                                        public void run() {//Use your "bitmap" here
////                                            doAllCache(ii);
////                                        }
////                                    }, 100);
//                                    }
////                                    else{
////                                        cancelFlag = true;
////                                    }
////                                }
                                return true;
                            }

                            @Override
                            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
                                Log.d(ASYNC_ERROR, String.valueOf(finalI));
                                Log.d(ASYNC_ERROR, "onLoadFailed: " + e);
                                return false;
                            }

                        });
            }




        }

    }

    public void showAlert(String message, String header) {
        if (header.equals(""))
            header = "Alert!";
        try {
            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getApplicationContext());
//            Log.d(TAG, "show: " + alertDialog.getOwnerActivity());
            alertDialogBuilder.setTitle(header);
            alertDialogBuilder.setMessage(message);
            alertDialogBuilder.setPositiveButton("موافق",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            ((Activity) context).finish();
                            dialog.dismiss();

                            showEndLoadingNotification(context);
                        }
                    });
//            alertDialogBuilder.show();
            alertDialogBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    ((Activity) context).finish();
                }
            });
            AlertDialog alertDialog = alertDialogBuilder.create();
            alertDialog.show();
        } catch (Exception ignored) {
            ignored.printStackTrace();
        }//when app trying to display a dialog using a previously finished activity as a context
    }
}
我想在onPostExecute方法中显示对话框。 我试过:

getApplicationContext(), DownloadService.this, this, getBaseContext()
所有这些都给出了相同的错误


提前感谢。

您无法从
服务
显示
警报对话框
。只能从
活动
中显示
警报对话框
。在这种情况下,显示启动此服务的活动中的对话框。或者,不要使用对话框,而是使用
通知

除此之外:

  • 不要在
    IntentService
    内部执行异步操作,因为只要
    onHandleIntent()
    返回,服务就会立即消失。一旦服务消失,您的进程可能会终止,在工作完成之前杀死您的后台线程。删除
    BackGroundTask
    并将其所有要执行的逻辑从
    onHandleIntent()
    移动。另外,摆脱Glide或者弄清楚如何让它同步下载图像(好吧,这是不行的)

  • IntentService
    在Android 8.0+上无法正常工作,除非您将其设置为前台服务并使用
    startForegroundService()
    。考虑使用<代码> JooTunService < /代码>,或者在2019和以后,<代码>工作管理器< /C> > < /P>

谢谢您的回答。这真的很有帮助:)您可以在没有活动上下文的情况下显示对话框@杰弗里伯拉特曼:如果你的意思是系统警报窗口,请不要这样做。
getApplicationContext(), DownloadService.this, this, getBaseContext()