Android убивает процесс при получении трансляции - PullRequest
0 голосов
/ 01 мая 2020

У меня проблема с приемником трансляции, который получил трансляцию от AlarmManager. Моя настройка включает в себя активность, службу переднего плана и приемник вещания. Когда широковещание получено, Android убивает мой процесс и обрабатывает широковещание в новом.

Чтобы воспроизвести проблему, I:

  1. запустите приложение;
  2. нажмите кнопку в главном окне, чтобы установить будильник;
  3. нажмите кнопку «Домой» (в этот момент запускается служба переднего плана и отображается уведомление);
  4. удаляет приложение из последних записей (служба переднего плана продолжает работать);
  5. В момент трансляции Через 10 секунд android убивает процесс (можно увидеть в Logcat) и немедленно запускает новый, где обрабатывается передача).

Если пропустить шаг 4 ( то есть я не удаляю приложение из последних записей), тогда вещание обрабатывается в том же процессе.

Я наблюдаю это поведение только в API 21 и 22. В настоящее время я по какой-то причине не могу загрузить изображения Marshmallow, поэтому Я не могу протестировать в API 23.

Однако в API 24 и выше широковещательная передача всегда принимается в одном и том же процессе.

Я не могу найти объяснение в документации. В моем понимании трансляция должна обрабатываться в моем основном потоке, если я явно не установлю process для получателя.

Вот код моего приложения:

class MainActivity : AppCompatActivity() {
    //...

    override fun onResume() {
        super.onResume()
        val intent = Intent(this, ForegroundService::class.java)
        stopService(intent)
    }

    override fun onPause() {
        super.onPause()
        val intent = Intent(this, ForegroundService::class.java)
        ContextCompat.startForegroundService(this, intent)
    }

    fun onClick(view: View) {
        val alarmManager = ContextCompat.getSystemService(this, AlarmManager::class.java)!!
        val intent = Intent(this, SampleReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(this, 0,intent, 0)
        val time = System.currentTimeMillis() + 10_000

        AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, RTC_WAKEUP, time, pendingIntent)
    }
}

class ForegroundService : Service() {
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)

        val notificationManager = ContextCompat.getSystemService(this, NotificationManager::class.java)!!

        val channelId = "mychannel"

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel =  NotificationChannel(channelId, "alarm", NotificationManager.IMPORTANCE_DEFAULT)
            notificationManager.createNotificationChannel(channel)
        }

        val notification = NotificationCompat.Builder(this, channelId)
            .setContentTitle("Title")
            .setContentText("Text")
            .setSmallIcon(R.drawable.ic_access_alarms_black_24dp)
            .build()

        Log.d("ForegroundService", "Starting foreground service")
        startForeground(1, notification)

        return START_STICKY
    }

    //...
}
class SampleReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        Log.d("SampleReceiver", "onReceive called")
    }
}

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testbr">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <receiver
            android:name=".SampleReceiver"
            android:enabled="true"
            android:exported="false" />

        <service
            android:name=".ForegroundService"
            android:enabled="true"
            android:exported="false" />

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
...