web-dev-qa-db-ja.com

bindServiceメソッドの後にonServiceConnectedが呼び出されることはありません

特定の状況があります。放送受信機によって開始されたサービスがアクティビティを開始します。このアクティビティがサービスに通信できるようにしたいと考えています。私はそれを可能にするためにAIDLを使用することを選択しました。アクティビティのbindService()で呼び出されるonCreate()メソッドを除いて、すべてがうまく機能しているようです。 bindService()は実際には、サービスのonServiceConnected()メソッドが呼び出されている間はonBind()が呼び出されないため、nullポインタ例外をスローします。とにかくbindService()はtrueを返します。アクティビティを開始するため、サービスは明らかにアクティブです。サービスからアクティビティを呼び出すのは奇妙に聞こえるかもしれませんが、残念ながらこれがサービスで音声認識を行う唯一の方法です。

前もって感謝します

33
Matroska

私はあなたの説明から正確な問題を解決することができないので、ここで推測します!

bindService()はどのようにNullPointerExceptionをスローできますか?これが発生する可能性のある唯一の方法は、ServiceまたはServiceConnectionリスナーを指定しない場合です。

bindService()NullPointerExceptionをスローできません原因onServiceConnected()は呼び出されません。 onServiceConnected()の呼び出しは、bindService()の結果です。

AIDLが実際に結合する前に、Serviceメソッドを呼び出していると思いますか?

13
MrSnowflake

onServiceConnected(...)が呼び出されないのと同じ症状で、この問題の別のバージョンが発生しました。私の場合、原因は異なりました。

アプリケーションタグ内のAndroidManifest.xmlにサービス宣言があることを確認する必要があります-これが問題の原因でした。

_<application Android:name=".YourAppTitle" Android:icon="@drawable/icon" Android:label="@string/app_name">
    <activity Android:name=".Main" Android:label="@string/app_name">
    </activity>
    <service Android:name="YourService" />
</application>
_

別のAndroidライブラリを使用している場合、さらに複雑になります。このサービスタグを追加しても、参照されているサービスがマニフェストと同じパッケージにある場合のみ問題が解決するようです。アプリがパッケージabcにあり、ここにAndroidManifest.xmlが存在する場合、 'YourService'もパッケージabc(必要に応じて別のライブラリから手動でコピー)になければなりません。そうでない場合、_<service..>_タグは無視される/ onServiceConnected(...)はまだ呼び出されません。

コードでサービスに適切なインポートステートメントを使用した場合でも、これは私のプロジェクトの場合でした。 Eclipseはエラーを表示しなかったため、インポートはEclipseワークスペース内の別のライブラリーからのクラスを正しく識別していました。

HTH

45
KomodoDave

何時間もこれを理解しようとすると、問題は、サービスの作成を示す例にonBindメソッドが含まれていないか、次のサンプルコードがあるか、または生成されます。

public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

これにより、onServiceConnectedメソッドが失敗するか、実際には実行されません。修正は非常に簡単で、次のとおりです。

public IBinder onBind(Intent intent) {
    return mBinder;
}

次のような単純なバインダーを作成して返すことができる場所:

private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
    public ConferenceService getService() {
    return ConferenceService.this;
  }
}
42
Brad Brown

onServiceConnectedイベントがアプリケーションで呼び出されませんでした。

問題は、アプリケーションマニフェストでサービス名を次のように定義していることです。

<service Android:name="MyService" Android:enabled="true"></service>

完全なクラス名に変更したら、うまくいきました:

<service Android:name="com.example.MyService" Android:enabled="true"></service>

pdate:相対クラス名を使用することもできます。

<service Android:name=".MyService" Android:enabled="true"></service>

MyServiceClassの代わりに、完全なcom.example.MyServiceClassを使用してクラス名を指定します。

26
IanGSY

もう1つは、bindserviceメソッド内でoncreateメソッドを呼び出す場合、onserviceconnectedメソッドが終了した後にoncreateが呼び出されることです。

したがって、oncreateが終了する前(またはonserviceconnectedが呼び出される前)にインターフェイス関数を参照すると、nullポインタ例外が発生します。

8
Abhijeet

元の質問のもう1つの原因は、サービスがまだ実行されておらず、bindServiceにフラグとして0を渡していることです。そのようです:

bindService(intent, serviceConnection, 0);

あなたが探しているのは:

bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
5
pakerfeldt

それほど頻繁ではないが、別の説明があるかもしれませんが、私はなんとかそれに入って、それを解決するために2時間を費やしました。

それで私がしたことは、onBindメソッドが受け取ったインテントからバンドルを再利用したかったということです。しかし、私は遅延バージョンに行き、インテントのクラスを変更しました。これにより、onServiceConnectedが呼び出されないようです。システムがインテントへの参照を保持し、onServiceConnectedを呼び出すときにそれを使用するためと考えられます。

結論として、onBindで受け取るインテントを変更しないでください。

1

OnCreate()メソッドが完了するまで待つ必要があります。例:Buttomでの購入サービスの設定:

Button button_useservice=findViewById(R.id.button_useservice);
            button_useservice.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    UsinService();
                }
            });

空のインテント-getContext().bindService(new Intent(), mConnection, Context.BIND_AUTO_CREATE)でbindを呼び出していました。バインドしたいサービスを示すために、意図をより具体的にする必要があります。これは明らかにコードエラーですが、Logcatの出力は残念ながら十分に明確ではありませんでした。

0
Gallal

他のすべてを試した後でも誰かが答えを探しているなら、これは役立つかもしれません。onServiceConnected()は呼び出されません すぐに bindService(...)の後。数秒かかります。したがって、onServiceConnected()から値を受け取り、onCreateまたはonStartの別の場所で使用する必要がある場合は、次の理由によりNullPointerExceptionがスローされます。 ディレイ。したがって、onServiceConnected(){......}内のonCreateまたはonStartからの値を必要とするコード行を、必要な値の宣言行の下にシフトできる場合うまくいくかもしれません。

0
Rohan buddy