ඇන්ඩ්‍රොයිඩ් හි සේවාවක් ක්‍රියාත්මක වේදැයි පරීක්ෂා කරන්නේ කෙසේද?


947

පසුබිම් සේවාවක් ක්‍රියාත්මක වේදැයි මා පරීක්ෂා කරන්නේ කෙසේද?

සේවාවේ තත්වය ටොගල් කරන ඇන්ඩ්‍රොයිඩ් ක්‍රියාකාරකමක් මට අවශ්‍යයි - එය ක්‍රියා විරහිත නම් සහ අක්‍රිය නම් එය සක්‍රිය කිරීමට එය මට ඉඩ දෙයි.



18
නිවැරදි පිළිතුර පහතින් ඇති අතර එය සලකුණු කර නැත: stackoverflow.com/a/5921190/2369122
toidiu

2
idtoidiu එය දැනටමත් නර්ෆෙඩ් කර නොමැති නම් getRunningTasks(), එය බොහෝ විට එසේ වනු ඇත.
කෙවින් ක්‍රම්වීඩ්

getSystemService () ශ්‍රිතය භාවිතා කිරීමෙන් ඔබට ක්‍රියාත්මක වන සියලුම සේවාවන් ලබා ගත හැකිය. එය හරහා ලූප් කර ඔබේ සේවාව ලැයිස්තුවේ තිබේදැයි පරීක්ෂා කර බලන්න wiki.workassis.com/android-check-the-service-is-running
Bikesh M

Answers:


293

මටත් ඒ ප්‍රශ්නයම තිබුණේ මීට කලකට පෙර නොවේ. මගේ සේවා දේශීය වූ නිසා, මම හුදෙක් hackbod විසින් විස්තර කර ඇති පරිදි, ටොගල රාජ්ය සේවය පන්තිය තුල ස්ථිතික ක්ෂේත්රය භාවිතා කරන අවසන් මෙතන

සංස්කරණය කරන්න (වාර්තාව සඳහා):

හැක්බෝඩ් විසින් යෝජනා කරන ලද විසඳුම මෙන්න:

ඔබේ සේවාදායකයා සහ සේවාදායක කේතය එකම .apk හි කොටසක් නම් සහ ඔබ කොන්ක්‍රීට් අභිප්‍රායයකින් (නිශ්චිත සේවා පන්තිය නියම කරන) සේවාවට බැඳී සිටී නම්, එය ක්‍රියාත්මක වන විට ඔබේ සේවාව ගෝලීය විචල්‍යයක් සැකසිය හැකිය. ඔබේ සේවාදායකයාට පරීක්ෂා කළ හැකිය.

සේවාවක් ක්‍රියාත්මක වේදැයි පරීක්ෂා කිරීමට අපට හිතාමතාම API එකක් නොමැත, මන්දයත් ඔබට නොවරදවාම, ඔබට එවැනි දෙයක් කිරීමට අවශ්‍ය වූ විට ඔබේ කේතයේ ධාවන කොන්දේසි සමඟ අවසන් වේ.


27
AcPacerier, ඔබ සඳහන් කරන විසඳුමට සේවාව ආරම්භ කිරීම අවශ්‍ය වන අතර හොඳම නම්‍යශීලී විසඳුම මඟින් සේවාවක් ආරම්භ නොකර ක්‍රියාත්මක වේදැයි පරීක්ෂා කිරීමට ඔබට ඉඩ දිය යුතුය.
ටොම්

17
පද්ධතිය මඟින් සේවාව නැවැත්වුවහොත්, ඔබ එය හඳුනාගෙන ඔබේ විචල්‍යය ටොගල් කරන්නේ කෙසේද?
jmng

23
යෙදුම is ාතනය වූ විට, එය ආරම්භ කළ සේවාව ද මරා දමන නමුත් සේවාව onDestroy()කැඳවනු නොලැබේ. එබැවින් නොගැලපෙන හැසිරීම් වල ප්‍රති ing ලයක් ලෙස ස්ථිතික විචල්‍යය එවැනි තත්වයක් තුළ යාවත්කාලීන කළ නොහැක.
faizal

5
@faizal ස්ථිතික විචල්‍යය ද නැවත ක්‍රියාත්මක නොකෙරේ, එමඟින් සේවාව තවදුරටත් ක්‍රියාත්මක නොවන බව පෙන්වන පෙරනිමි අගයට එය නැවත සකසනු ලැබේ ද?
පැබ්ලෝක්

12
@ ෆයිසාල්, ප්‍රාදේශීය සේවය වෙනම ක්‍රියාවලියක් නොවේ, එබැවින් සේවාව killed ාතනය වුවහොත් යෙදුමද විනාශ වේ.
සෙවර්

1693

ක්‍රියාකාරකමක් ඇතුළත සිට මම පහත සඳහන් දෑ භාවිතා කරමි:

