অগ্রভাগ পরিষেবা সর্বশেষ বন্ধ হয়ে গেলে অ্যাপ চলতে থাকে


9

অগ্রভাগের পরিষেবাগুলির সাথে একযোগে অ্যান্ড্রয়েডের প্রক্রিয়া পরিচালনার একটি আচরণ আমি পেয়েছিলাম, যা আমাকে সত্যই বিভ্রান্ত করে।

আমার জন্য কি যুক্তিযুক্ত

  1. আপনি যখন 'সাম্প্রতিক অ্যাপ্লিকেশনগুলি' থেকে আপনার অ্যাপটিকে সোয়াইপ করেন, অপেক্ষাকৃত অদূর ভবিষ্যতে ওএসের অ্যাপ্লিকেশন প্রক্রিয়াটি শেষ করা উচিত।
  2. অগ্রণী পরিষেবা চালানোর সময় আপনি যখন 'সাম্প্রতিক অ্যাপ্লিকেশনগুলি' থেকে আপনার অ্যাপ্লিকেশন সোয়াইপ করেন তখন অ্যাপটি জীবিত থাকে।
  3. যখন আপনি 'সাম্প্রতিক অ্যাপ্লিকেশনগুলি' থেকে আপনার অ্যাপ্লিকেশনটিকে সোয়াইপ করার আগে অগ্রভাগ পরিষেবাটি বন্ধ করেন আপনি 1 এর মতোই পাবেন)।

কি আমাকে বিভ্রান্ত করে

যখন আপনি অগ্রভাগে কোনও ক্রিয়াকলাপ না থাকাকালীন অগ্রভাগের পরিষেবাটি বন্ধ করেন (অ্যাপ্লিকেশনটি 'সাম্প্রতিক অ্যাপ্লিকেশনগুলিতে প্রদর্শিত হয় না), আমি এখনই অ্যাপটি মারা যাওয়ার আশা করব।

তবে এটি ঘটছে না, অ্যাপ প্রক্রিয়াটি এখনও বেঁচে আছে alive

উদাহরণ

আমি একটি ন্যূনতম উদাহরণ তৈরি করেছি যা এই আচরণটি দেখায়।

ফোরগ্রাউন্ড সার্ভিস:

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import timber.log.Timber

class MyService : Service() {

    override fun onBind(intent: Intent?): IBinder? = null

    override fun onCreate() {
        super.onCreate()
        Timber.d("onCreate")
    }

    override fun onDestroy() {
        super.onDestroy()
        Timber.d("onDestroy")

        // just to make sure the service really stops
        stopForeground(true)
        stopSelf()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Timber.d("onStartCommand")
        startForeground(ID, serviceNotification())
        return START_NOT_STICKY
    }

    private fun serviceNotification(): Notification {
        createChannel()

        val stopServiceIntent = PendingIntent.getBroadcast(
            this,
            0,
            Intent(this, StopServiceReceiver::class.java),
            PendingIntent.FLAG_UPDATE_CURRENT
        )
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentTitle("This is my service")
            .setContentText("It runs as a foreground service.")
            .addAction(0, "Stop", stopServiceIntent)
            .build()
    }

    private fun createChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(
                NotificationChannel(
                    CHANNEL_ID,
                    "Test channel",
                    NotificationManager.IMPORTANCE_DEFAULT
                )
            )
        }
    }

    companion object {
        private const val ID = 532207
        private const val CHANNEL_ID = "test_channel"

        fun newIntent(context: Context) = Intent(context, MyService::class.java)
    }
}

পরিষেবাটি বন্ধ করার জন্য ব্রডকাস্টার রিসিভার:

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent

class StopServiceReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {

        val serviceIntent = MyService.newIntent(context)

        context.stopService(serviceIntent)
    }
}

কার্যক্রম:

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        startService(MyService.newIntent(this))
    }
}

প্রকাশ:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.christophlutz.processlifecycletest">

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

    <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">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".MyService"/>
        <receiver android:name=".StopServiceReceiver" />
    </application>

</manifest>

