小编Mar*_*tin的帖子

在Android上用例外替换JNI崩溃

我开发了一个使用本机C库的Android应用程序.我可以用JNI成功编译整个东西,一切顺利.

但是,偶尔本机C库崩溃(最常见的是SIGSEGV).反过来,这会导致我的应用程序在没有任何有意义的用户通知的情况下崩溃.我想要实现的目标如下:

  1. 使用信号处理程序(sigaction)捕获本机代码中的信号以防止随机崩溃
  2. 在Java可以捕获的C库中抛出异常
  3. 在Java中捕获异常,为用户生成有意义的警告消息并使应用程序保持运行

如果这对你有用 - 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)

c java android signals android-ndk

7
推荐指数
1
解决办法
804
查看次数

Android MediaExtractor / MediaCodec 本机崩溃

我在 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 …

memory android bytebuffer mediaextractor android-mediacodec

6
推荐指数
0
解决办法
695
查看次数

单击通知后返回当前正在运行的活动

我有以下问题:我编写了一个 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

2
推荐指数
1
解决办法
1018
查看次数