3

サーバーからメッセージを受信するバックグラウンド サービスがあり、それらのメッセージを使用して、ListView に表示されるオブジェクトの内部プロパティを更新します。

私は常に runOnUiThread メソッドを使用して listArrayAdapter.notifyOnDataSetChanged() コマンドを実行します。

何らかの理由で、ListView が更新され、プロパティの更新が表示される場合と表示されない場合があります。

テストのために、ListView に「更新」ボタンを追加しました。ボタンを押すと、listArrayAdapter.notifyOnDataSetChanged() が実行されます。

ボタンをクリックするたびに、ビューが完全に更新されます..

サービスから更新しようとすると、常に機能するとは限らない理由がよくわかりませんが、UIThreadで常に実行されるとは限らないと思います...

私は本当に絶望的で、喜んで助けを求めます..

マイコード

ServerConnectionManager.java - サービスを拡張します

//example of a command executed when a specific message received from the server:
//app is the Application variable
    public void unFriend(int userId)
    {
        serverResponseManager.onUnFriend(app.getApplicationFriend(userId),false);
    }

ServerResponseManager.java - サーバー メッセージに対するすべてのアプリケーション応答を処理するクラス:

    public void onUnFriend(FacebookUser facebookUser, boolean isYouRemovedClient) {                 

         //this is the property which will effect the ListView view when calling the  
         //arrayListAdataper.notifyOnDataSetChanged();
        facebookUser.setApplicationFriend(false);        
        app.getApplicationFriends().remove(facebookUser);
        app.getDatabaseManager().deleteApplicationFriend(facebookUser.getId());         

         //if the application is currently running in the UI (not on the background) it will run a method inside the BaseActivity
        if (app.isApplicationInForeground())
        {           
            app.getCurrentActivity().onUnFriend(facebookUser);
            if (isYouRemovedClient)
                app.showToast(facebookUser.getName() + " has removed from your friends", true);
            else
                app.showToast(facebookUser.getName() + " has removed you from friends", true);
        }
    }

BaseActivity.java - それを拡張するすべてのアクティビティのすべてのデフォルト構成を設定するアクティビティ

//in this exemple the BaseActivity method does nothing but the ListViewActivity.java method override it
public void onUnFriend(FacebookUser facebookUser)
{                   

}

ListViewActivity.java - BaseActivity を拡張し、ServerResponseManager の public void onUnFriend(FacebookUser facebookUser, boolean isYouRemovedClient) で行われた FacebookUser オブジェクト プロパティの変更を反映する必要がある ListView をその中に持ちます。

@Override
public void onUnFriend(FacebookUser facebookUser)
{       
    updateView();
}

private void updateView()
{
    runOnUiThread(updateViewRunnable());
}

private Runnable updateViewRunnable()
{
    Runnable run = new Runnable() {

        @Override
        public void run() {             
            listArrayAdapter.notifyDataSetChanged();
        }
    };
    return run;
}
4

5 に答える 5

9

ビジネス ロジックを混在させないでください。見た目が複雑すぎて読みにくい。

  1. サービスで、更新に関する情報を含むインテントをブロードキャストします。
  2. Activitywhere is で、更新イベントをListView作成して登録BroadcastReceiverします。IntentFilter
  3. リストの更新など、更新イベントを処理するonReceive方法で。BroadcastReceiver
于 2012-11-04T10:49:18.663 に答える
1

ListViewでカーソルを使用して、データを表示できます。サービスは、ContentProviderのデータを書き込み/更新します。データベーストランザクションの最後に、次のように簡単に使用できます。

getContext().getContentResolver().notifyChange(PROVIDER_URI,null);

ListViewは自動的に更新されます。

于 2012-11-07T11:52:18.990 に答える
1

Service は通常、UI の問題から独立している必要があります。サービスと UI 関連のものを分離する優れた方法は、イベント バス パターンです。Android の場合は、https://github.com/greenrobot/EventBusを確認してください。

ServerConnectionManager では、イベントを投稿できます。

EventBus.getDefault().post(new UnfriendEvent(userId));

アクティビティをイベント バスに登録すると、onEvent メソッドを呼び出してイベントがアクティビティに配信されます。

public void onEventMainThread(UnfriendEvent event) {...}

このように、変更に対して非常に柔軟な、きちんとしたクリーンなソフトウェア設計につながるコンポーネントを分離します。

于 2012-11-10T12:31:17.953 に答える
0

このチュートリアルを使用して、コードの適切なアーキテクチャを確認できます

バックグラウンド サービスを使用したアプリの開発

サービスから通知を受け取り、UI を更新する方法を示します。

runOnUiThread は、主に AsyncTask 呼び出しが行われる前に使用されます。代わりにハンドラーを使用する必要があると思います (UI を更新し、スレッドを実行できるようにします)。ハンドラーを使用してみて、何が起こるかを確認してください

于 2012-11-07T10:50:52.597 に答える