এটি নিম্নলিখিত উপায়ে ব্যবহার করে দেখুন:

  1. অ্যাপ্লিকেশন শুরু করুন, অগ্রভাগ পরিষেবা বন্ধ করুন, 'সাম্প্রতিক অ্যাপস' থেকে অ্যাপ্লিকেশন সরান
  2. অ্যাপ্লিকেশন শুরু করুন, 'সাম্প্রতিক অ্যাপ্লিকেশনগুলি' থেকে অ্যাপ সরান, অগ্রভাগ পরিষেবা বন্ধ করুন

আপনি অ্যান্ড্রয়েড স্টুডিওর লগগিকেটে দেখতে পাচ্ছেন যে অ্যাপ্লিকেশন প্রক্রিয়াটি কেস 1 এর জন্য নয় তবে কেস 2 এর জন্য [DEAD] চিহ্নিত রয়েছে।

যেহেতু এটি পুনরুত্পাদন করা বেশ সহজ তাই এটি একটি উদ্দেশ্যমূলক আচরণ হতে পারে তবে ডকসগুলিতে আমি এর কোনও প্রকৃত উল্লেখ পাইনি।

কেউ কি জানেন যে এখানে কী চলছে?

উত্তর:


0

অগ্রভাগ পরিষেবাটি আসলে কী করে তার উপর এটি নির্ভর করে। যদি এটি থ্রেড, নেটওয়ার্ক সংযোগ, ফাইল আই / ও ইত্যাদি ব্যবহার করে যা মেমরিটিকে সক্রিয়ভাবে গ্রাস করে, আপনি পরিষেবা বন্ধ করার চেষ্টা করেও এটি ধ্বংস হবে না, সুতরাং প্রক্রিয়াটি জীবিত থাকবে। এর মধ্যে এমন কোনও ইন্টারফেস কলব্যাকের মধ্যে অন্তর্ভুক্ত রয়েছে যা আপনি পরিষেবা বন্ধ করার চেষ্টা করার সময় জীবিত থাকে। বিশেষত থ্রেডগুলি যা এখনও চলছে (এমনকি বাধাপ্রাপ্ত) এবং সীমাবদ্ধ পরিষেবাদি পরিষেবাটি সঠিকভাবে বন্ধ করে দিচ্ছে এমন লাইফসাইকেলটি অবরুদ্ধ করে।

আপনার পরিষেবায় আপনার কোনও মেমরি ফাঁস নেই এবং প্রতিটি সংযোগ (ডাটাবেস, নেটওয়ার্ক ইত্যাদি ...) বন্ধ করে রাখুন, আপনার পরিষেবা বন্ধ করার আগে সমস্ত ইন্টারফেস থেকে সমস্ত কলব্যাক সরিয়ে ফেলুন তা নিশ্চিত করুন। আপনি নিশ্চিত করতে পারেন যে পরিষেবাটি কল করা হলে ধ্বংস হতে চলেছে onDestroy()

বিভিন্ন প্রক্রিয়াগুলির জন্য: আমি বিশ্বাস করি যে প্রক্রিয়াটি বেঁচে থাকার কারণ হ'ল সিস্টেমটি এমনভাবে দেখায় যেখানে কিছু সময়ের জন্য পরিষেবা আবার শুরু হতে পারে, সুতরাং এটি প্রক্রিয়াটি অল্প সময়ের জন্যই বাঁচিয়ে রাখে। কমপক্ষে, আমি এটি পর্যবেক্ষণ করেছি, কারণ onDestroy()ডাকা হওয়ার পরেও , প্রক্রিয়াটি বেঁচে ছিল, আমি এটি ডিবাগার থেকে দেখতে সক্ষম হয়েছি।

আপনি যদি নিশ্চিত করতে চান (যদিও এই উপায়টি সুপারিশ করা হয়নি) যে প্রক্রিয়াটি সবকিছু নষ্ট হওয়ার পরে নিশ্চিতভাবে মারা যায়, আপনি নিজেই প্রক্রিয়াটি সমাপ্ত করতে এই কল করতে পারেন:

android.os.Process.killProcess(android.os.Process.myPid());

