我有服务,它通过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)
答案 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的调用访问正确的上下文的静态引用