Android-Toast调用上的空指针

Android-Toast调用上的空指针,android,service,nullpointerexception,java-native-interface,toast,Android,Service,Nullpointerexception,Java Native Interface,Toast,我有一个服务,它通过JNI调用C函数。然后,该函数生成一个pthread,并将其附加到JVM。我从这个pthread调用了一个Java方法,它应该发出Toast通知。不幸的是,只要调用Toast通知,就会出现空指针异常 下面是在我的服务类中处理Toast调用的方法: public void showToast(final String msg) { final Context MyContext = this; Handler h = new Handler(MyContext.

我有一个服务,它通过JNI调用C函数。然后,该函数生成一个
pthread
,并将其附加到JVM。我从这个
pthread
调用了一个Java方法,它应该发出
Toast
通知。不幸的是,只要调用
Toast
通知,就会出现空指针异常

下面是在我的服务类中处理
Toast
调用的方法:

public void showToast(final String msg) {
    final Context MyContext = this;
    Handler h = new Handler(MyContext.getMainLooper());
    h.post(new Runnable() {
        @Override
        public void run() {
            Toast myToast = Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT);
            myToast.show();
        }
    });
}
什么可能导致空指针异常,以及如何修复它

是否试图从C函数获取上下文失败

这是错误消息

W/dalvikvm( 4010): JNI WARNING: JNI method called with exception pending
W/dalvikvm( 4010):              in Ldalvik/system/NativeStart;.run:()V (CallVoidMethod)
W/dalvikvm( 4010): Pending exception is:
I/dalvikvm( 4010): java.lang.NullPointerException:
I/dalvikvm( 4010):  at android.content.ContextWrapper.getMainLooper(ContextWrapper.java:104)
使用
getApplicationContext

I/dalvikvm( 6242): java.lang.NullPointerException:
I/dalvikvm( 6242):  at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:109)
试试这个:

Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT).show();
我一直都是这样做的,只有当msg不为null时,它才会崩溃

试一试,如果这不起作用,检查msg是否为空。你可以这样做

if (msg.equals(null){
msg = "Variable was null";
}
Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT).show();
顺便说一下,我忘了你可能不明白这意味着什么。

如果在运行应用程序时收到toast消息变量为空。这意味着无论方法调用来自何处,都会发送空字符串。您需要找到方法调用并找出它传递的变量为null的原因

例如,在您的项目中搜索此showToast(

搜索该调用,搜索次数与调用次数相同。如果有多个调用,则可以在每次调用前检查字符串,如果字符串为空,则可以添加一个字符串,以帮助您识别调用的来源。您可以使用我在每次调用前输入的代码,但改为检查发送的变量。然后使其相等“来自xxxxx的调用为null”“”xxxx是进行调用的位置。然后您可以找出发送的变量为null的原因

还可以用getApplicationContext()而不是MyContext来尝试我所说的方法尝试以下操作:

Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT).show();
我一直都是这样做的,只有当msg不为null时,它才会崩溃

试试看,如果这不起作用,请检查msg是否为null。您可以这样做

if (msg.equals(null){
msg = "Variable was null";
}
Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT).show();
顺便说一下,我忘了你可能不明白这意味着什么。

如果在运行应用程序时收到toast消息变量为null。这意味着无论方法调用来自何处,都会发送null字符串。您需要找到方法调用,并找出它传递的变量为null的原因

例如,在您的项目中搜索此showToast(

搜索该调用,搜索次数与调用次数相同。如果有多个调用,则可以在每次调用前检查字符串,如果字符串为空,则可以添加一个字符串,以帮助您识别调用的来源。您可以使用我在每次调用前输入的代码,但改为检查发送的变量。然后使其相等“来自xxxxx的调用为空“”“xxxx是进行调用的位置。然后您可以找出发送的变量为空的原因


请尝试我用getApplicationContext()而不是MyContext所说的方法。问题是,当从C线程通过JNI调用时,我们无法获取上下文。我们必须从服务线程本身获取上下文。为此:

public class MyService extends Service{
    private static Context MyContext; /* get context to use when displaying toast from JNI*/

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void onDestroy() {
    }

    @Override
    public int onStartCommand(Intent intent,int flags, int startid){
        MyContext = getApplicationContext();
        // do what you need to
        return START_STICKY;
    }

    public void showToast(final String msg) {
        Handler h = new Handler(MyContext.getMainLooper());
        h.post(new Runnable() {
            @Override
            public void run() {
            Toast myToast = Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT);
            myToast.show();
            }
        });
    }
}

这样,我们就有了一个对适当上下文的静态引用,我们可以通过JNI调用来访问该上下文。问题是,当从C线程通过JNI调用时,我们无法获取上下文。我们必须从服务线程本身获取上下文。为此:

public class MyService extends Service{
    private static Context MyContext; /* get context to use when displaying toast from JNI*/

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void onDestroy() {
    }

    @Override
    public int onStartCommand(Intent intent,int flags, int startid){
        MyContext = getApplicationContext();
        // do what you need to
        return START_STICKY;
    }

    public void showToast(final String msg) {
        Handler h = new Handler(MyContext.getMainLooper());
        h.post(new Runnable() {
            @Override
            public void run() {
            Toast myToast = Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT);
            myToast.show();
            }
        });
    }
}

这样,我们就有了一个对正确上下文的静态引用,我们可以通过JNI的调用来访问它

您能发布准确的错误消息吗?您是否尝试过使用getApplicationContext()而不是
This
?是的。您应该使用getApplicationContext()作为前面提到的@ρƏσѕρєK。谢谢,但是使用
getApplicationContext()
我有同样的error@StephanGM:表示服务未运行,这就是为什么双向提供无效的上下文。您可以发布准确的错误消息吗?您是否尝试使用getApplicationContext()而不是
?是的。您应该使用getApplicationContext(),如前所述的@ρцσѕρєK。谢谢,但使用
getApplicationContext()
我有同样的error@StephanGM:表示服务未运行这就是为什么双向提供无效的上下文不是空字符串而是上下文不是空字符串而是上下文