প্রশ্ন থেকে & উদাহরণস্বরূপ আচরণের সাথে আপনি পুনরায় উত্পাদন করতে পারেন; কোনও সংযোগ, থ্রেড, বা অন্য কোনও কিছুই চলমান থাকে না। onDestroy(পরিষেবা) কল হয়ে যায়, তবুও প্রক্রিয়াটি সবকিছু শেষ হয়ে যাওয়ার পরেও দীর্ঘকাল ধরে থাকে। এমনকি যদি পরিষেবাটি পুনরায় চালু হওয়ার ক্ষেত্রে ওএস প্রক্রিয়াটি বাঁচিয়ে রাখছে, আপনি প্রথমে পরিষেবাটি বন্ধ করার পরে কেন এটি একই কাজ করে না তা দেখতে পাচ্ছি না, তারপরে অ্যাপ্লিকেশনগুলি রিসেন্টগুলি থেকে সরিয়ে দিন। প্রদর্শিত আচরণটি বরং অপ্রয়োজনীয় বলে মনে হচ্ছে, বিশেষত পশ্চাদপটে সম্পাদনের সীমাতে সাম্প্রতিক পরিবর্তনগুলি দেওয়া হয়েছে, সুতরাং প্রক্রিয়াটি কীভাবে বন্ধ হয়ে যায় তা নিশ্চিত করে কীভাবে তা জেনে রাখা ভাল লাগবে
ডেভিড মেডেনজাক

@ ডেভিডমেডেনজাক getApplicationContext().startService(MyService.newIntent(this));আপনি যা ব্যবহার করছেন তার পরিবর্তে ব্যবহার করার চেষ্টা করুন এবং আমাকে ফলাফলটি বলুন দয়া করে। আমি বিশ্বাস করি ক্রিয়াকলাপটি জীবিত থাকে কারণ ক্রিয়াকলাপটি প্রসঙ্গ প্রয়োগের পরিবর্তে ব্যবহার করা হয় context এছাড়াও যদি আপনি ওরিও বা তার getApplicationContext().startforegroundService(MyService.newIntent(this));
থেকেও

0

অ্যান্ড্রয়েড সিস্টেম মেমরি, প্রসেসর শক্তি এবং অ্যাপ্লিকেশন প্রক্রিয়াগুলির আজীবন স্ব-সচেতনতার জন্য পরিচিত - এটি কোনও প্রক্রিয়া না (হত্যা এবং ক্রিয়াকলাপের সাথে একই) রক্ষা করবে কিনা তা নিজে থেকেই সিদ্ধান্ত নেয়

এই বিষয়টি সম্পর্কে অফিসিয়াল ডকুমেন্টেশন এখানে দেওয়া হয়েছে

অগ্রভাগ সম্পর্কে এটি যা বলেছে তা দেখুন

সিস্টেমে কেবল এইরকম কয়েকটি প্রক্রিয়া থাকবে এবং এগুলি কেবলমাত্র সর্বশেষ অবলম্বন হিসাবে মারা যাবে যদি মেমরিটি এত কম থাকে যে এমনকি এই প্রক্রিয়াগুলি চালিয়ে যেতে না পারে। সাধারণত, এই মুহুর্তে, ডিভাইসটি একটি মেমরি পেজিং অবস্থায় পৌঁছেছে, সুতরাং ব্যবহারকারী ইন্টারফেসকে প্রতিক্রিয়াশীল রাখতে এই ক্রিয়াটি প্রয়োজন।

এবং দৃশ্যমান প্রক্রিয়া (অগ্রভাগ পরিষেবা একটি দৃশ্যমান প্রক্রিয়া)

সিস্টেমে এই প্রক্রিয়াগুলির সংখ্যা অগ্রভাগের প্রক্রিয়াগুলির তুলনায় কম সীমাবদ্ধ তবে এটি এখনও তুলনামূলকভাবে নিয়ন্ত্রিত। এই প্রক্রিয়াগুলি অত্যন্ত গুরুত্বপূর্ণ হিসাবে বিবেচিত হয় এবং যদি না করা না হয় তবে সমস্ত খালি প্রক্রিয়া চালিয়ে যাওয়ার প্রয়োজন হয় না।

