【问题标题】:Call method in another method?在另一个方法中调用方法?
【发布时间】:2013-04-15 23:14:40
【问题描述】:

您好,我尝试从 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 也没有显示。有什么想法吗?

LogCat:

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

【问题讨论】:

  • 重构您的代码以显示您真正使用的组件。如果没有这些信息,您的问题会令人困惑。
  • 我已经添加了上面的完整代码:)

标签: android class methods


【解决方案1】:

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

看看documentation

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

   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);

【讨论】:

  • B 是 mainactivity 的子类
  • 即便如此。您需要将“this”更改为 MainActivity.this 才能使您的代码正常工作。 (当然取决于你的课程名称)
  • 嘿,谢谢伙计。我刚刚尝试了您的建议,但仍然无法正常工作。我在上面的主帖中添加了 LogCat。
【解决方案2】:

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

【讨论】:

  • B 是 mainactivity 的子类
  • 请不要建议创建静态 getContext 方法。这是意大利面条代码的良好开端。
  • 我已经添加了上面的完整代码。我将 MainActivity.this 添加到 toast 中,但仍然无法正常工作。
【解决方案3】:

你不能直接实例化活动。在 A 中使用 startActivity(this, B.class); 并从 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;。进程被终止并重新启动后,您将丢失这些数据。

【讨论】:

    猜你喜欢
    • 2015-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    相关资源
    最近更新 更多