Ich benutze die superpoweredAdvancedAudioPlayer um MP3s auf Android zu spielen. Ich möchte eine Suchleiste verwenden, um den Fortschritt während der Wiedergabe der Datei anzuzeigen. Mein Plan war, das Attribut positionPercent
des Players einmal pro Sekunde mit einem Runnable auf der Java-Seite zu erhalten und die Suchleiste mit dem Ergebnis zu aktualisieren. Ich habe viele verschiedene Ansätze ausprobiert, aber alle haben zu Abstürzen geführt, entweder mit einem SIGILL oder nur mit einer Benachrichtigung auf dem Emulator, dass "xxx leider gestoppt hat". (xxx ist der Name der App.)Superpowered Android NDK: Holen Sie sich PositionPercent zu aktualisieren Audio Fortschritt seekbar
Hier ist mein letzter Versuch.
Java-Code:
private int timeSliderInterval = 1000; // 1 second
Runnable doUpdateTimeSlider;
final Handler timeSliderHandler = new Handler();
void startUpdateTimeSlider() {
doUpdateTimeSlider.run();
}
void stopUpdateTimeSlider() {
timeSliderHandler.removeCallbacks(doUpdateTimeSlider);
}
@Override
public void onDestroy() {
super.onDestroy();
stopUpdateTimeSlider();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);;
doUpdateTimeSlider = new Runnable() {
@Override
public void run() {
updateTimeSlider();
timeSliderHandler.postDelayed(this, timeSliderInterval);
}
void updateTimeSlider() {
float pp;
// this is where problems begin!
pp = getPositionPercent();
int ppint = (int) (pp*100);
timeSlider.setProgress(ppint);
}
};
private native int getPositionPercent();
C++ Code:
float SuperpoweredExample::getPositionPercent() {
float pp = 0.01f;
pp = player1->positionPercent;
return pp; }
extern "C" JNIEXPORT jint Java_org_irthlingz_ChoirherenceA3_PlayActivity_getPositionPercent(JNIEnv * __unused javaEnvironment, jobject __unused obj) {
example->getPositionPercent();
}
Die App erstellt und startet ohne Fehler. Aber wenn ich an den Ort komme, der SuperpoweredExample::getPositionPercent
ausführen würde, stürzt es ab.
Der ausführbare Teil selbst funktioniert. Aber sobald ich versuche, die PositionPercent zu bekommen, bekomme ich einen Absturz der einen oder anderen Art.
Eine andere Sache: Wenn ich den gecastet in einem int und Zeile es folgenden Kommentar aus:
int ppint = (int) (pp*100);
timeSlider.setProgress(ppint);
ich noch eine SIGILL bekommen. Also diese Zeilen sind an dieser Stelle nicht das Problem.
Irgendwelche Gedanken? Hier
ist ein stacktrace:
Signal = SIGILL (signal SIGILL: illegal instruction operand)
javaEnvironment = {JNIEnv * | 0xb4059a80} 0xb4059a80
[0] = {JNIEnv}
functions = {const JNINativeInterface * | 0xb3fb2a40} 0xb3fb2a40
[0] = {const JNINativeInterface}
reserved0 = {void * | 0x0} nil
reserved1 = {void * | 0x0} nil
reserved2 = {void * | 0x0} nil
reserved3 = {void * | 0x0} nil
GetVersion = {jint (*)(JNIEnv *) | 0xb39d05f5} (libart.so`art::CheckJNI::GetVersion(_JNIEnv*))
DefineClass = {jclass (*)(JNIEnv *, const char *, jobject, const jbyte *, jsize) | 0xb39d1ad0} (libart.so`art::CheckJNI::DefineClass(_JNIEnv*, char const*, _jobject*, signed char const*, int))
FindClass = {jclass (*)(JNIEnv *, const char *) | 0xb39d1f8c} (libart.so`art::CheckJNI::FindClass(_JNIEnv*, char const*))
FromReflectedMethod = {jmethodID (*)(JNIEnv *, jobject) | 0xb39d2c2f} (libart.so`art::CheckJNI::FromReflectedMethod(_JNIEnv*, _jobject*))
FromReflectedField = {jfieldID (*)(JNIEnv *, jobject) | 0xb39d31b4} (libart.so`art::CheckJNI::FromReflectedField(_JNIEnv*, _jobject*))
ToReflectedMethod = {jobject (*)(JNIEnv *, jclass, jmethodID, jboolean) | 0xb39d36f0} (libart.so`art::CheckJNI::ToReflectedMethod(_JNIEnv*, _jclass*, _jmethodID*, unsigned char))
GetSuperclass = {jclass (*)(JNIEnv *, jclass) | 0xb39d23d8} (libart.so`art::CheckJNI::GetSuperclass(_JNIEnv*, _jclass*))
IsAssignableFrom = {jboolean (*)(JNIEnv *, jclass, jclass) | 0xb39d27f0} (libart.so`art::CheckJNI::IsAssignableFrom(_JNIEnv*, _jclass*, _jclass*))
ToReflectedField = {jobject (*)(JNIEnv *, jclass, jfieldID, jboolean) | 0xb39d3b50} (libart.so`art::CheckJNI::ToReflectedField(_JNIEnv*, _jclass*, _jfieldID*, unsigned char))
Throw = {jint (*)(JNIEnv *, jthrowable) | 0xb39d3fb0} (libart.so`art::CheckJNI::Throw(_JNIEnv*, _jthrowable*))
ThrowNew = {jint (*)(JNIEnv *, jclass, const char *) | 0xb39d44c0} (libart.so`art::CheckJNI::ThrowNew(_JNIEnv*, _jclass*, char const*))
ExceptionOccurred = {jthrowable (*)(JNIEnv *) | 0xb39d49da} (libart.so`art::CheckJNI::ExceptionOccurred(_JNIEnv*))
ExceptionDescribe = {void (*)(JNIEnv *) | 0xb39d4dd0} (libart.so`art::CheckJNI::ExceptionDescribe(_JNIEnv*))
ExceptionClear = {void (*)(JNIEnv *) | 0xb39d5200} (libart.so`art::CheckJNI::ExceptionClear(_JNIEnv*))
FatalError = {void (*)(JNIEnv *, const char *) | 0xb39d5a30} (libart.so`art::CheckJNI::FatalError(_JNIEnv*, char const*))
PushLocalFrame = {jint (*)(JNIEnv *, jint) | 0xb39d5e3e} (libart.so`art::CheckJNI::PushLocalFrame(_JNIEnv*, int))
PopLocalFrame = {jobject (*)(JNIEnv *, jobject) | 0xb39d625d} (libart.so`art::CheckJNI::PopLocalFrame(_JNIEnv*, _jobject*))
NewGlobalRef = {jobject (*)(JNIEnv *, jobject) | 0xb39d6bd5} (libart.so`art::CheckJNI::NewGlobalRef(_JNIEnv*, _jobject*))
DeleteGlobalRef = {void (*)(JNIEnv *, jobject) | 0xb39d72d9} (libart.so`art::CheckJNI::DeleteGlobalRef(_JNIEnv*, _jobject*))
DeleteLocalRef = {void (*)(JNIEnv *, jobject) | 0xb39d729f} (libart.so`art::CheckJNI::DeleteLocalRef(_JNIEnv*, _jobject*))
IsSameObject = {jboolean (*)(JNIEnv *, jobject, jobject) | 0xb39d7740} (libart.so`art::CheckJNI::IsSameObject(_JNIEnv*, _jobject*, _jobject*))
NewLocalRef = {jobject (*)(JNIEnv *, jobject) | 0xb39d6b9b} (libart.so`art::CheckJNI::NewLocalRef(_JNIEnv*, _jobject*))
EnsureLocalCapacity = {jint (*)(JNIEnv *, jint) | 0xb39d7313} (libart.so`art::CheckJNI::EnsureLocalCapacity(_JNIEnv*, int))
AllocObject = {jobject (*)(JNIEnv *, jclass) | 0xb39d7b90} (libart.so`art::CheckJNI::AllocObject(_JNIEnv*, _jclass*))
NewObject = {jobject (*)(JNIEnv *, jclass, jmethodID, ...) | 0xb39d867c} (libart.so`art::CheckJNI::NewObject(_JNIEnv*, _jclass*, _jmethodID*, ...))
NewObjectV = {jobject (*)(JNIEnv *, jclass, jmethodID, va_list) | 0xb39d80a5} (libart.so`art::CheckJNI::NewObjectV(_JNIEnv*, _jclass*, _jmethodID*, char*))
NewObjectA = {jobject (*)(JNIEnv *, jclass, jmethodID, jvalue *) | 0xb39d86a7} (libart.so`art::CheckJNI::NewObjectA(_JNIEnv*, _jclass*, _jmethodID*, jvalue*))
GetObjectClass = {jclass (*)(JNIEnv *, jobject) | 0xb39d8c7e} (libart.so`art::CheckJNI::GetObjectClass(_JNIEnv*, _jobject*))
IsInstanceOf = {jboolean (*)(JNIEnv *, jobject, jclass) | 0xb39d9090} (libart.so`art::CheckJNI::IsInstanceOf(_JNIEnv*, _jobject*, _jclass*))
GetMethodID = {jmethodID (*)(JNIEnv *, jclass, const char *, const char *) | 0xb39d99b0} (libart.so`art::CheckJNI::GetMethodID(_JNIEnv*, _jclass*, char const*, char const*))
CallObjectMethod = {jobject (*)(JNIEnv *, jobject, jmethodID, ...) | 0xb39ea042} (libart.so`art::CheckJNI::CallObjectMethod(_JNIEnv*, _jobject*, _jmethodID*, ...))
CallObjectMethodV = {jobject (*)(JNIEnv *, jobject, jmethodID, va_list) | 0xb39e9fd9} (libart.so`art::CheckJNI::CallObjectMethodV(_JNIEnv*, _jobject*, _jmethodID*, char*))
CallObjectMethodA = {jobject (*)(JNIEnv *, jobject, jmethodID, jvalue *) | 0xb39e7197} (libart.so`art::CheckJNI::CallObjectMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*))
CallBooleanMethod = {jboolean (*)(JNIEnv *, jobject, jmethodID, ...) | 0xb39e9f6f} (libart.so`art::CheckJNI::CallBooleanMethod(_JNIEnv*, _jobject*, _jmethodID*, ...))
CallBooleanMethodV = {jboolean (*)(JNIEnv *, jobject, jmethodID, va_list) | 0xb39e9f05} (libart.so`art::CheckJNI::CallBooleanMethodV(_JNIEnv*, _jobject*, _jmethodID*, char*))
CallBooleanMethodA = {jboolean (*)(JNIEnv *, jobject, jmethodID, jvalue *) | 0xb39e712d} (libart.so`art::CheckJNI::CallBooleanMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*))
CallByteMethod = {jbyte (*)(JNIEnv *, jobject, jmethodID, ...) | 0xb39e9e9b} (libart.so`art::CheckJNI::CallByteMethod(_JNIEnv*, _jobject*, _jmethodID*, ...))
CallByteMethodV = {jbyte (*)(JNIEnv *, jobject, jmethodID, va_list) | 0xb39e9e31} (libart.so`art::CheckJNI::CallByteMethodV(_JNIEnv*, _jobject*, _jmethodID*, char*))
CallByteMethodA = {jbyte (*)(JNIEnv *, jobject, jmethodID, jvalue *) | 0xb39e70c3} (libart.so`art::CheckJNI::CallByteMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*))
CallCharMethod = {jchar (*)(JNIEnv *, jobject, jmethodID, ...) | 0xb39e9dc7} (libart.so`art::CheckJNI::CallCharMethod(_JNIEnv*, _jobject*, _jmethodID*, ...))
CallCharMethodV = {jchar (*)(JNIEnv *, jobject, jmethodID, va_list) | 0xb39e9d5d} (libart.so`art::CheckJNI::CallCharMethodV(_JNIEnv*, _jobject*, _jmethodID*, char*))
CallCharMethodA = {jchar (*)(JNIEnv *, jobject, jmethodID, jvalue *) | 0xb39e7059} (libart.so`art::CheckJNI::CallCharMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*))
CallShortMethod = {jshort (*)(JNIEnv *, jobject, jmethodID, ...) | 0xb39e9cf3} (libart.so`art::CheckJNI::CallShortMethod(_JNIEnv*, _jobject*, _jmethodID*, ...))
CallShortMethodV = {jshort (*)(JNIEnv *, jobject, jmethodID, va_list) | 0xb39e9c89} (libart.so`art::CheckJNI::CallShortMethodV(_JNIEnv*, _jobject*, _jmethodID*, char*))
CallShortMethodA = {jshort (*)(JNIEnv *, jobject, jmethodID, jvalue *) | 0xb39e6fef} (libart.so`art::CheckJNI::CallShortMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*))
CallIntMethod = {jint (*)(JNIEnv *, jobject, jmethodID, ...) | 0xb39e9c20} (libart.so`art::CheckJNI::CallIntMethod(_JNIEnv*, _jobject*, _jmethodID*, ...))
obj = {jobject | 0xbfcda6ec} 0xbfcda6ec
Bekommen Sie jede Stack-Trace wenn die App abstürzt? – kevto
@kevto Ich habe den Stacktrack hinzugefügt. Danke für den Vorschlag. – user1147171
Haben Sie die JNI-Bridge implementiert? JNIEXPORT bla bla Zeug? –