এর অর্থ হ'ল অ্যান্ড্রয়েড ওএসে আপনার অ্যাপ্লিকেশন প্রক্রিয়া যতক্ষণ চলবে ততক্ষণ যতক্ষণ না এতে সমস্ত অগ্রভাগের প্রক্রিয়া সমর্থন করার জন্য পর্যাপ্ত মেমরি থাকবে । এমনকি যদি আপনি এটি বন্ধ করেও থাকেন - সিস্টেম কেবল এটি ক্যাশেড প্রক্রিয়াগুলিতে সরিয়ে নিয়ে যেতে পারে এবং এটি কাতারের মতো পদ্ধতিতে পরিচালনা করতে পারে। অবশেষে এটি যেভাবেই হত্যা করা হবে - তবে সাধারণত এটি সিদ্ধান্ত নেওয়া আপনার পক্ষে নয়। স্পষ্টতই আপনার সমস্ত অ্যাপ্লিকেশন প্রক্রিয়া যা অ্যানড্রয়েড জীবনচক্র পদ্ধতি কল করার পরে (এবং যতক্ষণ না) প্রক্রিয়ায় যা ঘটছে সেদিকে মোটেই চিন্তা করা উচিত নয়। অ্যান্ড্রয়েড আরও ভাল জানেন।

অবশ্যই আপনি এই প্রক্রিয়াটি মারেন android.os.Process.killProcess(android.os.Process.myPid());তবে এটি সুপারিশ করা হয় না কারণ এটি যথাযথ অ্যান্ড্রয়েড উপাদানগুলির জীবনকালকে ব্যাহত করে এবং যথাযথ কলব্যাকগুলি কল করা যায় না, সুতরাং আপনার অ্যাপ্লিকেশন কিছু ক্ষেত্রে দুর্ব্যবহার করতে পারে।

আশা করি এটা সাহায্য করবে.


0

অ্যান্ড্রয়েডে এটি অপারেটিং সিস্টেম কে সিদ্ধান্ত নেয় যে কোন অ্যাপ্লিকেশনগুলি হত্যা করা হয়।

অগ্রাধিকারের একটি আদেশ রয়েছে:
অগ্রভাগের পরিষেবা রয়েছে এমন অ্যাপ্লিকেশনগুলি খুব কমই মারা যায়, পরিবর্তে অন্যান্য অ্যাপ্লিকেশন এবং পরিষেবাগুলি নিষ্ক্রিয়তার একটি সময় পরে মারা যায় এবং আপনার অ্যাপ্লিকেশনটির সাথে এটি ঘটে happens

আপনি যখন অগ্রভাগের পরিষেবাটি শেষ করেন, এটি আপনার অ্যাপ্লিকেশনটিকে হত্যা করার সিস্টেমের সম্ভাবনাগুলি বাড়িয়ে দেয় তবে কোনও অবস্থাতেই এর অর্থ এই নয় যে এটি তাত্ক্ষণিকভাবে হত্যা করা হবে।


0

সাম্প্রতিক স্ক্রিন [...] একটি সিস্টেম-স্তরীয় UI যেটি তালিকা সম্প্রতি অ্যাক্সেস করা হয় কার্যক্রম এবং কর্ম

তালিকার একক অ্যাপ্লিকেশন থেকে আপনার বেশ কয়েকটি ক্রিয়াকলাপ বা কাজ থাকতে পারে। এটা না একটি সাম্প্রতিক অ্যাপ্লিকেশনগুলি তালিকা।

সুতরাং রিসেন্টস স্ক্রিন এবং অ্যাপ্লিকেশন প্রক্রিয়ার উপাদানগুলির মধ্যে কোনও সরাসরি সম্পর্ক নেই ।

যাইহোক , আপনি যদি আপনার অ্যাপ্লিকেশনটির শেষ ক্রিয়াকলাপটি বন্ধ করে দেন এবং প্রক্রিয়াটির মধ্যে অন্য কোনও কিছু চলমান থাকে না (যেমন একটি অগ্রভাগ পরিষেবা), প্রক্রিয়াটি কেবল পরিষ্কার হয়ে যায়।

সুতরাং যখন আপনি কোনও চলমান অগ্রভাগ (দ্বারা stopService()বা stopSelf()আনবাইন্ডিং) বন্ধ করবেন, তখন সিস্টেমটি যে প্রক্রিয়াটি চালাচ্ছিল তা পরিষ্কার করে দেবে।

সুতরাং এটি আসলে একটি উদ্দেশ্যমূলক আচরণ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.