在ActivityGroup中的ListActivity无法显示AlertDialog。

4

我试图在ListActivity中的项目被点击时显示一个AlertDialog。我的应用程序将ListActivity显示在TabActivity的选项卡下,而AlertDialog没有问题地显示出来。 ListActivity(称为FavouritesActivity)基本上是从Android文档中复制过来的,具有以下设置:

    lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {

                //... code to set the strings station, number, route, and direction

                FavouritesActivity.this.confirmSend(position);
            }
        });

然后。
public void confirmSend(final int position) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Are you sure?")
        .setCancelable(true)
        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    //... some code to run here                                                              
                }
            })
        .setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });
    AlertDialog alert = builder.create();
    alert.show();
}

然而,在TabActivity的第二个标签页中,我使用LocalActivityManager创建了一个ActivityGroup,来启动另一个ListActivity,代码如下(与在线嵌套列表教程几乎没有改变):

public class MyGroupActivity extends ActivityGroup {

// Keep this in a static variable to make it accessible for all the nesten activities, lets them manipulate the view                                      
public static MyGroupActivity group;

// Need to keep track of the history if you want the back-button to work properly, don't use this if your activities requires a lot of memory.            
private ArrayList<View> history;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.history = new ArrayList<View>();
    group = this;

    // Start the root activity withing the group and get its view                                                                                         
    View view = getLocalActivityManager().startActivity("FirstListActivity", new
                                                        Intent(this,FirstListActivity.class)
                                                        .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
        .getDecorView();

    // Replace the view of this ActivityGroup                                                                                                             
    replaceView(view);

}

public void replaceView(View v) {
    // Changes this Groups View to the new View.                                                                                                          
    setContentView(v);
}

这里的FirstListActivity是一个ListActivity,它是一系列活动中的第一个。用户选择一个项目后,会出现另一个ListActivity,代码如下:

    lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                Intent intent = new Intent();
                intent.setClass(FirstListActivity.this, TheNextListActivity.class);                                                                                                                

                // Create View using the Group Activity's LocalActivityManager                                                                            
                View newview = MyGroupActivity.group.getLocalActivityManager()
                    .startActivity("show_routes", intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
                    .getDecorView();
                // And replace the view                                                                                                                   
                MyGroupActivity.group.replaceView(newview);
            }
        });

这个系列中的最后一个ListActivity与我展示的第一个ListActivity(那个能正常工作的)完全相同,都有一个onItemClick监听器和相关的confirmSend函数。但是现在,当用户点击某个项目时,AlertDialog没有显示出来,应用程序会意外停止,并输出以下调试信息:
W/WindowManager(  570): Attempted to add application window with unknown token android.os.BinderProxy@4373af30.  Aborting.
D/AndroidRuntime( 1953): Shutting down VM
W/dalvikvm( 1953): threadid=3: thread exiting with uncaught exception (group=0x4000fe70)
E/AndroidRuntime( 1953): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 1953): android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord@43750f98 is not valid; is your activity running?
E/AndroidRuntime( 1953):    at android.view.ViewRoot.setView(ViewRoot.java:425)
E/AndroidRuntime( 1953):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:178)
E/AndroidRuntime( 1953):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/AndroidRuntime( 1953):    at android.view.Window$LocalWindowManager.addView(Window.java:392)
E/AndroidRuntime( 1953):    at android.app.Dialog.show(Dialog.java:231)
E/AndroidRuntime( 1953):    at com.ttcsms.LastListActivity.confirmSend(LastListActivity.java:119)
E/AndroidRuntime( 1953):    at com.ttcsms.LastListActivity$1.onItemClick(LastListActivity.java:66)
E/AndroidRuntime( 1953):    at android.widget.AdapterView.performItemClick(AdapterView.java:283)
E/AndroidRuntime( 1953):    at android.widget.ListView.performItemClick(ListView.java:3132)
E/AndroidRuntime( 1953):    at android.widget.AbsListView$PerformClick.run(AbsListView.java:1620)
E/AndroidRuntime( 1953):    at android.os.Handler.handleCallback(Handler.java:587)
E/AndroidRuntime( 1953):    at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime( 1953):    at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 1953):    at android.app.ActivityThread.main(ActivityThread.java:3948)
E/AndroidRuntime( 1953):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 1953):    at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 1953):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
E/AndroidRuntime( 1953):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
E/AndroidRuntime( 1953):    at dalvik.system.NativeStart.main(Native Method)
I/Process (  570): Sending signal. PID: 1953 SIG: 3
I/dalvikvm( 1953): threadid=7: reacting to signal 3
I/dalvikvm( 1953): Wrote stack trace to '/data/anr/traces.txt'
I/Process ( 1953): Sending signal. PID: 1953 SIG: 9
I/ActivityManager(  570): Process com.ttcsms (pid 1953) has died.

这两种导致AlertDialog失败的路线有什么区别?似乎与AlertDialog.Building(this)有关。在ActivityGroup中,它获取到了错误的上下文或其他内容。我在网上找到的每个此错误的示例都是通过更改"this"和"getApplicationContext()"之间来解决的,但在这种情况下,两者都不起作用。我尝试了其他获取上下文的变化,但由于大多数都是随机猜测,所以我认为在这里寻求建议会更好。我应该传递哪个上下文,还是其他地方出了问题?
3个回答

21

明白了!实际上这是一个 Android 上下文 的问题。

代码行:

AlertDialog.Builder builder = new AlertDialog.Builder(this);

你应该传递 TabActivity 的上下文而不是 this,因为在活动中显示弹出窗口需要传递可见/主要活动的上下文。

所以,简单的解决方案:

  1. 存储 TabActivity 的上下文,以供稍后在弹出窗口中使用。
  2. 在弹出窗口的代码中传递 TabActivity 的上下文而不是 this。

希望能有所帮助。 干杯 :)


好的,我认为我已经按照您的建议实现了,在TabActivity类中加入了public static MyActivity context;,在onCreate方法中设置了context = this;,然后在创建对话框构建器时传递了MyActivity.context。这是正确的想法吗?无论如何,这似乎已经解决了问题。我发现很奇怪,在ListActivity中传递this可以工作,但在ActivityGroup中却不行,尽管两者都在TabActivity下面。 - GJP
嘿,太好了,知道你解决了!现在将此答案标记为正确,以便其他人可以受益。 - Piyush Patel

5

最终按照您的方式解决了我的问题,这里我提供一些细节:

创建一个上下文到 Tabactivity 类中,代码如下:

"public static MyTabactivity context;"

在 MyTabactivity 的 onCreate 方法中分配 "context=this"。然后在您的 alertboxes 中使用 MyTabactivity.context,代码如下:

"AlertDialog.Builder adb = new AlertDialog.Builder(MyTabactivity.context);"

希望这能帮到您......


5
为了简化起见,您可以直接将getParent()作为上下文传递给AlertDialog,而不是定义上下文变量并在onCreate中设置它。请注意保留HTML标记。

功能如广告所述,是所有答案中最简单的。 - stephenmuss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接