Android - Toast 调用上的空指针
Android - Null pointer on Toast call
我有一个 服务,它通过 JNI 调用 C 函数。然后这个函数生成一个 pthread
并将它附加到 JVM。我从这个 pthread
调用一个 Java 方法,它应该 post 一个 Toast
通知。不幸的是,一旦调用 Toast
通知,我就会收到 空指针异常 。
这是在我的服务中处理 Toast
调用的方法 class:
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 不为空时它才会崩溃。
尝试一下,如果不起作用,请检查 msg 之前是否为空。你可以这样做。
if (msg.equals(null){
msg = "Variable was null";
}
Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT).show();
顺便说一句,我忘了考虑你可能不明白这意味着什么。
如果您在 运行 您的应用程序时收到 toast 消息 Variable was null。这意味着无论方法调用来自何处,都会发送一个空字符串。您需要找到方法调用并弄清楚为什么它传递的变量为空。
例如,在您的项目中搜索此 showToast(
搜索那个电话,搜索多少次就搜索多少次。如果有多个调用,您可以在每次调用之前检查字符串,如果它为空,您可以添加一个字符串来帮助您识别调用的来源。您可以使用我在每次调用之前放在上面的代码,而是检查发送的变量。然后使它等于 "call from xxxxx is null""" xxxx 是调用的位置。那么你可以弄清楚为什么发送的变量为空。
也试试我说的用 getApplicationContext() 而不是 MyContext
问题是,当通过 JNI 从 C 线程调用时,我们无法获取上下文。我们必须从服务线程本身获取上下文。为此:
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 的调用访问该上下文
我有一个 服务,它通过 JNI 调用 C 函数。然后这个函数生成一个 pthread
并将它附加到 JVM。我从这个 pthread
调用一个 Java 方法,它应该 post 一个 Toast
通知。不幸的是,一旦调用 Toast
通知,我就会收到 空指针异常 。
这是在我的服务中处理 Toast
调用的方法 class:
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 不为空时它才会崩溃。
尝试一下,如果不起作用,请检查 msg 之前是否为空。你可以这样做。
if (msg.equals(null){
msg = "Variable was null";
}
Toast.makeText(MyContext, msg, Toast.LENGTH_SHORT).show();
顺便说一句,我忘了考虑你可能不明白这意味着什么。
如果您在 运行 您的应用程序时收到 toast 消息 Variable was null。这意味着无论方法调用来自何处,都会发送一个空字符串。您需要找到方法调用并弄清楚为什么它传递的变量为空。
例如,在您的项目中搜索此 showToast(
搜索那个电话,搜索多少次就搜索多少次。如果有多个调用,您可以在每次调用之前检查字符串,如果它为空,您可以添加一个字符串来帮助您识别调用的来源。您可以使用我在每次调用之前放在上面的代码,而是检查发送的变量。然后使它等于 "call from xxxxx is null""" xxxx 是调用的位置。那么你可以弄清楚为什么发送的变量为空。
也试试我说的用 getApplicationContext() 而不是 MyContext
问题是,当通过 JNI 从 C 线程调用时,我们无法获取上下文。我们必须从服务线程本身获取上下文。为此:
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 的调用访问该上下文