private boolean isMyServiceRunning(Class<?> serviceClass) {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

මම එය අමතන්නේ:

isMyServiceRunning(MyService.class)

මෙය විශ්වාසදායක ලෙස ක්‍රියා කරයි, මන්ද එය පදනම් වී ඇත්තේ ActivityManager # getRunningServices හරහා ඇන්ඩ්‍රොයිඩ් මෙහෙයුම් පද්ධතිය විසින් සපයනු ලබන ධාවන සේවා පිළිබඳ තොරතුරු මත ය .

OnDestroy හෝ onSometing සිදුවීම් හෝ බයින්ඩර් හෝ ස්ථිතික විචල්‍යයන් භාවිතා කරන සියලුම ප්‍රවේශයන් විශ්වසනීයව ක්‍රියා නොකරනු ඇත, මන්ද ඔබ කිසි විටෙකත් නොදන්නා සංවර්ධකයෙකු ලෙස, ඇන්ඩ්‍රොයිඩ් ඔබේ ක්‍රියාවලිය විනාශ කිරීමට තීරණය කළ විට හෝ සඳහන් කළ ඇමතුම් මොනවාදැයි හෝ නොකියයි. ඇන්ඩ්‍රොයිඩ් ප්‍රලේඛනයේ ජීවන චක්‍රීය සිදුවීම් වගුවේ "මරා දැමිය හැකි" තීරුව කරුණාකර සටහන් කරන්න .


86
මෙම විසඳුමට ස්තූතියි. මම එකතු කිරීමට කැමතියි: ඒ වෙනුවට "com.example.MyService" MyService.class.getName () භාවිතා කිරීමට වඩා අලංකාරයි
peter.bartos

10
පුද්ගලිකව, මම ස්ථිතික ක්ෂේත්‍රයක් භාවිතා කරමින් ගියෙමි. GetRunningServices () භාවිතා කිරීම වඩා ශක්තිමත් විසඳුමක් වුවද, මෙම විසඳුම් දෙකෙහි ශක්තිමත් බව සහ කාර්යක්ෂමතාව / සරල බව අතර වෙළඳාමක් ඇති බව මම විශ්වාස කරමි. සේවාවක් ක්‍රියාත්මක වේදැයි ඔබට නිතර පරීක්ෂා කර බැලීමට අවශ්‍ය නම්, 30+ ධාවනය කළ හැකි සේවාවන් හරහා ලූප වීම ඉතා සුදුසු නොවේ. පද්ධතිය විසින් විනාශ කරනු ලබන දුර්ලභ අවස්ථාව සමහර විට උත්සාහ කිරීම / අල්ලා ගැනීම හෝ START_STICKY භාවිතා කිරීම මඟින් පාලනය කළ හැකිය.
මංකොල්ලය

81
එය නිවැරදි පිළිතුර නොවේ, මන්ද එය ලේඛනයේ ද ලියා ඇත: "සටහන: මෙම ක්‍රමය අදහස් කරන්නේ සේවා කළමනාකරණ ආකාරයේ පරිශීලක අතුරුමුහුණත් නිදොස් කිරීම හෝ ක්‍රියාත්මක කිරීම සඳහා පමණි." එය පාලක ප්‍රවාහය සඳහා අදහස් නොකෙරේ!
seb

41
සේවාදායකයක් ක්‍රියාත්මක වේදැයි පරීක්ෂා කිරීම සඳහා මිනිසුන්ට ඒ සියල්ල හරහා යාමට සිදුවීම අලංකාරද?
රූයි මාර්ක්ස්

85
ආරම්භ ඇන්ඩ්රොයිඩ් ඕ , getRunningServicesප්රතික්ෂේප කරයි. මෙම පිළිතුරට නව අනුවාදය සඳහා යාවත්කාලීන කිරීමක් අවශ්‍ය වේ.
poring91

75

තේරුම් ගත්තා ද!

ඔබ යුතුය කතා startService()නිසි ලියාපදිංචි කිරීමට ඔබේ සේවාව සඳහා සම්මත BIND_AUTO_CREATEප්රමාණවත් නැහැ.

Intent bindIntent = new Intent(this,ServiceTask.class);
startService(bindIntent);
bindService(bindIntent,mConnection,0);

දැන් සර්විස් ටූල්ස් පන්තිය:

public class ServiceTools {
    private static String LOG_TAG = ServiceTools.class.getName();

    public static boolean isServiceRunning(String serviceClassName){
        final ActivityManager activityManager = (ActivityManager)Application.getContext().getSystemService(Context.ACTIVITY_SERVICE);
        final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        for (RunningServiceInfo runningServiceInfo : services) {
            if (runningServiceInfo.service.getClassName().equals(serviceClassName)){
                return true;
            }
        }
        return false;
     }
}

මෙය පද්ධති සේවා පමණක් ලැයිස්තුගත කරනු ඇත, නැත ?! එබැවින් මගේ ප්‍රාදේශීය සේවය ලැයිස්තුවෙන් බැහැර කර ඇති අතර මම අසත්‍යය ලබා දෙන්නෙමි. (
ඊවොක්ස්

මෙය බාහිර සේවාවන් සමඟ ක්‍රියා කරයි, මන්ද ඔබ ක්‍රියාත්මක වන්නේ නම් දේශීය සේවාවන් පැහැදිලිව පෙනේ.
කෙවින් පාකර්

11
කණගාටුයි නමුත් මට කියන්නට ඇත්තේ එය සුපිරි මෝඩ පිළිතුරකි..එය සුපිරි පැහැදිලිව පෙනෙන්නේ ඇයි?
ඊවොක්ස්

10
ඔබ මෙහි අදහස් කරන්නේ කුමක්දැයි පැහැදිලි නැත ... කඩා වැටීම ගැන කතා කළේ කවුද? එය කඩා වැටීමට මා උනන්දු නොවේ. සේවාව ආරම්භ කළ හැකිය, නැවැත්විය හැකිය, සමහර විට එය අභිප්‍රාය සේවාවක් විය හැකි අතර එය සිදු වූ විට එය තනිවම නතර වනු ඇත ... ප්‍රශ්නය වන්නේ එය තවමත් ක්‍රියාත්මක වන්නේද නැද්ද යන්න දැන ගන්නේ කෙසේද යන්න උදාහරණයක් ලෙස මිනිත්තු 3 කට පසුවය.
ඊවොක්ස්

1
බැඳී ඇති සේවාවක් ද ආරම්භ කළ යුතුය යන හැඟීම ලබා දීම වැරදිය. නැත. බන්ධන ස්වයංක්‍රීය නිර්මාණය එය පවසන දේම කරයි. සේවාව තවමත් ක්‍රියාත්මක නොවන්නේ නම් එය සේවාව නිර්මාණය කරයි (එබැවින් "ආරම්භ කරන්න").
ශ්‍රීදේවි ජේ

58

කුඩා අනුපූරකය නම්:

මගේ ඉලක්කය වන්නේ සේවාවක් ක්‍රියාත්මක නොවන්නේ නම් එය ක්‍රියාත්මක නොවී දැන ගැනීමයි.

බින්ඩ් සර්විස් ඇමතීම හෝ සේවයට හසු විය හැකි අභිප්‍රායයක් ඇමතීම හොඳ අදහසක් නොවේ, එවිට එය ක්‍රියාත්මක නොවන්නේ නම් එය සේවාව ආරම්භ කරනු ඇත.

එබැවින්, ප්‍රාතිහාර්ය 2 කේ යෝජනා කළ පරිදි, හොඳම දෙය නම් සේවාව ආරම්භ කර තිබේද නැද්ද යන්න දැන ගැනීම සඳහා සේවා පන්තියේ ස්ථිතික ක්ෂේත්‍රයක් තිබීමයි.

එය වඩාත් පිරිසිදු කිරීම සඳහා, මම යෝජනා කරන්නේ ඉතා කම්මැලි ලබා ගැනීමක් සහිත සේවාවක් සිංගල්ටන් එකක පරිවර්තනය කිරීමට ය: එනම්, ස්ථිතික ක්‍රම මගින් සිංගල්ටන් අවස්ථාවන්හි කිසිදු ක්ෂණික අවස්ථාවක් නොමැත. ඔබේ සේවාවේ ස්ථිතික getInstance ක්‍රමය / සිංගල්ටන් ඒකකය නිර්මාණය කර ඇත්නම් එය නැවත ලබා දෙයි. නමුත් එය ඇත්ත වශයෙන්ම සිංගල්ටන් එක ආරම්භ කිරීම හෝ ක්ෂණික කිරීම නොවේ. සේවාව ආරම්භ කරනු ලබන්නේ සාමාන්‍ය සේවා ආරම්භක ක්‍රම හරහා පමණි.

අවුල් සහගත getInstance ක්‍රමය ක්‍රමයට සමාන ලෙස නම් කිරීම සඳහා සිංගල්ටන් සැලසුම් රටාව වෙනස් කිරීම වඩාත් පිරිසිදු වනු ඇත isInstanceCreated() : boolean.

කේතය පෙනෙන්නේ:

public class MyService extends Service
{
   private static MyService instance = null;

   public static boolean isInstanceCreated() {
      return instance != null;
   }//met

   @Override
   public void onCreate()
   {
      instance = this;
      ....
   }//met

   @Override
   public void onDestroy()
   {
      instance = null;
      ...
   }//met
}//class

මෙම විසඳුම අලංකාරයි, නමුත් එය අදාළ වන්නේ ඔබට සේවා පන්තියට ප්‍රවේශය ඇත්නම් සහ සේවාවේ යෙදුම / පැකේජය හැරුණු කොට පන්ති සඳහා පමණි. ඔබේ පන්ති සේවා යෙදුමෙන් / පැකේජයෙන් පිටත නම්, ඔබට පීටර්-ජෑන් වැන් රොබේස් විසින් අවධාරණය කර ඇති සීමාවන් සමඟ ක්‍රියාකාරකම් කළමනාකරුගෙන් විමසිය හැකිය.


32
මෙය දෝෂ සහිතය. onDestroy කැඳවීමට සහතික නැත.
පැසීරියර්

8
පද්ධතියේ මතකය අඩු වූ විට, ඔබගේ ඩෙස්ට්‍රෝයි වෙත ඇමතුමක් නොමැතිව ඔබගේ සේවාව ස්වයංක්‍රීයව මරා දමනු ඇත, ඒ නිසා මෙය දෝෂ සහිත යැයි මම කියමි.
පැසීරියර්

17
Ac පැසීරියර්, නමුත් පද්ධතිය ක්‍රියාවලිය විනාශ කළහොත් නිදර්ශන ධජය නැවත සැකසෙනු ඇත. මම අනුමාන කරන්නේ ග්‍රාහකයා ඊළඟට පටවන විට (සේවාව killing ාතනය කරන පද්ධතිය පළ කිරීමෙන්) ස්ථිතික ධජය 'නිදසුන' ශුන්‍ය ලෙස ප්‍රතිනිර්මාණය වනු ඇත.
ටොම්

2
MyServiceRunning හි ඇති සියලුම සේවාවන් හරහා නැවත යෙදීමට වඩා අවම වශයෙන් හොඳය, එය සෑම උපාංගයකම භ්‍රමණය වන විට දේවල් ප්‍රමාද කරයි :)
Gunnar Forsgren - Mobimation

1
ඔබගේ නිදර්ශන විචල්‍යය අවසාන ලෙස ප්‍රකාශයට පත් නොකළ යුතුය, එසේ නොමැතිනම් එය onCreate () හෝ onDestroy () ක්‍රම මඟින් සැකසිය නොහැක.
k2col

28

ඔබට මෙය භාවිතා කළ හැකිය (මම මෙය තවම උත්සාහ කර නැත, නමුත් මෙය ක්‍රියාත්මක වේ යැයි මම විශ්වාස කරමි):

if(startService(someIntent) != null) {
    Toast.makeText(getBaseContext(), "Service is already running", Toast.LENGTH_SHORT).show();
}
else {
    Toast.makeText(getBaseContext(), "There is no service running, starting service..", Toast.LENGTH_SHORT).show();
}

දැනටමත් ක්‍රියාත්මක සේවාවක් තිබේ නම් ආරම්භක සේවා ක්‍රමය මඟින් සංරචක නාම වස්තුවක් ලබා දේ. එසේ නොවේ නම්, ශුන්‍යය ආපසු ලබා දෙනු ඇත.

බලන්න රාජ්ය වියුක්ත ComponentName startService (අභිප්රාය සේවා) .

මෙය මා සිතන ආකාරයට පරික්ෂා කිරීමක් නොවේ, මන්ද එය සේවාව ආරම්භ කරන නිසා ඔබට stopService(someIntent);කේතය යටතේ එකතු කළ හැකිය .


11
ලියකියවිලි පවසන දේ හරියටම නොවේ. ඔබගේ සබැඳියට අනුව: "ප්‍රතිලාභ සේවාව ආරම්භ කර තිබේ නම් හෝ දැනටමත් ක්‍රියාත්මක වන්නේ නම්, ආරම්භ කරන ලද සත්‍ය සේවාවේ සංරචක නාමය ආපසු ලබා දෙනු ලැබේ.
ගේබ්‍රියෙල්

හොඳ චින්තනයක් ... නමුත් වර්තමාන තත්වයට නොගැලපේ.
Code_Life

5
එය නිසි ක්‍රමයක් නොවේ, මන්ද IDE ප්‍රේරකය if(startService(someIntent) != null)මඟින් එය පරීක්ෂා කරනු ඇති IsserviceRunningනමුත් එය නව සේවාවක් ඉටු කරනු ඇත.
චින්තාන් කෙතිය

එහි සඳහන් පරිදි, ඔබ මෙම පාලනයෙන් පසු සේවාව නැවැත්වුවහොත් එය මෙම ගැටළුව සඳහා පහසු වනු ඇත. නමුත් කිසිම දෙයක් සඳහා සේවාවක් ආරම්භ කර නැවැත්විය යුත්තේ ඇයි?
ටැනර්

6
මෙය සේවාව ආරම්භ කරනු ඇත, එසේ නොවේ ද? සේවාව ආරම්භ කිරීම වෙනුවට එහි තත්වය පරීක්ෂා කිරීමට අවශ්‍යය ...
රැප්ටර්

26
/**
 * Check if the service is Running 
 * @param serviceClass the class of the Service
 *
 * @return true if the service is running otherwise false
 */
public boolean checkServiceRunning(Class<?> serviceClass){
    ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
    {
        if (serviceClass.getName().equals(service.service.getClassName()))
        {
            return true;
        }
    }
    return false;
}

23

ඇන්ඩ්‍රොයිඩ් ලියකියවිලි වලින් උපුටා ගැනීමක්:

සෙන්ඩ් බ්‍රෝඩ්කාස්ට් (අභිප්‍රාය) මෙන් , නමුත් අභිප්‍රාය සඳහා කිසියම් ග්‍රාහකයක් තිබේ නම් මෙම ක්‍රියාව අවහිර වී නැවත පැමිණීමට පෙර වහාම ඒවා යවනු ලැබේ.

මෙම කඩුල්ල "පිං" ලෙස සිතන්නService . අපට සමමුහුර්තව විකාශනය කළ හැකි බැවින්, අපට UI නූලෙන් සමමුහුර්තව විකාශනය කර ප්‍රති result ලයක් ලබා ගත හැකිය .

Service

@Override
public void onCreate() {
   LocalBroadcastManager
     .getInstance(this)
     .registerReceiver(new ServiceEchoReceiver(), new IntentFilter("ping"));
     //do not forget to deregister the receiver when the service is destroyed to avoid
     //any potential memory leaks 
}

private class ServiceEchoReceiver extends BroadcastReceiver {
    public void onReceive (Context context, Intent intent) {
      LocalBroadcastManager
         .getInstance(this)
         .sendBroadcastSync(new Intent("pong"));
    }
}

Activity

    bool serviceRunning = false;

    protected void onCreate (Bundle savedInstanceState){
        LocalBroadcastManager.getInstance(this).registerReceiver(pong, new IntentFilter("pong"));
        LocalBroadcastManager.getInstance(this).sendBroadcastSync(new Intent("ping"));
        if(!serviceRunning){
           //run the service
        }
    }

    private BroadcastReceiver pong = new BroadcastReceiver(){
        public void onReceive (Context context, Intent intent) {
          serviceRunning = true;   
        }
    }

බොහෝ යෙදුම් ජයග්රාහකයා ලෙස සකසා තිබේ සේවාව මත ස්ථිතික වීජ ක්ෂේත්රයේ නෙවෙයි trueදී Service.onCreate()හා falseදී Service.onDestroy()එය ගොඩක් සරල දෙයක් නිසා.


මෙය පිළිගත් විසඳුමට වඩා හොඳ විසඳුමක් වන අතර එය ගෝලීය විචල්‍ය ක්‍රමවේදය මගින් පෙන්නුම් කරන බැවින් ඇන්ඩ්‍රොයිඩ් සේවාව ills ාතනය කළහොත් එය අසාර්ථක වේ. මෙම සමමුහුර්ත පිං-පොං විකාශන උපක්‍රමය ඇත්ත වශයෙන්ම සේවාවක් ජීවමානද යන්න පරීක්ෂා කිරීමට ඇති එකම විශ්වාසදායක ක්‍රමයයි. සේවාව තිබේ නම් එය සරලව විමසීමට එය ඔබට පමණක් ඉඩ දෙයි. එය පිළිතුරු දෙන්නේ නම්, සේවාව ජීවමානව ක්‍රියාත්මක වන අතර, එසේ නොවුවහොත් එය ආරම්භ කර හෝ වසා දමා තිබේ නම්, ක්‍රමලේඛයෙන් හෝ පද්ධතිය මඟින් මතකය යථා තත්වයට පත් කරයි.
ෆීනික්ස් රිවීල්ඩ්

13

ඉහත ඉදිරිපත් කර ඇති විසඳුම් වලින් එකක් මම තරමක් වෙනස් කර ඇත, නමුත් එකම ක්‍රමයකින් එන නූල් සංසන්දනය කිරීමට වග බලා ගැනීම සඳහා සාමාන්‍ය නූල් නමක් වෙනුවට පන්තිය සමත් වීම class.getName()

public class ServiceTools {
    private static String LOG_TAG = ServiceTools.class.getName();

    public static boolean isServiceRunning(Context context,Class<?> serviceClass){
        final ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
        final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        for (RunningServiceInfo runningServiceInfo : services) {
            Log.d(Constants.TAG, String.format("Service:%s", runningServiceInfo.service.getClassName()));
            if (runningServiceInfo.service.getClassName().equals(serviceClass.getName())){
                return true;
            }
        }
        return false;
    }
}

ඊළගට

Boolean isServiceRunning = ServiceTools.isServiceRunning(
                    MainActivity.this.getApplicationContext(),
                    BackgroundIntentService.class);

දැඩි පැත්තෙන් සිටීමට ඔබට පන්ති Class<? extends Service>
පරාමිතිය

13

සේවාවක් ක්‍රියාත්මක වේදැයි පරීක්ෂා කිරීමට සුදුසුම ක්‍රමය එය සරලව විමසීමයි. ඔබේ ක්‍රියාකාරකම් වලින් පිං වලට ප්‍රතිචාර දක්වන බ්‍රෝඩ්කාස්ට් රිසීවරයක් ඔබේ සේවාවේ ක්‍රියාත්මක කරන්න. සේවාව ආරම්භ වන විට බ්‍රෝඩ්කාස්ට් රිසීවරය ලියාපදිංචි කරන්න, සහ සේවාව විනාශ වූ විට එය ලියාපදිංචි නොකරන්න. ඔබගේ ක්‍රියාකාරකම් වලින් (හෝ ඕනෑම සංරචකයක්), දේශීය විකාශන අභිප්‍රායයක් සේවාවට යවන්න, එය ප්‍රතිචාර දක්වන්නේ නම්, එය ක්‍රියාත්මක වන බව ඔබ දන්නවා. පහත කේතයේ ACTION_PING සහ ACTION_PONG අතර ඇති සියුම් වෙනස සටහන් කරන්න.

public class PingableService extends Service {
    public static final String ACTION_PING = PingableService.class.getName() + ".PING";
    public static final String ACTION_PONG = PingableService.class.getName() + ".PONG";

    public int onStartCommand (Intent intent, int flags, int startId) {
        LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter(ACTION_PING));
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy () {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
        super.onDestroy();
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive (Context context, Intent intent) {
            if (intent.getAction().equals(ACTION_PING)) {
                LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getApplicationContext());
                manager.sendBroadcast(new Intent(ACTION_PONG));
            }
        }
    };
}

