【问题标题】:Android : Inform adapter that data-set has changed from a static methodAndroid:通知适配器数据集已从静态方法更改
【发布时间】:2015-12-03 12:54:41
【问题描述】:

我正在开发一个 Android 项目,我正在尝试集成 Cometd 框架提供的 PUSH 服务。 现在,每当收到Conversation 的新消息时,我想通知ChatMessagesActivity,其中包含两个用户之间的消息列表。

现在,当其他用户向 Android 应用发送消息时,我想更新用户的视图。我尝试通过在adapter 上调用notifyDataSetHasChanged() 来做到这一点,但是因为我在View 线程之外调用它,所以我收到了一个错误。

该方法是静态的,因为新消息在Conversation 类中接收,而消息在ChatMessagesActivity 类中进行。对于两个类之间的通信,我创建了 2 个静态方法,它们就像一个双向桥梁,用于发送和接收消息。

我希望我很清楚,如果有任何疑问,请告诉我。

ChatMessagesActivity.java:

public class ChatMessagesActivity extends ApplicationDrawerLoader {


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat_messages);

        chatList = (ListView)findViewById(R.id.chatList);

 new getPrivateChatsForUser(this).execute();

}

// IN the method below, I receive information from another activity.

    public static void recieveUpdatedMessage(String channelName, Map<String, Object> input){
 Boolean found = Arrays.asList(channelName.split(" ")).contains("chat");
        if(found){
            int processedChannelName = Integer.valueOf(channelName.replace("/chat/",""));
            if(processedChannelName == groupAccountId){

// Here i tried calling adapter.NotifyDataSetchanged();.. Didn't fly.

            }
        }
}

// Async method retrieving messages.
    public class getPrivateChatsForUser extends AsyncTask<Void, Void, ResponseEntity<RestReplies[]>> {

        ChatMessagesActivity chatMessagesActivity = null;

        getPrivateChatsForUser(ChatMessagesActivity chatMessagesActivity) {
            this.chatMessagesActivity = chatMessagesActivity;
        }
 @Override
        protected ResponseEntity<RestReplies[]> doInBackground(Void... params) { 
// network connection related stuff, not relevant to problem
}
 @Override
        protected void onPostExecute(ResponseEntity<RestReplies[]> responseEntity) {
            super.onPostExecute(responseEntity);
            RestReplies[] restRepliesArray = responseEntity.getBody();
            Collections.addAll(restRepliesList, restRepliesArray);

            ArrayList<HashMap<String, String>> chatMessagesHashMapList = new ArrayList<HashMap<String, String>>();

            for (RestReplies restReplies : restRepliesList) {
                HashMap<String, String> chatMap = new HashMap<>();
                chatMap.put(chatText, restReplies.getReplyText());
                chatMap.put(firstName, restReplies.getReplyingPersonName());
                chatMap.put(chatImage, restReplies.getSenderImage());
                chatMap.put(privateChannel,"/service/person/"+String.valueOf(conversationId));
                chatMessagesHashMapList.add(chatMap);
            }

            chatList = (ListView) findViewById(R.id.chatList);

            chatMessagesAdapter = new ChatMessagesAdapter(chatMessagesActivity, chatMessagesHashMapList);

            chatList.setAdapter(chatMessagesAdapter);

            chatList.scrollTo(0, chatList.getHeight());

        }
    }

那么,我应该如何指示数据集已更改。适配器如何知道在哪里以及如何获取已更改的数据集。谁能帮我解决这个问题。非常感谢... :-)

【问题讨论】:

    标签: java android android-asynctask


    【解决方案1】:

    在您的适配器上使用广播接收器并在您的推送服务中使用 android LocalBroadcast 触发本地广播

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent)
        {
    
            if(intent.getAction().equals("MYREFRESH"))
            {
                notifiyDataSetChanged();
            }
        }
    };
    

    在适配器的构造函数中注册此接收器

    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("MYREFRESH");
    LocalBroadcastManager.getInstance(context).registerReceiver(broadReceiver, intentFilter);
    

    在你的推送中,如果你收到推送通知触发这个

    Intent intent = new Intent();
    intent.putExtra(...) //send any data to your adapter
    Intent.setAction("myaction");
    LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
    

    【讨论】:

    • 这听起来很花哨,不幸的是我已经有两个多星期没有在 android 上工作了。你能告诉我我怎么能做到这一点。谢谢。
    • 通过格式化修复了您的答案。现在检查。谢谢。
    • 我试过你给的代码,但是有几个未知字段,我不知道是什么,并且我必须在发送之前在PUSH中处理消息,所以不能直接触发一些东西那里。你能检查一下这个包含两个类的pastebin,然后告诉我应该在哪里进行更改... Pastebin 链接:pastebin.com/7gCCuPuY
    【解决方案2】:

    处理这个问题的方法是使用广播或总线模式。您可以使用一些不错的总线库,例如 http://square.github.io/otto/LocalBroadcast

    我过去的回答展示了如何使用 LocalBroadcast 系统:Refreshing fragments in FragmentActivity after sync service runs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多