3

セットアップ: にデータをフィードするカスタム アダプターListView。データは、外部サービスによって計算されたいくつかの数値に基づいています。AIDL を使用してサービスをバインドし、必要なデータを取得しています。

問題: サービスのバインドを解除するタイミングを知るにはどうすればよいですか? 接続はアダプタ自体に対してプライベートであり、アプリケーション全体がシャットダウンしていることを検出する唯一の方法はオーバーライドunregisterDataSetObserverです。または、少なくとも別の方法が見つかりませんでした。これは、コンテンツプロバイダーとコンテンツオブザーバーを使用して同じアダプターでうまく機能しました。ただし、AIDL では機能しませんServiceConnectionLeaked。エラーが発生します。

「unbindFromService」メソッドをアダプターに追加して、アクティビティの onDestroy() から呼び出すことができることはわかっていますが、それは私にとって十分にエレガントではありません。可能であれば、「正直な」トリガーを希望します。

4

3 に答える 3

4

CustomAdapter に実装ActivityLifecycleCallbacksしてから、アクティビティ呼び出しから実装します

mAdapter.setActivity(this);

アダプタ クラス

public class CustomAdapter  extends ArrayAdapter<String> implements ActivityLifecycleCallbacks{

    Activity mActivity;

    public void setActivity(Activity activity) {
           /* or you could remove setactivity and do below operation in Constructor */
        mActivity = activity;
        mActivity.getApplication().registerActivityLifecycleCallbacks(this);
    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        /*unregister so that you do not get callbacks after activity is destroyed*/
        if(activity instanceof MainActivity)   
              mActivity.getApplication().unregisterActivityLifecycleCallbacks(this);

            /*unregister your activity or in any other callbacks*/
    }

    /* skipped other dummy functions*/

}
于 2013-02-20T20:37:32.060 に答える
1

Connection is private to adapter間違っている。Adapter は Context-less であるため、サービスを adapter に対して非公開にすることはできません

アダプターは、Context なしではサービスにバインドできません。本質的に、アダプターがサービスにバインドするための Context を提供する関数があります。したがって、バインドされた接続はアダプタに対してプライベートではありません。その作成を許可したのは、渡されたコンテキストです。

本当の問題は、文脈を聞く方法がないということです。つまり、アダプター内にコンテキスト インスタンスを保持しているとします。アダプターがこのコンテキストをリッスンし、何らかの形でアクティビティが完了したことを認識できるようにする方法はありません。これにより、エレガントではない解決策を受け入れることになります。アクティビティは、そのコンテキストを使用しているアダプターに通知する必要があります。そうしないと、よりハッキングされたソリューションになってしまいます。


コメントの議論全体が、「サービスはアダプターに対してプライベートである」ことを扱っていることに注意してください。実際には、これを行うエレガントな方法は、接続を提供する ServiceProvider インターフェイスを用意することであり、これはアクティビティによって実装されます。アダプターは、渡された ServiceProvider で初期化する必要があります。一部の関数は と にgetConnectionなりisRunningます。このようにして、アダプターが使用している間、アクティビティが接続を処理します。(同期)

于 2013-02-20T08:42:47.350 に答える
1

Service を使用して新しいデータを SQLite テーブルに挿入したり、ContentProvider を更新したりしてから、SimpleCursorAdapter (後方互換性のある android.support.v4.widget.SimpleCursorAdapter) と LoaderManager、SQLiteCursorLoader/CursorLoader、Loader パターンを使用して表示しますList または ListFragment のデータ。

SQLiteCursorLoader は Android SDK では提供されていませんが、Mark Murphy が GitHub で使用しているため、ローカルの SQLite DB に新しいデータを永続化したい場合は、これを参照してください。

Service は SQLite の基になるデータとリストのアダプターから独立している可能性があるため、新しいデータの挿入またはプロバイダーの更新が完了したらバインドを解除できるため、推奨されるパターンに従ってサービスのバインドを解除できます (この質問を参照してください: Android:サービスを安全にバインド解除する方法) を参照し、http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle を参照してください

これがヒントになることを本当に願っています。幸運を!

于 2013-02-21T06:37:38.093 に答える