public class MyActivity extends Activity {
    private boolean isSvcRunning = false;

    @Override
    protected void onStart() {
        LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getApplicationContext());
        manager.registerReceiver(mReceiver, new IntentFilter(PingableService.ACTION_PONG));
        // the service will respond to this broadcast only if it's running
        manager.sendBroadcast(new Intent(PingableService.ACTION_PING));
        super.onStart();
    }

    @Override
    protected void onStop() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
        super.onStop();
    }

    protected BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive (Context context, Intent intent) {
            // here you receive the response from the service
            if (intent.getAction().equals(PingableService.ACTION_PONG)) {
                isSvcRunning = true;
            }
        }
    };
}

1
මම ඇත්තටම මෙම ප්‍රවේශයට කැමතියි. එය ටිකක් බර කේත wise ානවන්ත නමුත් සෑම විටම ක්‍රියාත්මක වනු ඇත. විකාශන අභිප්‍රායන් ඕනෑම වේලාවක
ක්ෂය වන බවක්

විකාශනයක් මග හැරිය හැකි බව සැලකිල්ලට ගන්න.
දුනා

සහ ... LocalBroadcastManager දැන් අතහැර දමා ඇත ... (රිම්ෂොට්). එය තවමත් හොඳ විසඳුමක්.
ehartwell

