无法从 ActivityGroup 内的 ListActivity 显示 AlertDialog

发布于 2024-10-16 03:21:17 字数 7094 浏览 6 评论 0原文

我试图在单击 ListActivity 中的项目时显示 AlertDialog。我的应用程序在 TabActivity 的选项卡下显示 ListActivity,并且 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的第二个选项卡中,我有一个ActivityGroup,它使用LocalActivityManager来启动另一个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 侦听器和关联的 verifySend 函数,但现在当用户单击某个项目时,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()”之间进行更改来解决的,但在这种情况下,这些都不起作用。我尝试了其他变体来获取上下文,但由于我主要是随机猜测,所以我认为最好在这里寻求建议。我应该传递什么上下文,或者还有什么问题?

I am trying to show an AlertDialog when an item in a ListActivity is clicked. My app displays the ListActivity under a tab of a TabActivity, and the AlertDialog shows up no problem. The ListActivity (called FavouritesActivity) is pretty much straight from the Android docs, with this setting:

    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);
            }
        });

and then

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();
}

However, in a second tab of the TabActivity, I have an ActivityGroup that uses the LocalActivityManager to start another ListActivity, like so (again, pretty much unchanged from a tutorial on nesting lists under tabs online):

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);
}

The FirstListActivity here is a ListActivity that is the first in a series. The user picks an item and is presented with another ListActivity, with code like this:

    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);
            }
        });

The last ListActivity in this series has EXACTLY the same onItemClick listener and associated confirmSend function as the first ListActivity example I showed (the one which does work), but now when the user clicks on an item, the AlertDialog fails to show and the application stops unexpectedly, with this debug output:

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.

What is the difference between these two routes to the AlertDialog that cause this failure? It seems to have something to do with the AlertDialog.Building(this) bit. When within the ActivityGroup, it's getting the wrong context or something. Every example I found online of this error was solved by changing between "this" and "getApplicationContext()", but in this case neither of those work. I tried other variations on getting the context but as I mostly guessing at random I thought it would be better to ask here for advice. What context should I be passing, or, what else is wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

嘿哥们儿 2024-10-23 03:21:17

知道了!实际上这是一个Android Context问题。

排队:

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

您应该传递 TabActivity 的上下文,而不是 this,传递可见/主活动的上下文以显示活动中的任何弹出窗口。

因此,简单的解决方案:

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

希望这有帮助。
干杯:)

Got it! Actually here it's an Android Context problem.

In line:

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

Instead of this, you should pass the Context of the TabActivity, the context of the visible/main activity is passed to display any popup within activity.

So, simple solution:

  1. Store context of TabActivity for later use in pop-up.
  2. Pass TabActivity Context in pop-up code instead of this.

hope this helps.
cheers :)

疯了 2024-10-23 03:21:17

最后按照你的方法解决了我的问题。
在这里,我提供了一些详细信息,

如下所示为 Tabactivity 类创建上下文。

"public static MyTabactivity context;"

assgin "context= this" 在 MyTabactivity 的 onCreate 方法中。
然后在警报框中使用 MyTabactivity.context,如下所示。

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

我希望这会有所帮助......

Finally followed your approach and solved my problem.
Here i am giving some details

create a context to the Tabactivity class as follows.

"public static MyTabactivity context;"

assgin "context= this" in onCreate method of the MyTabactivity.
Then use MyTabactivity.context in your alertboxes as follows.

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

I hope this will help.....

懵少女 2024-10-23 03:21:17

为了使其变得相当简单,您可以直接将 getParent() 作为 中的上下文传递,而不是定义上下文变量并将其设置在 onCreate 上。警报对话框

To make it fairly simple, instead of defining context variable and setting it on onCreate, what you can do is you can directly pass getParent() as context in the AlertDialog.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文