Android 在另一个方法中调用方法?

Android 在另一个方法中调用方法?,android,class,methods,Android,Class,Methods,嗨,我试图从ScreenReceiver类调用mainactivity中的一个方法。我发现了这一点,并将其实现到我的代码中 主要活动: public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R

嗨,我试图从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;
        }
    }
}
我没有收到任何错误,但是祝酒词也没有显示出来。有什么想法吗

日志:

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

您的调用实际上不应该起作用,因为您需要将
Context
作为
makeText
的第一个参数输入。由于您的类不是从上下文、活动或类似的东西派生的,所以它甚至不应该编译

看这张照片

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

   new MainActivity().Toast("Screen Off");
您已经有一个实例化的MainActivity,不需要实例化新的MainActivity。现在,如果您想使用第一个类的方法,您可以做的一件事是为ScreenReceiver添加一个构造函数

MainActivity myContext;
public ScreenReceiver(MainActivity context){
    myContext = context;
}
在onReceive方法中,将该行更改为

myContext.Toast("Screen Off");
BroadcastReceiver mReceiver = new ScreenReceiver(this);
要实例更改后的类,需要将该行更改为

myContext.Toast("Screen Off");
BroadcastReceiver mReceiver = new ScreenReceiver(this);

您的调用实际上不应该起作用,因为您需要将
Context
作为
makeText
的第一个参数输入。由于您的类不是从上下文、活动或类似的东西派生的,所以它甚至不应该编译

看这张照片

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

   new MainActivity().Toast("Screen Off");
您已经有一个实例化的MainActivity,不需要实例化新的MainActivity。现在,如果您想使用第一个类的方法,您可以做的一件事是为ScreenReceiver添加一个构造函数

MainActivity myContext;
public ScreenReceiver(MainActivity context){
    myContext = context;
}
在onReceive方法中,将该行更改为

myContext.Toast("Screen Off");
BroadcastReceiver mReceiver = new ScreenReceiver(this);
要实例更改后的类,需要将该行更改为

myContext.Toast("Screen Off");
BroadcastReceiver mReceiver = new ScreenReceiver(this);

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

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

您不能直接实例化活动。使用
startActivity(本,B类)在A中,并从B生命周期方法中调用方法B

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

如果您只想展示Toast,请直接在
BroadcastReceiver
中进行:

Toast.makeText(context, "Screen On/Off", Toast.LENGTH_SHORT).show();
如果您想调用组件(
Activity
)上的函数,该组件创建了您的
BroadcastReceiver
,最好添加回调接口并在
Activity
中实现,通过构造函数(如DigCamara在回答中所说)或setter发送到
BroadcastReceiver
,并在需要时调用

注:

  • 您不会直接实例化
    活动
    服务
    。它根本不起作用
  • 您需要在匹配函数中注销
    BroadcastReceiver
    (在您的情况下是
    ondestory
  • 不要将数据保存在静态变量中:
    publicstaticboolearnwasscreenon=true。进程终止并重新启动后,您将丢失此数据
  • 不能直接实例化活动。使用
    startActivity(本,B类)在A中,并从B生命周期方法中调用方法B

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

    如果您只想展示Toast,请直接在
    BroadcastReceiver
    中进行:

    Toast.makeText(context, "Screen On/Off", Toast.LENGTH_SHORT).show();
    
    如果您想调用组件(
    Activity
    )上的函数,该组件创建了您的
    BroadcastReceiver
    ,最好添加回调接口并在
    Activity
    中实现,通过构造函数(如DigCamara在回答中所说)或setter发送到
    BroadcastReceiver
    ,并在需要时调用

    注:

  • 您不会直接实例化
    活动
    服务
    。它根本不起作用
  • 您需要在匹配函数中注销
    BroadcastReceiver
    (在您的情况下是
    ondestory
  • 不要将数据保存在静态变量中:
    publicstaticboolearnwasscreenon=true。进程终止并重新启动后,您将丢失此数据

  • B是MainActivity的一个子类,尽管如此。您需要将“this”更改为MainActivity.this才能使代码正常工作。(当然,这取决于你们班的名字)嘿,谢谢你,伙计。我刚试过你的建议,但还是不管用。我在上面的主帖子中添加了LogCat。B是mainActivity的子类。您需要将“this”更改为MainActivity.this才能使代码正常工作。(当然,这取决于你们班的名字)嘿,谢谢你,伙计。我刚试过你的建议,但还是不管用。我在上面的主要帖子中添加了LogCat。B是mainactivityPlease的子类,不建议创建静态getContext方法。这是一个很好的开始,我已经在上面添加了完整的代码。我将MainActivity.this添加到toast中,但仍然不起作用。B是mainactivityPlease的子类,请不要建议创建静态getContext方法。这是一个很好的开始,我已经在上面添加了完整的代码。我将MainActivity.this添加到toast中,但仍然不起作用。重构代码以显示您真正使用的组件。如果没有这些信息,你的问题会让人困惑。我已经添加了上面的完整代码:)重构你的代码,以显示你真正使用的组件。没有这些信息,您的问题令人困惑。我已添加了上面的完整代码:)