Android - Toast调用上的空指针

时间:2016-07-04 20:53:16

标签: 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.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)

2 个答案:

答案 0 :(得分:0)

试试这个:

Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT).show();

我是如何做到的,只有当msg不为空时它才会崩溃。

尝试一下,如果没有工作,请检查msg是否为null。你可以这样做。

if (msg.equals(null){
msg = "Variable was null";
}
Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT).show();

顺便说一下,我忘了考虑你可能得不到这意味着什么。

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

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

尽可能多地搜索该电话。如果有多个呼叫,您可以在每次呼叫之前检查字符串,如果它是空的,您可以添加一个字符串,以帮助您识别呼叫的来源。您可以在每次调用之前使用上面的代码,但检查发送的变量。然后使它相等"来自xxxxx的呼叫为空""" xxxx是进行呼叫的位置。然后你可以弄清楚为什么发送的变量为空。

也尝试使用getApplicationContext()代替MyContext

答案 1 :(得分:0)

问题在于,当从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的调用访问正确的上下文的静态引用