8

@Snicolas විසින් පිළිතුරට සටහනක් එක් කිරීමට මට අවශ්‍යය. ඇමතුම් සමඟ / නැතිව නැවතුම් සේවාව පරීක්ෂා කිරීමට පහත පියවර භාවිතා කළ හැකිය onDestroy().

  1. onDestroy() කැඳවනු ලැබුවේ: සැකසීම් වෙත යන්න -> යෙදුම -> සේවා ක්‍රියාත්මක කිරීම -> ඔබේ සේවාව තෝරාගෙන නවත්වන්න.

  2. onDestroy()කැඳවූයේ නැත: සැකසීම් වෙත යන්න -> යෙදුම -> යෙදුම් කළමනාකරණය -> ඔබේ සේවාව ක්‍රියාත්මක වන ඔබගේ යෙදුම තෝරන්න සහ "බල කිරීම නවත්වන්න". කෙසේ වෙතත්, ඔබගේ අයදුම්පත මෙහි නතර කර ඇති බැවින් අනිවාර්යයෙන්ම සේවා අවස්ථා ද නතර වනු ඇත.

අවසාන වශයෙන්, සිංගල්ටන් පන්තියේ ස්ථිතික විචල්‍යයක් භාවිතා කරමින් එහි සඳහන් ප්‍රවේශය මා වෙනුවෙන් ක්‍රියාත්මක වන බව සඳහන් කිරීමට කැමැත්තෙමි.


