0

嗨,我试图从 ScreenReceiver 类调用我的 mainactivity 中的方法。我发现了这一点并将其实现到我的代码中。

主要活动:

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ScreenRecv
        IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        BroadcastReceiver mReceiver = new ScreenReceiver();
        registerReceiver(mReceiver, filter);
    }

    // Toast(String)
    public void Toast(String text) {
        Toast.makeText(MainActivity.this, "" + text, Toast.LENGTH_SHORT).show();
    }
}

屏幕接收器:

package com.wifitimer;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class ScreenReceiver extends BroadcastReceiver {
    public static boolean wasScreenOn = true;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            new MainActivity().Toast("Screen Off");
            wasScreenOn = false;
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            new MainActivity().Toast("Screen On");
            wasScreenOn = true;
        }
    }
}

我没有收到任何错误,但 Toast 也没有显示。有任何想法吗?

日志猫:

04-16 00:53:35.470: I/WifiManager(19123): setWifiEnabled : true
04-16 00:53:57.135: D/AndroidRuntime(19123): Shutting down VM
04-16 00:53:57.135: W/dalvikvm(19123): threadid=1: thread exiting with uncaught exception (group=0x416922a0)
04-16 00:53:57.140: E/AndroidRuntime(19123): FATAL EXCEPTION: main
04-16 00:53:57.140: E/AndroidRuntime(19123): java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.SCREEN_OFF flg=0x50000010 } in com.wifitimer.ScreenReceiver@42312238
04-16 00:53:57.140: E/AndroidRuntime(19123):    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:765)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at android.os.Handler.handleCallback(Handler.java:615)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at android.os.Handler.dispatchMessage(Handler.java:92)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at android.os.Looper.loop(Looper.java:137)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at android.app.ActivityThread.main(ActivityThread.java:4898)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at java.lang.reflect.Method.invokeNative(Native Method)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at java.lang.reflect.Method.invoke(Method.java:511)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at dalvik.system.NativeStart.main(Native Method)
04-16 00:53:57.140: E/AndroidRuntime(19123): Caused by: java.lang.NullPointerException
04-16 00:53:57.140: E/AndroidRuntime(19123):    at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:101)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at com.wifitimer.MainActivity.Toast(MainActivity.java:107)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at com.wifitimer.ScreenReceiver.onReceive(ScreenReceiver.java:13)
04-16 00:53:57.140: E/AndroidRuntime(19123):    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:755)
04-16 00:53:57.140: E/AndroidRuntime(19123):    ... 9 more
04-16 00:53:57.445: I/Process(19123): Sending signal. PID: 19123 SIG: 9
4

3 回答 3

3

你的调用实际上不应该工作,因为你需要Context作为第一个参数提供给makeText. 而且由于您的类不是从 Context 或 Activity 或类似的东西派生的,它甚至不应该编译。

查看文档

现在显示您的代码,您当前遇到的问题是:

   new MainActivity().Toast("Screen Off");

你已经有一个实例化的 MainActivity,你不需要实例化一个新的。现在,如果你想使用第一个类的方法,你可以做的一件事是为你的 ScreenReceiver 添加一个构造函数

MainActivity myContext;
public ScreenReceiver(MainActivity context){
    myContext = context;
}

并在 onReceive 方法中将该行更改为

myContext.Toast("Screen Off");

并实例化您更改的类,您需要将该行更改为

BroadcastReceiver mReceiver = new ScreenReceiver(this);
于 2013-04-15T23:30:51.177 回答
0

您不能直接实例化活动。startActivity(this, B.class);在 A 内部使用并从 B 生命周期方法内部调用 methodB 。

编辑以匹配已编辑的问题:

如果你只想显示 Toast,BroadcastReceiver直接在里面做:

Toast.makeText(context, "Screen On/Off", Toast.LENGTH_SHORT).show();

如果您想在Activity创建您的组件()上调用一个函数BroadcastReceiver,最好添加回调接口并在其中实现,Activity通过构造函数发送(如 DigCamara 在他的回答中所说)或设置器发送到BroadcastReceiver并在需要时调用。

笔记:

  1. 你不直接实例ActivitiesServices。它根本行不通。
  2. 您需要BroadcastReceiver在匹配功能中取消注册(在您的情况下onDestroy)。
  3. 不要将数据保存在静态变量中:public static boolean wasScreenOn = true;. 进程被杀死并重新启动后,您将丢失此数据。
于 2013-04-15T23:38:29.810 回答
0

创建 Toast 时,第一个参数需要是 Context。因此,要么 B 需要是活动/服务/应用程序的子类,要么您需要将 B 的构造函数中的引用传递给有效的上下文。或者,您可以继承 Application 并提供静态 getContext 方法。

于 2013-04-15T23:31:34.740 回答