我开发了一个使用本机C库的Android应用程序.我可以用JNI成功编译整个东西,一切顺利.
但是,偶尔本机C库崩溃(最常见的是SIGSEGV).反过来,这会导致我的应用程序在没有任何有意义的用户通知的情况下崩溃.我想要实现的目标如下:
如果这对你有用 - JNI代码在一个单独的线程中运行(在AsyncTask中更精确).
我已经检查了http://blog.httrack.com/blog/2013/08/23/catching-posix-signals-on-android/和https://github.com/xroche/coffeecatch 但我无法编译.
遵循Best方法在JNI代码中抛出异常的建议?而如何捕捉JNI崩溃与使用信号处理基础的机制在Java异常和https://www.developer.com/java/data/exception-handling-in-jni.html 我进行下面的步骤:
在我的本机代码中,我添加了以下函数(据我所知)设置了一个信号处理程序:
void initializeSignalHandler(JNIEnv* env){
int watched_signals[] = { SIGABRT, SIGILL, SIGSEGV, SIGINT, SIGKILL }; // 6, 4, 11, 2, 9
struct sigaction sighandler;
memset(&sighandler, 0, sizeof(sighandler));
sighandler.sa_sigaction = &sighandler_func;
sighandler.sa_mask = 0;
sighandler.sa_flags = SA_SIGINFO | SA_ONSTACK;
for(int ii=0; ii<5; ii++){
int signal = watched_signals[ii];
sigaction(signal, &sighandler, NULL);
}
env = env;
}
Run Code Online (Sandbox Code Playgroud)
我处理这些信号的函数如下所示:
void sighandler_func(int sig, siginfo_t* …Run Code Online (Sandbox Code Playgroud) 我在 Android 中开发了一个简单的音频播放器,可以播放 .mp3 文件。为了解码文件,我使用 Android MediaExtractor 和 Android MediaCodec。示例代码如下所示:
int inIndex = mDecoder.dequeueInputBuffer(TIMEOUT_US);
if (inIndex >= 0) {
ByteBuffer buffer = inputBuffers[inIndex];
int sampleSize = mExtractor.readSampleData(buffer, 0);
if (sampleSize < 0) {
// We shouldn't stop the playback at this point, just pass the EOS
// flag to mDecoder, we will get it again from the
// dequeueOutputBuffer
Log.d(TAG, "InputBuffer BUFFER_FLAG_END_OF_STREAM");
mDecoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
}
else {
mDecoder.queueInputBuffer(inIndex, 0, sampleSize, mExtractor.getSampleTime(), 0);
mExtractor.advance();
}
Run Code Online (Sandbox Code Playgroud)
在我的所有测试设备上,代码运行没有任何问题。然而,在 Google Play …
我有以下问题:我编写了一个 android 服务 - 一个音乐播放器 - 在后台运行并在启动时启动通知。单击此通知会打开允许与该玩家互动的活动 A。这工作正常。
问题是当我有第三方活动(例如 Web 浏览器)运行时,我单击了通知。此单击将我带到活动 A,但单击“后退”按钮 - 这就是问题 - 将我带到主屏幕。相反,我想恢复以前运行的活动,即 Web 浏览器。
有人知道怎么做吗?
private void initNotification(){
Intent resultIntent = new Intent(this, AudioPlayerActivity.class);
//resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(AudioPlayerActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
stackBuilder.getIntents();
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setSmallIcon(...);
mBuilder.setContentTitle("...");
mBuilder.setContentText("...");
mBuilder.setContentIntent(resultPendingIntent);
// create a notification manager that then displays the notification
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
Run Code Online (Sandbox Code Playgroud) android android-intent android-notifications android-activity android-pendingintent