【问题标题】:Not allowed to call my own methods ("static" mystery)不允许调用我自己的方法(“静态”之谜)
【发布时间】:2012-03-29 20:32:09
【问题描述】:

我有一个 BroadcastReceiver 作为单独的类文件,在后台监听来自服务的传感器操作。我希望它偶尔在屏幕上显示文本。

我希望 BroadcastClass 在我的 Activity 类中调用一个方法来处理要显示的字符串。但是我的 BroadcastReceiver 类无法调用非静态方法(?)“无法从 myActivity 类型对非静态方法 showString(String) 进行静态引用”

如果我在我的 Activity 类中将特定方法设为静态,它会通过不再找到 findViewById 来有效地失去与自己 Activity 的 UI 的联系“无法对非静态方法 findViewById(int ) 来自类型 Activity"。

在另一个小应用程序中,我有一个 BroadcastReceiver 作为 Activity 类文件中的内部类。然后我直接从它访问 UI 没有问题。然后我将相关视图声明为类文件字段。但我想更好地构建事物,将 UI 与广播接收和分析分开。将整个应用程序源代码放在同一个文件中会变得非常混乱。

创建 Activity 的实例是什么意思?我应该在 Activity 本身还是在 BroadcastReceiver 中这样做?我不想要多个 UI 实例,但我可能需要从几个不同的类访问它。

编辑添加: 我从书中尝试了这种单例模式,但无法实例化 myActivity,不允许访问构造函数。输入 onCreate 前崩溃:

public class MyStartupActivity extends Activity {
    private static MyStartupActivity uniqueInstance;
    private MyStartupActivity() {}
    public static MyStartupActivity instantiate() {
        if (uniqueInstance == null) {
            uniqueInstance = new MyStartupActivity();
        }
        return uniqueInstance;
    }

【问题讨论】:

    标签: android methods static scope


    【解决方案1】:

    您必须在 BroadcastReceiver 类中为 Activity 对象添加一个字段,如下所示:

    class MyBroadcastReceiver extends BroadcastReceiver {
        private final Activity activity;
    
        public MyBroadcastReceiver(Activity activity) {
            this.activity = activity;
        }
    
        public void onReceive(...) {
            View v = activity.findViewById(ID);
            // ...
        }
    }
    

    像这样初始化它

    class MyActivity extends Activity {
        public void onCreate(...) {
            MyBroadcastReceiver receiver = new MyBroadcastReceiver(this);
            // ...
        }
    }
    

    编辑:如果您不想在每次创建 Activity 时都将接收器实例化,您可以(例如)向 MyBroadcastReceiver 引入一个设置器:

    class MyBroadcastReceiver extends BroadcastReceiver {
        private Activity activity;
    
        public void setActivity(Activity activity) {
            this.activity = activity;
        }
    
        public void onReceive(...) {
            if (activity != null) {
                View v = activity.findViewById(ID);
                // ...
            } else {
                // we don't have an activity, do whatever you can do without it...
            }
            // ...
        }
    }
    

    并在活动中使用它:

    class MyActivity extends Activity {
        private static MyBroadcastReceiver receiver;
    
        public void onCreate(...) {
            if (receiver == null) {
                receiver = new MyBroadcastReceiver();
                // ...
            }
            receiver.setActivity(this);
    
            // ...
        }
    }
    

    【讨论】:

    • 好的,现在几乎说得通了。但是您似乎设置了 BroadcastReceiver,而不是 Activity。每次调用 Activity.onCreate 时不会实例化一个新的 MyBroadcastReceiver 吗(比如转动手机屏幕时)?还是通过它需要访问的每个 Activity(当用户切换屏幕时)?
    • 查看我的编辑 - 如果您有多个活动,则必须为变量 receiver 找到另一个位置
    【解决方案2】:

    您需要一个类的实例来将该非静态函数调用到您的静态函数中。


    您不能将Activity 本身作为一个单例对象。 Androud 必须有权访问构造函数。更好地为您的应用实现一个Application,它类似于一个单例对象。

    你必须像这样在你的清单中声明它:

    <manifest package="your.personal.package">
    ...
      <application android:label="@string/app_name"
                   android:icon="@drawable/icon"
                   android:description="@string/desc"
                   android:name=".MySingeltonClass"
                   android:debuggable="true">
        ...
    

    在您的应用中,您可以通过调用 getApplicationContext() 来访问该应用实例。

    这是一个更大的例子:

    public class MySingeltonClass extends Application {
        public void doSomething() { ... }
    }
    

    在您应用的任何活动中,您都可以通过以下代码调用函数doSomething()

    ((MySingeltonClass)getApplicationContext()).doSomething();
    

    请注意,您的 Application 类在这里称为 MySingeltonClass 有自己的上下文,因此您可以调用 afik 每个需要上下文的函数。

    【讨论】:

    • 创建一个Activity的实例是什么意思?我应该在 Activity 本身还是在 BroadcastReceiver 中这样做?我不想要多个 UI 实例,但我可能需要从几个不同的类访问它。
    • 你需要调用 new ClassName()。比你有一个实例可以使用。
    • 每次我这样做时不会得到一个新实例吗?例如,我的 BroadcastReceiver 类使用的 Activity 的一个实例,以及我的 Service 类使用的另一个实例。当应用程序与 Activity 一起启动时,它是否是第三个实例?
    • 对不起,我在火车上耽搁了......您可以通过构造函数或使用单格盘来保存实例。
    • 我从书中尝试了这种单例模式,但无法实例化 myActivity,不允许访问构造函数:请参阅问题帖子中的编辑 public class MyStartupActivity extends Activity { private static MyStartupActivity uniqueInstance;私有 MyStartupActivity() {} 公共静态 MyStartupActivity 实例化() { if (uniqueInstance == null) { uniqueInstance = new MyStartupActivity(); } 返回唯一实例; }
    猜你喜欢
    • 2011-11-25
    • 1970-01-01
    • 2011-12-11
    • 2015-04-09
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    相关资源
    最近更新 更多