2012-03-13 58 views
0

我有一个BroadcastReceiver作为单独的类文件,在后台监听来自服务的传感器动作。我希望它在Occassions上的屏幕上显示文字。不允许调用我自己的方法(“静态”之谜)

我想让BroadcastClass在我的Activity类中调用一个方法,该方法负责显示字符串。但我的广播接收器类不能调用它们不是静态的(?)“不能让一个静态引用从类型myActivity非静态方法showString(字符串)”

方法如果我做的特定方法静态的,我的Activity类,它没有找到findViewById,它有效地失去了与它自己的活动的UI的联系“无法对类型为Activity的非静态方法findViewById(int)进行静态引用。

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

创建活动的实例意味着什么?我应该在活动本身还是在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; 
    } 

回答

1

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


您不能将Activity本身作为singelton对象。 Androud必须有权访问构造函数。更好地实现一个Application,它就像你的应用程序的singelton对象。

你必须将其申报为您的清单如下:

<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()访问该应用程序实例。

这是一个更大的例子:

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

请注意,您Application类在这里被称为MySingeltonClass

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

在任何你对你的应用程序的活动,你可以通过这个代码调用函数doSomething()有自己的上下文,以便您可以调用afik每个需要上下文的函数。

+0

是什么意思创建活动的实例?我应该在活动本身还是在BroadcastReceiver中执行此操作?我不想要一个以上的UI实例,但我可能需要从几个不同的类访问它。 – Tombola 2012-03-13 12:47:53

+0

您需要调用新的ClassName()。比你有一个合作的实例。 – rekire 2012-03-13 12:49:26

+0

每当我这样做时,我不会得到一个新实例吗?例如我的BroadcastReceiver类工作的Activity的一个实例,以及我的Service类工作的另一个实例。当应用程序与Activity一起启动时,它是否是第三个实例? – Tombola 2012-03-13 12:57:14

2

你必须添加一个字段为活动对象在你的广播接收器类,像这样:

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

编辑:如果你不想每创建一次就可以安装接收器,您可以(例如)引入一个设置器到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); 

     // ... 
    } 
} 
+0

好吧,现在它几乎是有道理的。但是你似乎安装了BroadcastReceiver,而不是Activity。每次调用Activity.onCreate时都不会实例化一个新的MyBroadcastReceiver(就像打开手机屏幕一样)?或者通过每个活动它需要访问(作为用户切换屏幕)? – Tombola 2012-03-13 13:08:32

+0

请参阅我的编辑 - 如果您有多个活动,则必须为变量'receiver'找到另一个地方 – hjhill 2012-03-13 22:28:34