9

私は音楽プレーヤーをプログラミングしていて、音楽はバックグラウンドで再生されますService。ユーザーがActivityホスト3を強制終了しFragments、再度再起動すると、現在再生中の曲に関する情報と、ユーザーがセッションに追加した曲のリストを含むからActivityを送信します。BroadcastService

問題は、最後の情報を設定したいときはいつでもFragments、作成に時間がかかりすぎて、本来のBroadcastように処理されないために何も起こらないことです。

フラグメントが作成されて適切に処理されるまで、Serviceまたはを待機させるにはどうすればよいですか?Broadcast

関連するコードスニペットは次のとおりです。

//When the activity binds to the service, refresh the fragments
private ServiceConnection conn = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        LocalBinder binder = (LocalBinder) service;
        myService = binder.getService();
        myService.setBound(true);
        if(myService.startedOnce) {
            myService.refreshFragments();
        }
        myService.startedOnce = true;
    }
}

//This is the broadcast receiver of the Fragment
//it receives the broadcast too soon, and I can't set the
//Views so they are always empty.
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (action.equals(MusicService.REFRESH_ALL)) {
        Song current = intent.getParcelableExtra("song");
        setCurrentSong(current);
    }
}
4

4 に答える 4

14

最も簡単な方法は、フラグメントが情報を表示する準備ができるまで、情報を保持することです。フラグメントのsetArguments()メソッドを使用して、情報をフラグメントに添付します。

@Override
public void onReceive() {
   String action = intent.getAction();
   if(action.equals(MusicService.REFRESH_ALL)) {
      // Creating a new Bundle so the Fragment can control its own object
      Bundle args = new Bundle(intent.getExtras()); 
      Fragment fr = getUsingFragment();
      fr.setArguments(fr);
   }
}

次に、フラグメントでonCreateView()、引数をからプルgetArguments()し、値を使用してビューを構築します。

@Override
public void onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   Bundle args = getArguments();
   if(args != null) {
      // code to set values if arguments are set
   } else {
      // code to set values if arguments are not set
   }
}

これを行う別の方法は、フラグメント自体が値をバンドルに入れるセッターメソッドを使用することですsetArguments()。これにより、フラグメントのビューが破棄されて再作成する必要がある場合に発生する可能性のあるイベントの引数を設定するだけでなく、ビューが作成されたときにいつでもビューを更新できます。

setArguments()注:フラグメントがアクティビティにアタッチされる前にのみ呼び出すことができます。setArgumentsただし、渡したバンドルへの参照をから取得し、値を入力するだけで、バンドルを更新できgetArguments()ます。したがってsetArguments()、受信者から呼び出す代わりに、次のようにします。

public void setCurrentSong(Song extra) {
   Bundle args = getArguments();
   args.putParcable(KEY_MAP, extra);
   if(/* Views are created */) {
      // update and invalidate the views
   }
}
于 2012-11-12T14:44:11.833 に答える
3

これをどのように修正したか

メディア再生サービスを利用していたので、直接再生できるように、このサービスで最後に聴いた曲を表示したいと思いました。これは古いロジックでしたが、実際にはそれを中心にコードを作成しました。これまで私はそれにぶつかりました。

これは起こっていた

  • FragmentActivity創造された
  • Service開始され、バインドされます
  • 一方、Fragments非同期で作成されます
  • 開始するとすぐに、最新情報をService送信しますBroadcast
  • Serviceと作成の両方Fragmentが非同期であるため、ブロードキャストはサービスから送信されますが、のはまだ初期化さBroadcastReceiversれていないため、は受信されません。FragmentsIntent

私がそれを修正するためにしたこと

私はどういうわけかそれを確認するコールバックを使用する必要がありました

  • サービスが作成され、バインドされました
  • 作成されたフラグメントとビューが設定されます

そこでServiceConnection、正確には、onServiceConnected()メソッドを使用しました。そこで最後の曲を保存した設定を取得し、送信してBroadcast受信Fragmentsし、Views適切に設定しました。これは向きの変更にも有効でした。

コード

//This is the code in the FragmentActivity
private ServiceConnection conn = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        LocalBinder binder = (LocalBinder) service;
        myService = binder.getService();
        myService.setBound(true);
        if (myService.startedOnce) {
            myService.refreshFragments();
        } else {
            sendLastSavedSong();
        }
        myService.startedOnce = true;
    }

    public void onServiceDisconnected(ComponentName className) {
        myService.setBound(false);
    }
};
于 2012-11-13T16:36:31.150 に答える
0

のようなフラグメントで何かをすることはできませんか

Song current=null;
public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (action.equals(MusicService.REFRESH_ALL)) {
        current = intent.getParcelableExtra("song");
    }
}

@Override
public void onResume()
{
    if(current!=null) setCurrentSong(current);
    super.onResume();
}
于 2012-11-12T13:13:39.543 に答える
0

私の解決策は、独自のコールバック インターフェイスを作成することでした。フラグメントの onCreateView メソッドの最後でコールバック メソッドを呼び出すだけで、作成が完了したことを mainactivity に伝えます。

それは私のために働いた、あなたも助けてくれることを願っています。

于 2014-06-29T03:00:24.857 に答える