如何在没有Activity上下文的情况下在android中显示对话框?

这似乎应该是简单的,但我没有find答案的任何地方。 我有一个Android应用程序在后台执行networking任务。 如果出现错误,我想显示错误对话框。 当任务返回时,我不知道哪个Activity在前台。 基于这篇文章 ,它看起来像我们不能使用应用程序上下文来显示对话框(事实上,如果我尝试,我会得到崩溃)。

那么我怎样才能获得当前活动的背景呢? 同样,networking任务的接收者在应用程序上下文中运行,而不是在特定的活动中运行。 任何其他的想法?

编辑:我应该澄清。 如果我不是前台应用程序,我不想显示错误对话框。 我只对我们的应用现在处于前台的情况感兴趣。

Solutions Collecting From Web of "如何在没有Activity上下文的情况下在android中显示对话框?"

如果出现错误,我想显示错误对话框。

请只做这个,如果你知道用户正在积极使用你的应用程序。 如果你在别的事情中打断他们(玩游戏,看电影,看书),用户会非常恼火。

那么我怎样才能获得当前活动的背景呢?

你没有。 您最多可以让当前活动知道需要做些什么。

任何其他的想法?

一种可能性是使用有序的广播,所以如果你有一个前台活动,它得到控制,否则你提出一个Notification ,让用户知道这个问题,而不会popup一个对话框。 接收到有序广播的活动可以显示一个AlertDialog或者让用户知道这个问题。 我写了关于如何在博客文章中做到这一点的细节(以及关于这个问题的书籍章节 ),下面是一个演示这种技术的示例应用程序 。

或者,让服务调用startActivity()来启动一个以对话为主题的活动 。

我创build了一个实现CommonsWare思想的帮助类。 希望显示警报的活动只需要调用Alerts.register()和Alerts.unregister()。 然后任何人都可以调用Alerts.displayError()。

评论欢迎。

 public class Alerts { private static class AlertReceiver extends BroadcastReceiver { private static HashMap<Activity, AlertReceiver> registrations; private Context activityContext; static { registrations = new HashMap<Activity, AlertReceiver>(); } static void register(Activity activity) { AlertReceiver receiver = new AlertReceiver(activity); activity.registerReceiver(receiver, new IntentFilter(MyApplication.INTENT_DISPLAYERROR)); registrations.put(activity, receiver); } static void unregister(Activity activity) { AlertReceiver receiver = registrations.get(activity); if(receiver != null) { activity.unregisterReceiver(receiver); registrations.remove(activity); } } private AlertReceiver(Activity activity) { activityContext = activity; } @Override public void onReceive(Context context, Intent intent) { abortBroadcast(); String msg = intent.getStringExtra(Intent.EXTRA_TEXT); displayErrorInternal(activityContext, msg); } } public static void register(Activity activity) { AlertReceiver.register(activity); } public static void unregister(Activity activity) { AlertReceiver.unregister(activity); } public static void displayError(Context context, String msg) { Intent intent = new Intent(MyApplication.INTENT_DISPLAYERROR); intent.putExtra(Intent.EXTRA_TEXT, msg); context.sendOrderedBroadcast(intent, null); } private static void displayErrorInternal(Context context, String msg) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle("Error") .setMessage(msg) .setCancelable(false) .setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); final AlertDialog alert = builder.create(); alert.show(); } } 

我也面临这个问题。 我find了一个简单而有效的解决scheme。 通常,我们有一个基本的活动用来处理一些常见的逻辑。 所以有这个:

 public class BaseActionBarActivity extends ActionBarActivity{ //this BaseActionBarActivity is the Base Act private static BaseActionBarActivity current; @Override protected void onStart() { super.onStart(); current=this; } public static BaseActionBarActivity getCurrentContext() { return current; } } 

当前的领域是当前的上下文活动。 我相信没有内存泄漏的问题。 这对我来说很有效! 希望有帮助

下面是一个实现,它将允许AlertDialog显示在当前活动活动之上(这是一个消息对话框的例子,但也可以用于提醒)。

 public class AlertsDialogue { private AlertDialog.Builder alertDialogBuilder; private AlertDialog alert; public AlertsDialogue(Context context, String title, String message) { alertDialogBuilder = new AlertDialog.Builder(context); alertDialogBuilder.setTitle(title); alertDialogBuilder.setIcon(R.drawable.ic_launcher); alertDialogBuilder.setMessage(message) .setCancelable(false) .setPositiveButton(context.getString(R.string.text_ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { alert.dismiss(); } }); alert = alertDialogBuilder.create(); Window window = alert.getWindow(); if (window != null) { // the important stuff.. window.setType(WindowManager.LayoutParams.TYPE_TOAST); alert.show(); } else Toast.makeText(context, message, Toast.LENGTH_LONG).show(); } } 

即使实例化的上下文不再有效,对话框也会显示,就像Toast一样。

呼叫new AlertsDialogue(MyActivity.this, "title", "message");

AndroidManifest文件中不需要额外的权限。

在后台进行什么types的networking任务。 我会build议可能重新考虑devise。 也许通知会更好? 或者,也许是一个“结果总结”屏幕。 作为一个用户,如果我不积极地等待任务完成,我宁愿一个不显眼的错误信号。

为什么不使用事件总线( https://github.com/greenrobot/EventBus )?

  1. 定义事件:

     public class ShowErrorMessageEvent { public String errorMessage; public ShowErrorMessageEvent(String errorMessage) { this.errorMessage = errorMessage; } public String getErrorMessage() { return this.errorMessage; } } 
  2. 为所有需要的活动准备订阅者:

     @Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { EventBus.getDefault().unregister(this); super.onStop(); } 
  3. 在所有活动中,如果收到事件,请显示对话框

      public void onEvent(ShowErrorMessageEvent event) { /* Show dialog with event.getErrorMessage() from background thread */ }; 
  4. 在后台线程中,发布错误事件:

     EventBus.getDefault().post(new ShowErrorMessageEvent("This is an error message!")); 

你需要重新设置Window对话框的types,如下所示:dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

不要忘记在清单中声明“android.permission.SYSTEM_ALERT_WINDOW”权限。

那么,我认为最适合你的将是一个AsyncTask。 这里有一个例子和文档: http : //developer.android.com/reference/android/os/AsyncTask.html