web-dev-qa-db-ja.com

Android:サービスが経由しているかどうかを確認します。 bindService

Androidサービスが実行されているかどうかを確認する最良の方法は何ですか?ActivityManager AP​​Iは知っていますが、APIの使用は推奨されていないようです私のようなシナリオ( source )です。サービスの状態を維持するためにグローバル変数または永続変数を使用する可能性も知っています。

フラグを0に設定してbindServiceを使用しようとしましたが、sourceリンク上の人と同じ問題が発生しました(唯一の例外)だった、私はbindServiceをローカルサービスで試していた)。

次の呼び出し

getApplicationContext().bindService(new Intent(getApplicationContext(),
        MyService.class), mServiceConnection, 0);

常にtrueを返しますが、接続されません。これは予想される動作ですか? bindServiceは、サービスがまだ実行されていない場合(そうでない場合、確認しました)、またはBIND_AUTO_CREATEフラグが設定されていない場合(再度設定されていない場合)は、falseを返します。

20
Igor

同じ問題があります。最もよく知られている解決策は、WhateverServiceでpublic staticブール値を作成することです。onCreate(またはonStartCommand、選択)中にtrueに設定し、onDestroy中にfalseに設定します。その後、同じapkの他のクラスからアクセスできます。しかし、これは危険かもしれません。 Android=)内にAPIはなく、サービスが実行されているかどうかを確認します(副作用なし):参照 http://groups.google.com/group/Android-developers/browse_thread/thread/8c4bd731681b8331/bf3ae8ef79cad75d

競合状態は、OSがいつでも(別のプロセスの)リモートサービスを強制終了する可能性があるという事実に起因すると思います。上で提案したように、ローカルサービス(同じプロセス)をチェックすることは、私にはレースフリーのようです-OSがサービスを強制終了すると、ステータスをチェックしたものもすべて強制終了します。

11
bryanr

共有設定を使用して、サービス実行フラグを保存します。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    int res = super.onStartCommand(intent, flags, startId);
    setRunning(true);
    return res;
}

@Override
public void onDestroy() {
    super.onDestroy();
    setRunning(false);
}

private void setRunning(boolean running) {
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    SharedPreferences.Editor editor = pref.edit();

    editor.putBoolean(PREF_IS_RUNNING, running);
    editor.apply();
}

public static boolean isRunning(Context ctx) {
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(ctx.getApplicationContext());
    return pref.getBoolean(PREF_IS_RUNNING, false);
}

別の方法:

public static boolean isServiceRunning(Context ctx, String serviceClassName) {
    ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (TrackingService.class.getName().equals(serviceClassName)) {
            return true;
        }
    }
    return false;
}

同じ必要性があり、すでにバインドされている何かで.bindServiceを実行すると、エラーが発生することがわかりました。 .bindServiceを実行する直前にこれを行いました

try{
    context.unbindService(fetch_connection);
} catch (IllegalArgumentException e){
    System.out.println("Unbinding didn't work. little surprise");
}
1
atraudes
0
Kevin Parker

あなたの活動であなたは単に私の場合あなたのサービスのインスタンスを使ってそれをチェックすることができます

  button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent intent=new Intent(MainActivity.this, MyService.class);
            //startService(intent);
            bindService(intent,serviceConnection,BIND_AUTO_CREATE);
            if (myService!=null)
            {
                myService.RecData(editText.getText().toString());
            }
        }
    });
}

ServiceConnection serviceConnection=new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        Toast.makeText(MainActivity.this,"onServiceConnected called",Toast.LENGTH_SHORT).show();
        MyService.MyBinder myBinder= (MyService.MyBinder) iBinder;
        myService= myBinder.getServiceInstant();
        myService.SetActivity(MainActivity.this);
        myService.RecData(editText.getText().toString());
    }
0
The Black Horse