2016-07-23 88 views
0

所有JNI检测到的错误应用:不能调用无效android.graphics.Canvas.drawBitmap

我尝试写使用JNI这个代码,但没有任何工程。任何建议?

extern "C" 
{ 

JNIEXPORT void JNICALL Java_com_example_hellojni_HelloView_drawingBitmap(JNIEnv *env, jfloat width, jfloat height, jobject canvas, jobjectRefType paint); 

} 

class JniBitmap 
{ 
public: 
    uint32_t* _storedBitmapPixels; 
    AndroidBitmapInfo _bitmapInfo; 
    JniBitmap() 
    { 
     _storedBitmapPixels = NULL; 
    } 
}; 

JniBitmap *jniBitmap = new JniBitmap(); 

JNIEXPORT void JNICALL Java_com_example_hellojni_HelloView_drawingBitmap(JNIEnv *env, jfloat width, jfloat height, jobject canvas, jobjectRefType paint){ 

jclass getcanvasClass = env -> FindClass("android/graphics/Canvas"); 
    jmethodID drawBitmapFunction = env->GetMethodID(getcanvasClass, "drawBitmap", "(Landroid/graphics/Bitmap;FFLandroid/graphics/Paint;)V"); 

    env-> CallVoidMethod(getcanvasClass, drawBitmapFunction, jniBitmap->_storedBitmapPixels, width, height, paint); 


} 

日志:

[ 07-23 13:22:44.849 24629:24890 D/   ] 
                   ro.exynos.dss isEnabled: 0 
07-23 13:22:44.849 24629-24890/com.example.hellojni D/mali_winsys: new_window_surface returns 0x3000, [1440x2560]-format:1 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] 

JNI DETECTED ERROR IN APPLICATION: can't call void android.graphics.Canvas.drawBitmap(android.graphics.Bitmap, float, float, android.graphics.Paint) on instance of java.lang.Class<android.graphics.Canvas> 


07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410]  in call to CallVoidMethodV 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410]  from void com.example.hellojni.HelloView.drawingBitmap(float, float, android.graphics.Canvas, android.graphics.Paint) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] "Thread-1691" prio=5 tid=10 Runnable 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] | group="main" sCount=0 dsCount=0 obj=0x12c84940 self=0x7faba89a00 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] | sysTid=24889 nice=0 cgrp=default sched=0/0 handle=0x7fabbfd440 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] | state=R schedstat=(57509155 44992191 10) utm=5 stm=0 core=4 HZ=100 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] | stack=0x7fabafb000-0x7fabafd000 stackSize=1037KB 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] | held mutexes= "mutator lock"(shared held) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #00 pc 000000000048a5b0 /system/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, BacktraceMap*, char const*, art::ArtMethod*, void*)+200) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #01 pc 0000000000459358 /system/lib64/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, BacktraceMap*) const+224) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #02 pc 000000000030d764 /system/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+1004) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #03 pc 000000000030e01c /system/lib64/libart.so (art::JavaVMExt::JniAbortV(char const*, char const*, std::__va_list)+116) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #04 pc 000000000014217c /system/lib64/libart.so (art::ScopedCheck::AbortF(char const*, ...)+144) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #05 pc 0000000000142574 /system/lib64/libart.so (art::ScopedCheck::CheckMethodAndSig(art::ScopedObjectAccess&, _jobject*, _jclass*, _jmethodID*, art::Primitive::Type, art::InvokeType)+724) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #06 pc 000000000015bc58 /system/lib64/libart.so (art::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, std::__va_list, art::Primitive::Type, art::InvokeType)+724) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #07 pc 000000000015def8 /system/lib64/libart.so (art::CheckJNI::CallVoidMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+68) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #08 pc 00000000000013a0 /data/app/com.example.hellojni-2/lib/arm64/libJniBitmapOperations.so (_JNIEnv::CallVoidMethod(_jobject*, _jmethodID*, ...)+192) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #09 pc 00000000000/data/app/com.example.hellojni-2/lib/arm64/libJniBitmapOperations.so (Java_com_example_hellojni_HelloView_drawingBitmap+200) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #10 pc 0000000000003ae0 /data/app/com.example.hellojni-2/oat/arm64/base.odex (void com.example.hellojni.HelloView.drawingBitmap(float, float, android.graphics.Canvas, android.graphics.Paint)+196) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #11 pc 000000000000397c /data/app/com.example.hellojni-2/oat/arm64/base.odex (void com.example.hellojni.HelloView.draw()+624) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #12 pc 0000000000003e10 /data/app/com.example.hellojni-2/oat/arm64/base.odex (void com.example.hellojni.HelloView.run()+132) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] native: #13 pc 0000000002f4e654 /system/framework/arm64/boot.oat (???) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] at com.example.hellojni.HelloView.drawingBitmap(Native method) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] at com.example.hellojni.HelloView.draw(HelloView.java:80) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] at com.example.hellojni.HelloView.run(HelloView.java:48) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] at java.lang.Thread.run(Thread.java:818) 
07-23 13:22:44.869 24629-24889/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] 
07-23 13:22:44.899 24629-248 