සේවාව විවිධ ක්‍රියාදාමයන් මත විය හැකිය, මෙය සැලකිල්ලට ගන්න
දුනා

8

onDestroy සැමවිටම සේවයට කැඳවන්නේ නැති නිසා මෙය නිෂ් less ල ය!

උදාහරණයක් ලෙස: සූර්යග්‍රහණයෙන් එක් වෙනසක් සමඟ යෙදුම නැවත ධාවනය කරන්න. SIG: 9 භාවිතයෙන් යෙදුම බලහත්කාරයෙන් ඉවත් වේ.


7

කොට්ලින් භාවිතා කරන තවත් ප්‍රවේශයක්. වෙනත් පරිශීලකයින්ගේ පිළිතුරු වලින් ආශ්වාදයක්

fun isMyServiceRunning(serviceClass: Class<*>): Boolean {
    val manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    return manager.getRunningServices(Integer.MAX_VALUE)
            .any { it.service.className == serviceClass.name }
}

කොට්ලින් දිගුව ලෙස

fun Context.isMyServiceRunning(serviceClass: Class<*>): Boolean {
    val manager = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    return manager.getRunningServices(Integer.MAX_VALUE)
            .any { it.service.className == serviceClass.name }
}

භාවිතය

context.isMyServiceRunning(MyService::class.java)

සටහන: getRunningServicesදැන් ඉවත් කර ඇත, එය හරහා ක්‍රමය මකා නොදමන බව පෙනේ.
ipid

6

පළමුවෙන්ම ඔබ ActivityManager භාවිතා කරමින් සේවාවට ළඟා වීමට උත්සාහ නොකරයි. ( මෙහි සාකච්ඡා කෙරිණි )

සේවාවන් තනිවම ක්‍රියාත්මක විය හැකිය, ක්‍රියාකාරකමකට හෝ දෙකටම බැඳී සිටිය යුතුය. ඔබේ සේවාව ක්‍රියාත්මක වන්නේද නැද්ද යන්න ක්‍රියාකාරකම පරීක්ෂා කර බැලීමේ ක්‍රමය නම්, ක්‍රියාකාරකම් සහ සේවාව යන දෙකම තේරුම් ගත හැකි ක්‍රම ප්‍රකාශ කරන අතුරු මුහුණතක් (බයින්ඩර් දිගු කරයි). උදාහරණයක් ලෙස "isServiceRunning ()" යනුවෙන් ප්‍රකාශ කරන ඔබේම අතුරු මුහුණතක් සාදා ගැනීමෙන් ඔබට මෙය කළ හැකිය. එවිට ඔබට ඔබේ ක්‍රියාකාරකම ඔබේ සේවාවට බැඳ තැබිය හැකිය, එය ක්‍රියාත්මක වන්නේ සේවා රනිං (), එය ක්‍රියාත්මක වන්නේද නැද්ද යන්න සේවාව විසින්ම පරීක්ෂා කර බලා ඔබේ ක්‍රියාකාරකමට බූලියනයක් ලබා දෙයි.

ඔබේ සේවාව නැවැත්වීමට හෝ වෙනත් ආකාරයකින් එය සමඟ අන්තර් ක්‍රියා කිරීමට ඔබට මෙම ක්‍රමය භාවිතා කළ හැකිය.

මගේ යෙදුම තුළ මෙම තත්වය ක්‍රියාත්මක කරන්නේ කෙසේදැයි දැන ගැනීමට මම මෙම නිබන්ධනය භාවිතා කළෙමි .


3
එම සාකච්ඡාව '12 / 26/07 'හිදී සිදුවිය. එක්කෝ එය මේ වසරේ ජූලි (එනම් අනාගතයේදී) හෝ ඇන්ඩ්‍රොයිඩ් ප්‍රසිද්ධ වීමට පෙරය. කෙසේ හෝ මා එය විශ්වාස නොකරයි.
ටොම්

