【问题标题】:Passing Activity Context to Handler(fragment) for Toast将活动上下文传递给 Toast 的处理程序(片段)
【发布时间】:2015-05-12 11:01:28
【问题描述】:

我正在尝试在处理程序片段类中使用 Toast 消息,但我无法访问主类的上下文。处理程序与主要活动 PlayFrets(也是 UI 线程)在同一个类中。我已经阅读了有关 stackoverflow 上有关此主题的大量问题,但几乎每个解决方案都涉及传递 getActivity() 或 getActivity() .getApplicationContext() 进入 Toast 的上下文字段。当我尝试这个时,我得到了错误

以下是相关代码:

public class PlayFrets extends Activity {
. 
.
.
    static Handler mHandler = new Handler(Looper.getMainLooper()){  
        public void handleMessage(final Message msg){ 
            if(msg.obj != null){                
                runOnUiThread(new Runnable() {
                   public void run() {
                   //error happens here on Toast message
                       Toast.makeText(getActivity(), "Background Thread sent "+  msg.what + " bytes: " + msg.obj,Toast.LENGTH_SHORT).show();
                    }
                });
            }
            else{
            }
        }
    };
}

这些是我传递上下文和每个变体产生的错误的尝试。

Toast.makeText(PlayFrets.this.getActivity()...)

^^^PlayFrets 类型的 getActivity() 方法未定义

Toast.makeText(PlayFrets.this...) 

^^^PlayFrets 类型的封闭实例在范围内是不可访问的

 Toast.makeText(getActivity().getApplicationContext()...)

^^^new Runnable(){}类型的getActivity()方法未定义

将主要活动的上下文传递到处理程序片段以在 Toast 消息中使用的正确方法是什么?

【问题讨论】:

    标签: android-fragments handler android-context android-toast


    【解决方案1】:

    Activity 本身就是一个上下文。而不是你尝试的所有事情,你应该

    • 不创建 static 处理程序 - 这就是您尝试通过 PlayFrets.this 失败的原因
    • PlayFrets.this 作为上下文传递
    • 无需调用runOnUiThread(),因为处理程序在当前情况下处理 UI 线程上的消息

    您的处理程序代码应如下所示:

    Handler mHandler = new Handler() {  
        public void handleMessage(final Message msg){ 
            if(msg.obj != null){
                       Toast.makeText(PlayFrets.this, "Background Thread sent "+  msg.what + " bytes: " + msg.obj,Toast.LENGTH_SHORT).show();
            }
            else{
            }
        }
    };
    

    【讨论】:

    • 你确定吗?我读过很多指南,例如androiddesignpatterns.com/2013/01/…,明确指出您应该避免使用非静态内部类来防止内存泄漏。此外,如果我的处理程序是非静态的,那么我从另一个类 (PlayFrets.mHandler.sendMessage()) 对它的调用将不起作用并给出以下错误:“无法对非静态字段 PlayFrets.mHandler 进行静态引用”。有没有办法让 Handler 保持静态?
    • 是的,我确定。至于另一个类的调用,把handler的实例传给另一个类,不要静态引用。
    • @Cody 我已经查看了您参考的指南,显然,该指南是有道理的。但是,您没有按照指南进行操作。例如,请注意指南中的MyHandler 类是静态的,但保存其实例的变量mHandler 不是静态的。对活动的引用在构造函数中传递给MyHandler,然后用作您正在寻找的上下文......但在所有这些之前,您应该问自己文章中描述的资源泄漏是否适用于您的案例。记住最重要的设计模式:越简单越好。
    • 泄漏的可能性适用于我的情况,因为我的工作线程不断向 UI 线程中的处理程序发送数据(在无限循环中),因此当主要活动被杀死时,它仍然是可能的如果 Looper que 中有来自工作线程的消息,则 Handler 会一直徘徊。 @您的第一条评论,我试过这个,它似乎有点工作,但它以不一致的方式干扰了我程序的其他元素。 AsyncTask 是否比使用线程/处理程序更适合我需要将常量数据发送到 UI 线程?
    • 它是否解决了您的问题:“将活动上下文传递给 Toast 的处理程序(片段)”?如果是这样,请将问题标记为已回答。如果资源泄漏适用于您,请使用上述指南中提出的方法,并将handler 保留在您的工作线程中的WeakReference 中。我认为 AsyncTask 是用线程实现的,所以它不应该有所作为。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多