0

リモート サーバーと通信するバックグラウンド サービスを実行するアプリケーションを作成しています。サーバーから新しいメッセージが送信されたら、UI で表されるオブジェクトを更新し、UI ビューを更新してオブジェクトの新しい状態を表す必要があります (たとえば、オブジェクトの background プロパティが true の場合 - 背景を設定します)。ビューの背景を緑に設定し、false の場合はビューの背景を赤に設定します)。

リスト ビューを使用して、ArrayAdapter をスローするすべてのオブジェクトのすべての ArrayList を表示しています。

静的参照用の Application オブジェクト (app という名前) があり、現在実行中のアクティビティを格納する CurrentActivity プロパティがあります (UI が閉じている場合は null)。

私はこのコードを使用してUIを更新しています:

私のサービスで:

onNewMessage(boolean backgruond)
{
  if (app.getCurrentActivity != null)
     app.getCurrentActivity.onNewMessage(background);
}

私の活動で:

onNewMessage(boolean background)
{
  object.setBackground(bacground);
  Log.d("Background", String.valueof(background));
  runOnUiThread(new Runnable() {
      @Override
      public void run()
      {
        arrayAdapter.notifyDataSetChanged();
      }
  });
}

ログは正しいバックグラウンド状態を返しますが、ビューは notifyDataSetChanged() で更新されません。

Activity throw BroadcastRecevier にメッセージを送信しようとしましたが、サーバーから大量のメッセージが送信され、多くの受信者を登録する必要があるため、はるかに複雑です。さらに、なぜレシーバーが機能し、このメカニズムが機能しないのか理解できません..

ListView を更新する作業メソッドの例:

ListViewActivity - BaseActivity からの継承:

@Override
public void onUnFriend(FacebookUser facebookUser, boolean isYouRemovedClient) 
{               
    super.onUnFriend(facebookUser, isYouRemovedClient);
    updateView();
}

BaseActivity (Activity を拡張するスーパークラス):

public void onUnFriend(FacebookUser facebookUser, boolean isYouRemovedClient)
{                           
    facebookUser.setApplicationFriend(false);
    app.getApplicationFriends().remove(facebookUser);
    app.getDatabaseManager().deleteApplicationFriend(facebookUser.getId());     
    if (isYouRemovedClient)
        app.showToast(facebookUser.getName() + " has removed from your friends", true);
    else
        app.showToast(facebookUser.getName() + " has removed you from friends", true);
}   

これは機能し、ListView の背景色を変更します。

ListViewActivity の例が機能しない:

@Override
public void onFriendRequestAccepted(FacebookUser facebookUser, boolean showDialog) {
    super.onFriendRequestAccepted(facebookUser, showDialog);
    updateView();
}

ベースアクティビティ:

public void onFriendRequestAccepted(FacebookUser facebookUser, boolean showDialog) 
{   
    facebookUser.setApplicationFriend(true);
    app.getApplicationFriends().add(facebookUser);
    app.getDatabaseManager().addApplicationFriend(facebookUser);
    if (showDialog)
        app.showNewEventActivity(facebookUser, EventDialogManager.EVENT_FRIEND_ACCEPTED);
}

更新されていません...理由がよくわかりません..

4

2 に答える 2

0

現在実行中のアクティビティを格納する CurrentActivity プロパティがあります(UIが閉じている場合はnull)

この方法はお勧めしません。そのデータ メンバーを一貫して確実に更新することに依存しApplication、サービスと UI の間の結合を増やします。

ログは正しいバックグラウンド状態を返しますが、ビューは notifyDataSetChanged() で更新されません。

アダプタのデータを変更していないように見えます。確かに、ここにあるコードには、アダプターのデータを更新したという証拠はありません。

ところで、ここに示したコード スニペットはどちらもコンパイルされそうにありません (1 つ目は有効な Java ではなく、2 つ目はタイプミスがあります)。

サーバーから大量のメッセージが届き、多くの受信者を登録する必要があります

いいえ、1 つの受信者を登録する必要があります。 ではonReceive()ifステートメント (またはswitch、必要に応じて ) を使用して、メッセージを別のメッセージと区別します。

于 2012-11-04T15:09:19.807 に答える
0

CommonsWare が言ったことに加えてobject、あなたの最初の行にonNewMessageはビューがあると思います。ではなく、パラメーターsetBackroundを受け入れます。intboolean

0xFF00FF00緑と0xFFFF0000赤に使用します。

ところで、Contextオブジェクトとその派生クラスの静的参照を保持することは非常に悪い習慣です (両方とも から派生してApplicationおり、それらの静的参照を保持すると重大なメモリ リークが発生する可能性があります。詳細はこちらを参照してください)。ActivityContext

BroadcastReceiver代わりにaを使用してください。それらは、あなたが説明した方法と比較してはるかに単純です-必要なのは1つだけです.

于 2012-11-04T15:56:36.757 に答える