当我调试是该线路上的错误:

env-> CallVoidMethod(getcanvasClass, drawBitmapFunction, jniBitmap->_storedBitmapPixels, width - jniBitmap->_bitmapInfo.width/2, 
               height - jniBitmap->_bitmapInfo.height/2, paint); 

但是,为什么,因为相同的码型使用“机器人,我不知道/图形/位图“,并调用createBitmap方法工作正常。

感谢您的高级帮助。

我改变这样的代码:

JNIEXPORT void JNICALL 
Java_com_example_hellojni_JniBitmapHolder_drawingBitmap(JNIEnv *env, jfloat width, jfloat height, jobject canvas, jobject paint) { 

    // TODO 
    jclass getcanvasClass = env-> GetObjectClass(canvas); 
    jmethodID drawBitmapFunction = env -> GetMethodID(getcanvasClass, "drawBitmap", "(Landroid/graphics/Bitmap;FFLandroid/graphics/Paint;)V"); 


    env -> CallVoidMethod(canvas, drawBitmapFunction, jniBitmap->_storedBitmapPixels, width - jniBitmap->_bitmapInfo.width/2, 
         height - jniBitmap->_bitmapInfo.height/2, paint); 


} 

日志:

07-23 21:44:41.539 17369-17369/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: can't call void android.graphics.Canvas.drawBitmap(android.graphics.Bitmap, float, float, android.graphics.Paint) on instance of java.lang.Class<android.graphics.Canvas> 
07-23 21:44:41.539 17369-17369/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410]  in call to CallVoidMethodV 
07-23 21:44:41.539 17369-17369/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410]  from void com.example.hellojni.JniBitmapHolder.drawingBitmap(float, float, android.graphics.Canvas, android.graphics.Paint) 
07-23 21:44:41.539 17369-17369/com.example.hellojni A/art: art/runtime/java_vm_ext.cc:410] "main" prio=5 tid=1 Runnable 

还是同样的错误。

回答

1

您需要一个android.graphics.Canvas的实例来执行调用drawBitmap()。此方法不是静态方法,因此它需要一个对象,而不是对象的“类”。

令人困惑的部分是,在Java中,对象的类是java.lang.CLass<>类型的对象。在你的情况下,getcanvasClass变量是java.lang.Class<android.graphics.Canvas>类型。您始终可以从对象转到类对象(例如env->GetObjectClass(object)),但如果只知道它属于哪个类,通常无法找到对象。

底线是你的方法需要一个实际的画布对象来绘制位图。您可能可以在Java中获得这样的对象,并将其传递给本地方法。

+0

谢谢你的想法,但错误仍然存​​在。你能帮助一些示例代码先生吗?谢谢 –

+0

你的C++代码现在看起来不错。有什么可能出错?最有可能的是,你的apk仍然使用旧图书馆。添加一些日志语句来验证这一点。调用'JniBitmapHolder.drawingBitmap()'的Java方面不太可能,是不正确的。 –

相关问题