Android 调用popupwindow的showAtLocation正在使应用程序崩溃

Android 调用popupwindow的showAtLocation正在使应用程序崩溃,android,popup,Android,Popup,我有一个从视图扩展而来的类,我正试图使用此代码显示一个弹出窗口 public class dbView extends View implements View.OnTouchListener { private void showDialog(String msg) { LayoutInflater layoutInflater; View dialogContent; final PopupWindow popupWindow;

我有一个从
视图
扩展而来的类,我正试图使用此代码显示一个
弹出窗口

public class dbView extends View implements View.OnTouchListener {

    private void showDialog(String msg) {
        LayoutInflater layoutInflater;
        View dialogContent;
        final PopupWindow popupWindow;

        layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        dialogContent = layoutInflater.inflate(R.layout.pop_up_dialog, null);

        popupWindow = new PopupWindow(
                dialogContent,
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);

        popupWindow.showAtLocation(this, Gravity.CENTER, 10, 10);

    }

}
我的应用程序在尝试执行最后一行时崩溃。异常的消息是

无法在尚未调用的线程内创建处理程序 Looper.prepare()

我一直在寻找与该消息相关的答案,所有这些答案都涉及到弹出窗口是在一个单独的线程上创建的,我应该使用它
runOnUIThread
但是如果我在视图中我需要这样做吗?这个问题的原因是什么?

我想可能是因为您试图从非原始线程(创建UI的线程)干扰UI。您的自定义视图类无法更改UI,因此我认为最好的方法是调用
runOnUIThread()
。虽然我听说使用runOnUIThread可能不是最好的选择,但在我看来,这正是您的情况所需要的

通常为了实现这一点,我会创建一个特殊的类来扩展应用程序(在我的例子中是ContextGetter),并实现如下方法:

public class ContextGetter extends Application {

    private static Context context;

    public void onCreate(){
        super.onCreate();
        context = getApplicationContext();
    }

    public static Context getAppContext() {
        return context;
    }
}
<application
        android:name=".ContextGetter"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
它帮助我从任何地方获取应用程序上下文。您还应将其添加到清单中,如下所示:

public class ContextGetter extends Application {

    private static Context context;

    public void onCreate(){
        super.onCreate();
        context = getApplicationContext();
    }

    public static Context getAppContext() {
        return context;
    }
}
<application
        android:name=".ContextGetter"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

这可能看起来很奇怪,但一定对你有用。它看起来是这样的,因为
活动
是从
上下文
派生的。无论你何时尝试,我都想知道它是否有效。希望我能帮助解决这个问题,这取决于你在哪里调用showDialog(String msg),我知道你是从视图类调用它的,但这并不意味着它在UI线程上,视图调用是在UI线程上处理的,但是如果你在线程中进行视图调用,你就会出现这个错误。我知道同样的代码是自己解决的,但是如果您运行的是视图类中的TimerTask或线程,您应该仔细检查它们。也可以调用
post(runnable),而不是
rununuithread
(与视图类中的处理程序<代码>相同的机制),它将确保可运行调用将发送到主线程

简而言之,检查您在清单的
视图中调用它的位置

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

我是从同样的角度来看待这个问题的!!你能给我一个具体的例子吗?信不信由你,这只是一个提供赏金的问题,现在使用与我发布的代码相同的代码@MauricioGracia这真的很奇怪,但不管怎样,我很高兴它现在起作用了!为Android开发祝您好运如果TimerTask从显示对话框的视图调用一个方法,我必须在该调用中使用RunUiThread吗?是的,因为
TimerTask
运行不同的线程-(它创建了一个新线程),所以即使您在一个视图中调用的方法应该在UI线程上,这不是。。。明白了吗,先生?如果您想在视图类中移动到UI线程,请使用post方法,它与我的answer@MauricioGraciayou有一个错误,如“无法在未调用Looper.prepare()的线程内创建处理程序”,但您提到了有关使用“处理程序”的代码。请解释我与你做了正确的代码,这样我可以尝试为你。