ඒ සාකච්ඡාවට 2007 දෙසැම්බර් 26, සිට ඔවුන් පෙර නිකුතුවේ අනුවාදය මම හිතන්නේ (සාකච්ඡා කරන ඇත developer.android.com/sdk/OLD_RELEASENOTES.html#m3-rc37a දෙසැම්බර් 14, 2007 දින නිකුත් කරන ලද)
ingh.am

6

නැවතත්, අපේක්ෂිත අභිප්‍රායන් භාවිතා කරන්නේ නම් මිනිසුන් පිරිසිදු බව සොයා ගත හැකි තවත් විකල්පයක් (උදාහරණයක් ලෙස AlarmManager:

public static boolean isRunning(Class<? extends Service> serviceClass) {
    final Intent intent = new Intent(context, serviceClass);
    return (PendingIntent.getService(context, CODE, intent, PendingIntent.FLAG_NO_CREATE) != null);
}

CODEඔබේ සේවාවට සම්බන්ධ අපේක්ෂිත අභිප්‍රායන් හඳුනා ගැනීම සඳහා ඔබේ පන්තියේ පුද්ගලිකව නිර්වචනය කරන නියතයක් කොහිද?


1
ඔබගේ පෙර පිළිතුර ඒකාබද්ධ හෝ යාවත්කාලීන කරන්න. කරුණාකර එක් තනතුරකට පිළිතුරු එකකට වඩා පළ කිරීමෙන් වළකින්න.
චුවාංෆෑම්

මෙම පිළිතුර පුළුල් කළ හැකිද, එනම් යමෙකු CODE සඳහා වන අගය සේවාව සමඟ සම්බන්ධ කරන්නේ කෙසේද?
ඩේව් නොටේජ්

සන්දර්භය ලබා ගන්නේ කොහෙන්ද?
බැසිල්

6

පහත දැක්වෙන්නේ සියල්ල ආවරණය වන අලංකාර හැක් ය Ifs. මෙය දේශීය සේවාවන් සඳහා පමණි.

    public final class AService extends Service {

        private static AService mInstance = null;

        public static boolean isServiceCreated() {
            try {
                // If instance was not cleared but the service was destroyed an Exception will be thrown
                return mInstance != null && mInstance.ping();
            } catch (NullPointerException e) {
                // destroyed/not-started
                return false;
            }
        }

        /**
         * Simply returns true. If the service is still active, this method will be accessible.
         * @return
         */
        private boolean ping() {
            return true;
        }

        @Override
        public void onCreate() {
            mInstance = this;
        }

        @Override
        public void onDestroy() {
            mInstance = null;
        }
    }

පසුව:

    if(AService.isServiceCreated()){
        ...
    }else{
        startService(...);
    }

මෙහි ඇති එකම ගැටළුව වන්නේ සේවාව ඇලෙන සුළු සේවාවක් වන අතර එය නැවත ආරම්භ වේ. සේවාව නැවත ආරම්භ කිරීමෙන් පසු isServiceCreated () වෙත ඇමතීම සාවද්‍ය වනු ඇත, මන්ද mInstance අහෝසි වනු ඇත.
මිරා_කෝල්

1
සේවාව නැවත ආරම්භ වූ විට onCreate අමතන්නේ නැද්ද?
TheRealChx101

6

Xamarin C # අනුවාදය:

private bool isMyServiceRunning(System.Type cls)
{
    ActivityManager manager = (ActivityManager)GetSystemService(Context.ActivityService);

    foreach (var service in manager.GetRunningServices(int.MaxValue)) {
        if (service.Service.ClassName.Equals(Java.Lang.Class.FromType(cls).CanonicalName)) {
            return true;
        }
    }
    return false;
}

ඔබට ontContext` අවශ්‍ය GetSystemServiceවේ.
පරීක්ෂා කිරීම

5

මෙහි දක්වා ඇති භාවිත අවස්ථාව සඳහා, අපි stopService()ක්‍රමයේ ප්‍රතිලාභ අගය භාවිතා කළ හැකිය . trueනිශ්චිත සේවාවක් තිබේ නම් එය නැවත පැමිණේ . නැතහොත් එය නැවත පැමිණේ false. එබැවින් ඔබට සේවාව නැවත ආරම්භ කළ හැකිය ප්‍රති result falseලය වෙනත් නම් වත්මන් සේවාව නතර කර ඇති බවට සහතික වේ. :) ඔබ දෙස තිබේ නම් එය වඩාත් හොඳ වනු ඇත මෙම .


4

කොට්ලින්හිදී ඔබට සහායක වස්තුවක බූලියන් විචල්‍යය එක් කළ හැකි අතර ඔබට අවශ්‍ය ඕනෑම පන්තියකින් එහි වටිනාකම පරීක්ෂා කළ හැකිය:

companion object{
     var isRuning = false

}

සේවාව නිර්මාණය කර විනාශ වූ විට එහි අගය වෙනස් කරන්න

 override fun onCreate() {
        super.onCreate()
        isRuning = true
    }

override fun onDestroy() {
    super.onDestroy()
    isRuning = false
    }

3

GeekQ හි ප්‍රතිචාරය නමුත් කොට්ලින් පන්තියේ. ස්තූතියි geekQ

fun isMyServiceRunning(serviceClass : Class<*> ) : Boolean{
    var manager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
        if (serviceClass.name.equals(service.service.className)) {
            return true
        }
    }
    return false
}

ඇමතුම

isMyServiceRunning(NewService::class.java)

7
ActivityManager.getRunningServicesඇන්ඩ්‍රොයිඩ් ඕ
ඩැනියෙල් ෂට්ස්

3

ඔබගේ සේවා උප පංතියේ පහත දැක්වෙන පරිදි සේවාවේ තත්වය ලබා ගැනීම සඳහා ස්ථිතික බූලියන් භාවිතා කරන්න.

MyService.kt

class MyService : Service() {
    override fun onCreate() {
        super.onCreate()
        isServiceStarted = true
    }
    override fun onDestroy() {
        super.onDestroy()
        isServiceStarted = false
    }
    companion object {
        var isServiceStarted = false
    }
}

MainActivity.kt

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

        val serviceStarted = FileObserverService.isServiceStarted
        if (!serviceStarted) {
            val startFileObserverService = Intent(this, FileObserverService::class.java)
            ContextCompat.startForegroundService(this, startFileObserverService)
        }
    }
}

3

කොට්ලින් සඳහා, ඔබට පහත කේතය භාවිතා කළ හැකිය.

fun isMyServiceRunning(calssObj: Class<SERVICE_CALL_NAME>): Boolean {
    val manager = requireActivity().getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    for (service in manager.getRunningServices(Integer.MAX_VALUE)) {
        if (calssObj.getName().equals(service.service.getClassName())) {
            return true
        }
    }
    return false
}

ඔබේ වැඩ කිරීමේ කේතය වෙනස් නොකර ඔබට එය භාවිතා කළ හැකි බැවින්, පරීක්ෂණ ලිවීම සඳහා මෙය හොඳ පිළිතුරකි.
රොබට් ලිබරටෝර්

1

එකම පන්ති නාමයක් සහිත සේවාවන් කිහිපයක් තිබිය හැකිය.

මම දැන් යෙදුම් දෙකක් නිර්මාණය කර ඇත. පළමු යෙදුමේ පැකේජයේ නම වේ com.example.mock. මම loremයෙදුම තුළ කැඳවූ උප පැකේජයක් සහ සේවාවක් නමින් නිර්මාණය කළෙමි Mock2Service. එබැවින් එහි සම්පූර්ණ සුදුසුකම් ලත් නම වේ com.example.mock.lorem.Mock2Service.

ඉන්පසු මම දෙවන යෙදුම සහ සේවාවක් නිර්මාණය කළෙමි Mock2Service. දෙවන යෙදුමේ පැකේජයේ නම වේ com.example.mock.lorem. සේවාවේ සම්පූර්ණ සුදුසුකම් ලත් නම com.example.mock.lorem.Mock2Serviceද වේ.

මෙන්න මගේ ලොග් කැට් ප්‍රතිදානය.

03-27 12:02:19.985: D/TAG(32155): Mock-01: com.example.mock.lorem.Mock2Service
03-27 12:02:33.755: D/TAG(32277): Mock-02: com.example.mock.lorem.Mock2Service

වඩා හොඳ අදහසක් සන්සන්දනය කිරීම යනු ComponentNameනිසා අවස්ථා equals()පිළිබඳ ComponentNameදෙකම පැකේජය නම් හා පන්ති නම් සසඳයි. උපාංගයක එකම පැකේජ නාමයක් සහිත යෙදුම් දෙකක් ස්ථාපනය කළ නොහැක.

හි සමාන () ක්‍රමය ComponentName.

@Override
public boolean equals(Object obj) {
    try {
        if (obj != null) {
            ComponentName other = (ComponentName)obj;
            // Note: no null checks, because mPackage and mClass can
            // never be null.
            return mPackage.equals(other.mPackage)
                    && mClass.equals(other.mClass);
        }
    } catch (ClassCastException e) {
    }
    return false;
}

සංරචක නාමය


1

TheServiceClass ඇතුලත අර්ථ දක්වන්න:

 public static Boolean serviceRunning = false;

ඉන්පසු InStartCommand (...)

 public int onStartCommand(Intent intent, int flags, int startId) {

    serviceRunning = true;
    ...
}

 @Override
public void onDestroy()
{
    serviceRunning = false;

} 

ඉන්පසු if(TheServiceClass.serviceRunning == true)ඕනෑම පන්තියකින් අමතන්න .


5
ඔබගේ සේවය ඇන්ඩ්‍රොයිඩ් විසින් විනාශ වුවහොත් මෙය ක්‍රියාත්මක නොවේ.
හයිසන්බර්ග්

Is හයිසන්බර්ග් මම එය අත්විඳිමි. ඔබ දන්නවාද ඇයි නැත්තේ කියලා?
ටිම්

App හයිසන්බර්ග් මගේ යෙදුම මෙහෙයුම් පද්ධතිය විසින් killed ාතනය කළ විට, සේවාව නැවත ආරම්භ කර ස්ථිතික බූල් සත්‍ය බවට පත් කරයි, නමුත් එය ලැබීමෙන් පසු එය අසත්‍ය බව වාර්තා වේ
ටිම්

ඔබ ඇමතුමක් ගත්තොත් මෙය ක්‍රියා නොකරනු ඇත stopService. අවම වශයෙන් අභිප්‍රාය සේවා සඳහා. onDestroy()වහාම කැඳවනු ඇත, නමුත් onHandleIntent()තවමත් ක්‍රියාත්මක වේ
serggl

2
E හයිසන්බර්ග් අඩු මතකය හේතුවෙන් සේවාව killing ාතනය නොකිරීම යන්නෙන් අදහස් කරන්නේ ක්‍රියාවලිය killing ාතනය කිරීම නොවේද?
ඇන්ඩ්‍රොයිඩ් සංවර්ධක

1

කරුණාකර මෙම කේතය භාවිතා කරන්න.

if (isMyServiceRunning(MainActivity.this, xyzService.class)) { // Service class name
    // Service running
} else {
    // Service Stop
}


public static boolean isMyServiceRunning(Activity activity, Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

getRunningServices ඇන්ඩ්‍රොයිඩ් ඕ
ඩූනා

0

මෙය නූල් බිහි වූ බැවින් අභිප්‍රාය සේවා නිදොස්කරණය සඳහා මෙය වඩාත් අදාළ වේ, නමුත් සාමාන්‍ය සේවාවන් සඳහාද එය ක්‍රියා කරයි. මම මේ ත්‍රෙඩ් එක හොයාගත්තේ බිංගිංට ස්තූතියි

මගේ නඩුවේදී, මම නිදොස්කරණය සමඟ සෙල්ලම් කර නූල් දර්ශනය සොයා ගතිමි. එය එම්එස් වර්ඩ් හි බුලට් පොයින්ට් නිරූපකය මෙන් පෙනේ. කෙසේ වෙතත්, එය භාවිතා කිරීම සඳහා ඔබ නිදොස් කිරීමේ මාදිලියේ සිටිය යුතු නොවේ. ක්‍රියාවලිය මත ක්ලික් කර එම බොත්තම ක්ලික් කරන්න. ඕනෑම අභිප්‍රාය සේවාවක් ක්‍රියාත්මක වන විට අවම වශයෙන් ඉමුලේටරය මත පෙන්වනු ඇත.


0

සේවාව වෙනත් ක්‍රියාවලියකට අයත් නම් හෝ APK විසින් ActivityManager මත පදනම් වූ විසඳුම භාවිතා කරන්න.

ඔබට එහි ප්‍රභවයට ප්‍රවේශය ඇත්නම්, ස්ථිතික ක්ෂේත්‍රයක් මත පදනම්ව විසඳුම භාවිතා කරන්න. නමුත් බූලියන් භාවිතා කිරීම වෙනුවට දිනය වස්තුවක් භාවිතා කිරීමට මම යෝජනා කරමි. සේවාව ක්‍රියාත්මක වන අතරතුර, එහි වටිනාකම 'දැන්' ලෙස යාවත්කාලීන කර එය අවසන් වූ විට එය අහෝසි කරන්න. ක්‍රියාකාරකමෙන් ඔබට එහි ශුන්‍යය හෝ දිනය ඉතා පැරණි දැයි පරීක්ෂා කළ හැකිය, එයින් අදහස් වන්නේ එය ක්‍රියාත්මක නොවන බවයි.

ප්‍රගතිය වැනි වැඩිදුර තොරතුරු සමඟ ක්‍රියාත්මක වන බව දක්වමින් ඔබේ සේවාවෙන් විකාශන දැනුම් දීමක් ඔබට එවිය හැකිය.


0

ස්වයංක්‍රීයව නිර්මාණය නොකරන්න සරල භාවිතය - ps බලන්න. යාවත්කාලීන කරන්න ...

public abstract class Context {

 ... 

  /*
  * @return {true} If you have successfully bound to the service, 
  *  {false} is returned if the connection is not made 
  *  so you will not receive the service object.
  */
  public abstract boolean bindService(@RequiresPermission Intent service,
        @NonNull ServiceConnection conn, @BindServiceFlags int flags);

උදාහරණයක් :

    Intent bindIntent = new Intent(context, Class<Service>);
    boolean bindResult = context.bindService(bindIntent, ServiceConnection, 0);

භාවිතා නොකරන්නේ ඇයි? getRunningServices ()

List<ActivityManager.RunningServiceInfo> getRunningServices (int maxNum)
Return a list of the services that are currently running.

සටහන: මෙම ක්‍රමය අදහස් කරන්නේ සේවා කළමනාකරණ වර්ගයේ පරිශීලක අතුරුමුහුණත් නිදොස් කිරීම හෝ ක්‍රියාත්මක කිරීම සඳහා පමණි.


ps. ඇන්ඩ්‍රොයිඩ් ප්‍රලේඛනය නොමඟ යවන සුළු සැකයක් දුරු කිරීම සඳහා මම ගූගල් ට්‍රැකර් හි ගැටලුවක් විවෘත කර ඇත්තෙමි.

https://issuetracker.google.com/issues/68908332

අපට දැකිය හැකි පරිදි, බන්ධන සේවාව ඇත්ත වශයෙන්ම ඇක්ටිව් මැනේජර් බයින්ඩර් හරහා සේවා හැඹිලි බයින්ඩර් හරහා ගනුදෙනුවක් සිදු කරයි - බන්ධනය සඳහා වගකිව යුත්තේ කුමන සේවාවද යන්න මම සොයා බලමි.

int res = ActivityManagerNative.getDefault().bindService(...);
return res != 0;

ගනුදෙනුව සිදු කරනු ලබන්නේ බයින්ඩර් හරහා ය:

ServiceManager.getService("activity");

ඊලඟ:

  public static IBinder getService(String name) {
    try {
        IBinder service = sCache.get(name);
        if (service != null) {
            return service;
        } else {
            return getIServiceManager().getService(name);

මෙය ක්‍රියාකාරකම් ත්‍රෙඩ් හි සකසා ඇත්තේ:

 public final void bindApplication(...) {

        if (services != null) {
            // Setup the service cache in the ServiceManager
            ServiceManager.initServiceCache(services);
        }

මෙය ක්‍රමවේදය ලෙස ActivityManagerService ලෙස හැඳින්වේ:

 private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
    ...
    thread.bindApplication(... , getCommonServicesLocked(),...)

එවිට:

 private HashMap<String, IBinder> getCommonServicesLocked() {

නමුත් "ක්‍රියාකාරකම්" නොමැත කවුළු පැකේජය සහ අනතුරු ඇඟවීම පමණි ..

එබැවින් අපට නැවත ඇමතුමක් ලබා ගත යුතුය:

 return getIServiceManager().getService(name);

    sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());

මෙය හරහා ඇමතුමක් ලබා දෙයි:

    mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);

එයට හේතු වන්නේ:

BinderInternal.getContextObject()

මෙය ස්වදේශීය ක්‍රමයයි ....

  /**
     * Return the global "context object" of the system.  This is usually
     * an implementation of IServiceManager, which you can use to find
     * other services.
     */
    public static final native IBinder getContextObject();

සී හාරා ගැනීමට මට දැන් වෙලාවක් නැත, එබැවින් මම විවේක ඇමතුම විසුරුවා හරින තෙක් මගේ පිළිතුර අත්හිටුවමි.

නමුත් සේවාව ක්‍රියාත්මක වේදැයි පරීක්ෂා කිරීම සඳහා හොඳම ක්‍රමය නම් බන්ධනය නිර්මාණය කිරීමයි (බන්ධනය නිර්මාණය කර නොමැති නම් සේවාව නොපවතී) - සහ බන්ධනය හරහා එහි තත්වය පිළිබඳව විමසන්න (එහි ගබඩා කර ඇති අභ්‍යන්තර ධජය භාවිතා කරමින්).

යාවත්කාලීන කිරීම 23.06.2018

මම ඒවා සිත්ගන්නාසුලු විය:

/**
 * Provide a binder to an already-bound service.  This method is synchronous
 * and will not start the target service if it is not present, so it is safe
 * to call from {@link #onReceive}.
 *
 * For peekService() to return a non null {@link android.os.IBinder} interface
 * the service must have published it before. In other words some component
 * must have called {@link android.content.Context#bindService(Intent, ServiceConnection, int)} on it.
 *
 * @param myContext The Context that had been passed to {@link #onReceive(Context, Intent)}
 * @param service Identifies the already-bound service you wish to use. See
 * {@link android.content.Context#bindService(Intent, ServiceConnection, int)}
 * for more information.
 */
public IBinder peekService(Context myContext, Intent service) {
    IActivityManager am = ActivityManager.getService();
    IBinder binder = null;
    try {
        service.prepareToLeaveProcess(myContext);
        binder = am.peekService(service, service.resolveTypeIfNeeded(
                myContext.getContentResolver()), myContext.getOpPackageName());
    } catch (RemoteException e) {
    }
    return binder;
}

කෙටියෙන් :)

"දැනටමත් බැඳී ඇති සේවාවක් සඳහා බන්ධකයක් ලබා දෙන්න. මෙම ක්‍රමය සමමුහුර්ත වන අතර ඉලක්කගත සේවාව නොමැති නම් එය ආරම්භ නොකරනු ඇත."

public IBinder peekService (අභිප්‍රාය සේවාව, String resolvedType, String callPackage) දුරස්ථ එක්සෙප්ෂන් විසි කරයි;

*

public static IBinder peekService(IBinder remote, Intent service, String resolvedType)
             throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken("android.app.IActivityManager");
    service.writeToParcel(data, 0);
    data.writeString(resolvedType);
    remote.transact(android.os.IBinder.FIRST_CALL_TRANSACTION+84, data, reply, 0);
    reply.readException();
    IBinder binder = reply.readStrongBinder();
    reply.recycle();
    data.recycle();
    return binder;
}

*


සේවාව ක්‍රියාත්මක නොවන්නේ නම් bindResult (bindService ක්‍රමයේ ප්‍රතිලාභ අගය) අසත්‍ය නොවේ.
ෂන්ගෙත් සිවන්

0

මගේ කෝට්ලින් ActivityManager::getRunningServicesපදනම් කරගත් පිළිතුරු පරිවර්තනය කිරීම . මෙම ශ්‍රිතය ක්‍රියාකාරකමකට දමන්න-

private fun isMyServiceRunning(serviceClass: Class<out Service>) =
    (getSystemService(ACTIVITY_SERVICE) as ActivityManager)
        .getRunningServices(Int.MAX_VALUE)
        ?.map { it.service.className }
        ?.contains(serviceClass.name) ?: false

0

සේවාවක් ක්‍රියාත්මක වන්නේ දැයි හඳුනාගත හැකි එකම කාර්යක්ෂම / වේගවත් / පිරිසිදු ක්‍රමය වන්නේ PING / PONG ක්‍රියාකාරීත්වයක් නිර්මාණය කිරීමයි.

සේවාව තුළ මැසෙන්ජර් හෝ ඒඩ්ස් ක්‍රමය ක්‍රියාත්මක කරන්න: isAlive()- එමඟින් සේවාවේ තත්වය නැවත ලබා දේ.

එපා නොවන ඔවුන් අහිමි කළ හැකි බැවින් විකාශන ක්රියාත්මක කිරීම.


-3

ඔබගේ සේවාව තවමත් පසුබිමේ ක්‍රියාත්මක වේදැයි බැලීමට ඔබට ඇන්ඩ්‍රොයිඩ් සංවර්ධක විකල්පයන්ගෙන් මෙම විකල්ප භාවිතා කළ හැකිය.

1. Open Settings in your Android device.
2. Find Developer Options.
3. Find Running Services option.
4. Find your app icon.
5. You will then see all the service that belongs to your app running in the background.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.